diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index f6bf1e478b1c0..0000000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,31 +0,0 @@ - - -**Is this a BUG REPORT or FEATURE REQUEST?**: - -> Uncomment only one, leave it on its own line: -> -> /kind bug -> /kind feature - - -**What happened**: - -**What you expected to happen**: - -**How to reproduce it (as minimally and precisely as possible)**: - - -**Anything else we need to know?**: - -**Environment**: -- Kubernetes version (use `kubectl version`): -- Cloud provider or hardware configuration: -- OS (e.g. from /etc/os-release): -- Kernel (e.g. `uname -a`): -- Install tools: -- Others: diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000000000..6313c4cf055c4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,27 @@ +--- +name: Bug Report +about: Report a bug encountered while operating Kubernetes + +--- + + + + +**What happened**: + +**What you expected to happen**: + +**How to reproduce it (as minimally and precisely as possible)**: + +**Anything else we need to know?**: + +**Environment**: +- Kubernetes version (use `kubectl version`): +- Cloud provider or hardware configuration: +- OS (e.g. from /etc/os-release): +- Kernel (e.g. `uname -a`): +- Install tools: +- Others: + + +/kind bug \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md new file mode 100644 index 0000000000000..54f21fda5f2b9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement.md @@ -0,0 +1,13 @@ +--- +name: Enhancement Request +about: Suggest an enhancement to the Kubernetes project + +--- + + +**What would you like to be added**: + +**Why is this needed**: + + +/kind feature \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/failing-test.md b/.github/ISSUE_TEMPLATE/failing-test.md new file mode 100644 index 0000000000000..5da4006fe2924 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/failing-test.md @@ -0,0 +1,22 @@ +--- +name: Failing Test +about: Report test failures in Kubernetes CI jobs + +--- + + + +**Which jobs are failing**: + +**Which test(s) are failing**: + +**Since when has it been failing**: + +**Testgrid link**: + +**Reason for failure**: + +**Anything else we need to know**: + + +/kind failing-test \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/support.md b/.github/ISSUE_TEMPLATE/support.md new file mode 100644 index 0000000000000..28a1100eb3553 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support.md @@ -0,0 +1,22 @@ +--- +name: Support Request +about: Support request or question relating to Kubernetes + +--- + + + + + +/triage support + diff --git a/.gitignore b/.gitignore index 02a2a4b1a78a6..2d5e0e2c4a9fa 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,6 @@ zz_generated_*_test.go /bazel-* *.pyc + +# generated by verify-godeps.sh +vendordiff.patch diff --git a/CHANGELOG-1.11.md b/CHANGELOG-1.11.md index fb9f5c4039aef..399bb245664be 100644 --- a/CHANGELOG-1.11.md +++ b/CHANGELOG-1.11.md @@ -1,33 +1,40 @@ -- [v1.11.3](#v1113) - - [Downloads for v1.11.3](#downloads-for-v1113) +- [v1.11.4](#v1114) + - [Downloads for v1.11.4](#downloads-for-v1114) - [Client Binaries](#client-binaries) - [Server Binaries](#server-binaries) - [Node Binaries](#node-binaries) - - [Changelog since v1.11.2](#changelog-since-v1112) - - [Action Required](#action-required) + - [Changelog since v1.11.3](#changelog-since-v1113) - [Other notable changes](#other-notable-changes) -- [v1.11.2](#v1112) - - [Downloads for v1.11.2](#downloads-for-v1112) +- [v1.11.3](#v1113) + - [Downloads for v1.11.3](#downloads-for-v1113) - [Client Binaries](#client-binaries-1) - [Server Binaries](#server-binaries-1) - [Node Binaries](#node-binaries-1) - - [Changelog since v1.11.1](#changelog-since-v1111) - - [Action Required](#action-required-1) + - [Changelog since v1.11.2](#changelog-since-v1112) + - [Action Required](#action-required) - [Other notable changes](#other-notable-changes-1) -- [v1.11.1](#v1111) - - [Downloads for v1.11.1](#downloads-for-v1111) +- [v1.11.2](#v1112) + - [Downloads for v1.11.2](#downloads-for-v1112) - [Client Binaries](#client-binaries-2) - [Server Binaries](#server-binaries-2) - [Node Binaries](#node-binaries-2) - - [Changelog since v1.11.0](#changelog-since-v1110) - - [Action Required](#action-required-2) + - [Changelog since v1.11.1](#changelog-since-v1111) + - [Action Required](#action-required-1) - [Other notable changes](#other-notable-changes-2) -- [v1.11.0](#v1110) - - [Downloads for v1.11.0](#downloads-for-v1110) +- [v1.11.1](#v1111) + - [Downloads for v1.11.1](#downloads-for-v1111) - [Client Binaries](#client-binaries-3) - [Server Binaries](#server-binaries-3) - [Node Binaries](#node-binaries-3) + - [Changelog since v1.11.0](#changelog-since-v1110) + - [Action Required](#action-required-2) + - [Other notable changes](#other-notable-changes-3) +- [v1.11.0](#v1110) + - [Downloads for v1.11.0](#downloads-for-v1110) + - [Client Binaries](#client-binaries-4) + - [Server Binaries](#server-binaries-4) + - [Node Binaries](#node-binaries-4) - [Kubernetes 1.11 Release Notes](#kubernetes-111-release-notes) - [Urgent Upgrade Notes](#urgent-upgrade-notes) - [(No, really, you MUST do this before you upgrade)](#no-really-you-must-do-this-before-you-upgrade) @@ -50,7 +57,7 @@ - [Graduated to Stable/GA](#graduated-to-stablega) - [Graduated to Beta](#graduated-to-beta) - [New alpha features](#new-alpha-features) - - [Other Notable Changes](#other-notable-changes-3) + - [Other Notable Changes](#other-notable-changes-4) - [SIG API Machinery](#sig-api-machinery-1) - [SIG Apps](#sig-apps) - [SIG Auth](#sig-auth-1) @@ -74,62 +81,167 @@ - [Non-user-facing changes](#non-user-facing-changes) - [v1.11.0-rc.3](#v1110-rc3) - [Downloads for v1.11.0-rc.3](#downloads-for-v1110-rc3) - - [Client Binaries](#client-binaries-4) - - [Server Binaries](#server-binaries-4) - - [Node Binaries](#node-binaries-4) - - [Changelog since v1.11.0-rc.2](#changelog-since-v1110-rc2) - - [Other notable changes](#other-notable-changes-4) -- [v1.11.0-rc.2](#v1110-rc2) - - [Downloads for v1.11.0-rc.2](#downloads-for-v1110-rc2) - [Client Binaries](#client-binaries-5) - [Server Binaries](#server-binaries-5) - [Node Binaries](#node-binaries-5) - - [Changelog since v1.11.0-rc.1](#changelog-since-v1110-rc1) + - [Changelog since v1.11.0-rc.2](#changelog-since-v1110-rc2) - [Other notable changes](#other-notable-changes-5) -- [v1.11.0-rc.1](#v1110-rc1) - - [Downloads for v1.11.0-rc.1](#downloads-for-v1110-rc1) +- [v1.11.0-rc.2](#v1110-rc2) + - [Downloads for v1.11.0-rc.2](#downloads-for-v1110-rc2) - [Client Binaries](#client-binaries-6) - [Server Binaries](#server-binaries-6) - [Node Binaries](#node-binaries-6) - - [Changelog since v1.11.0-beta.2](#changelog-since-v1110-beta2) - - [Action Required](#action-required-3) + - [Changelog since v1.11.0-rc.1](#changelog-since-v1110-rc1) - [Other notable changes](#other-notable-changes-6) -- [v1.11.0-beta.2](#v1110-beta2) - - [Downloads for v1.11.0-beta.2](#downloads-for-v1110-beta2) +- [v1.11.0-rc.1](#v1110-rc1) + - [Downloads for v1.11.0-rc.1](#downloads-for-v1110-rc1) - [Client Binaries](#client-binaries-7) - [Server Binaries](#server-binaries-7) - [Node Binaries](#node-binaries-7) - - [Changelog since v1.11.0-beta.1](#changelog-since-v1110-beta1) - - [Action Required](#action-required-4) + - [Changelog since v1.11.0-beta.2](#changelog-since-v1110-beta2) + - [Action Required](#action-required-3) - [Other notable changes](#other-notable-changes-7) -- [v1.11.0-beta.1](#v1110-beta1) - - [Downloads for v1.11.0-beta.1](#downloads-for-v1110-beta1) +- [v1.11.0-beta.2](#v1110-beta2) + - [Downloads for v1.11.0-beta.2](#downloads-for-v1110-beta2) - [Client Binaries](#client-binaries-8) - [Server Binaries](#server-binaries-8) - [Node Binaries](#node-binaries-8) - - [Changelog since v1.11.0-alpha.2](#changelog-since-v1110-alpha2) - - [Action Required](#action-required-5) + - [Changelog since v1.11.0-beta.1](#changelog-since-v1110-beta1) + - [Action Required](#action-required-4) - [Other notable changes](#other-notable-changes-8) -- [v1.11.0-alpha.2](#v1110-alpha2) - - [Downloads for v1.11.0-alpha.2](#downloads-for-v1110-alpha2) +- [v1.11.0-beta.1](#v1110-beta1) + - [Downloads for v1.11.0-beta.1](#downloads-for-v1110-beta1) - [Client Binaries](#client-binaries-9) - [Server Binaries](#server-binaries-9) - [Node Binaries](#node-binaries-9) - - [Changelog since v1.11.0-alpha.1](#changelog-since-v1110-alpha1) + - [Changelog since v1.11.0-alpha.2](#changelog-since-v1110-alpha2) + - [Action Required](#action-required-5) - [Other notable changes](#other-notable-changes-9) -- [v1.11.0-alpha.1](#v1110-alpha1) - - [Downloads for v1.11.0-alpha.1](#downloads-for-v1110-alpha1) +- [v1.11.0-alpha.2](#v1110-alpha2) + - [Downloads for v1.11.0-alpha.2](#downloads-for-v1110-alpha2) - [Client Binaries](#client-binaries-10) - [Server Binaries](#server-binaries-10) - [Node Binaries](#node-binaries-10) + - [Changelog since v1.11.0-alpha.1](#changelog-since-v1110-alpha1) + - [Other notable changes](#other-notable-changes-10) +- [v1.11.0-alpha.1](#v1110-alpha1) + - [Downloads for v1.11.0-alpha.1](#downloads-for-v1110-alpha1) + - [Client Binaries](#client-binaries-11) + - [Server Binaries](#server-binaries-11) + - [Node Binaries](#node-binaries-11) - [Changelog since v1.10.0](#changelog-since-v1100) - [Action Required](#action-required-6) - - [Other notable changes](#other-notable-changes-10) + - [Other notable changes](#other-notable-changes-11) +# v1.11.4 + +[Documentation](https://docs.k8s.io) + +## Downloads for v1.11.4 + + +filename | sha512 hash +-------- | ----------- +[kubernetes.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes.tar.gz) | `035d123271ca72372be955631cf106b94b53ba7b6d2242e0111c0557fbe2153d549493e5057f7f16b4e8390ecbd44d86c69d96418496b3898c35265706833faf` +[kubernetes-src.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-src.tar.gz) | `b59a340b0f325649648b0a0e361398f613e093f2b4ba087a8b602fc27888eab013377e3516c8fcd80fc2c069811911b558a4b53f24c5c1c47dd266342dc488cc` + +### Client Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-client-darwin-386.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-darwin-386.tar.gz) | `e1914c95260ad7a2418c68017710941151ef069cb2101e404ef17658585dc6d90e90a7534078fd89cb9f3a3e6681c25b7a8a10f7a8cd3b59408383f8ade9aa26` +[kubernetes-client-darwin-amd64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-darwin-amd64.tar.gz) | `145d67df9135acf237f41c48dded2e017943a5806bdd1ecc23c33c35befc354a5cdd009eaa8a25ad871f238db6cfcce1bdc8da682d0263fcff7d99cccd11f61d` +[kubernetes-client-linux-386.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-linux-386.tar.gz) | `586a48872a8e1082c165cee3168babdf925c9e1b3ee7a1e6f38f85acb863de540929b259a19df6122168e0122d7943c60b25ec7ab1fc39a5bebbb451ed57954a` +[kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-linux-amd64.tar.gz) | `6d9060ab605c3c86dafd40dbfcb25e4f2d8c2a0d4770ab949f57c96a74cdc4ac98c543d0171cab276b88680c0f18eb4acb33689a94a7648c2053ada41233f37b` +[kubernetes-client-linux-arm.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-linux-arm.tar.gz) | `7c12e679f13c6a11ed05df0e4204862a7db3bbf273e5e837eeb59c656c945089a89da01788dd977f735a17f6d541a70f0612520163e9d5431031c04609c88a24` +[kubernetes-client-linux-arm64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-linux-arm64.tar.gz) | `662a33a7f00eb3bb607bfcbd3f599e6a378c9e9e32fe7b4bb697b5858b8cad499f228d80ac0d3dfe93050b808a8adfea4ac3d99d16fdac01020152e449f02370` +[kubernetes-client-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-linux-ppc64le.tar.gz) | `64f07ac851068fa5c784ed9e66551016b9f5436663e2a98a3b07734ecf98a7fea0482a701114e8bc9d1e04f8a122ed047d0049242f790efbf47726a03a22f578` +[kubernetes-client-linux-s390x.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-linux-s390x.tar.gz) | `bc72689bd75b65820097d640cb3e26fcbf95600438cf9486265b209cd82b16ec742bb96a95d788eab6b483a48f81d8a56962f19e2c8365e0289d87414217e4f2` +[kubernetes-client-windows-386.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-windows-386.tar.gz) | `d5d41f4f70d6e9be229c1c00eb4184d5cd14f9eec78e5ea65481e81d51d4a09ead1b6ae739d385517a901d901a8f06e2fc9f632c1b1766a22a43d8ea535a3ea4` +[kubernetes-client-windows-amd64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-client-windows-amd64.tar.gz) | `12ef0cc939f6ff834c7e8f4b2a6e441cd5c50aa7a10e3b3545c116c07feb67f1b98f8f56c8aa01b70bd195e59e46be627f3087dfaf7d8d6861cb80304b69676d` + +### Server Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-server-linux-amd64.tar.gz) | `58d22b0c5339d75ef72266c3922ad3c44690ef937703653a966379c6791d527a0d66318b78deb135232b88eee30f8f06d085306df3ea0d08f6625fedc4bb7407` +[kubernetes-server-linux-arm.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-server-linux-arm.tar.gz) | `a1ad67cf28c5d583f103a89070e76f210bdd193b16a7b505b4a2d5d9a9218638af340424dc670e2fbab3c9c3cc55910ea5ab57081c36e34afd6f32102673d6e4` +[kubernetes-server-linux-arm64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-server-linux-arm64.tar.gz) | `25f544e2834dc2c12f1e22cffb8becbbffae37ffb36232d3100d5944e0d09eb0a25587301c49a9ac86b1c69a99936df1164abb6a85e091559f1df0a5a1134c9b` +[kubernetes-server-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-server-linux-ppc64le.tar.gz) | `07089eae49a3fc7a368ac8e084041cc28102de2fd3c5fc7354aea14d6f2283d64905eaf109f4e5c9f3ab6cbc5cf71897815fa130de6abf7ee8f11a20d1516378` +[kubernetes-server-linux-s390x.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-server-linux-s390x.tar.gz) | `ed4ec0353218e6846cf9e5a6509148cb6ba08c131d48dca8e2bb618eec3fbe3a83bc631696b479bfa8870bfa23abb14fa1b1086ec7d0ba0c7b83daf284c3798c` + +### Node Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-node-linux-amd64.tar.gz) | `43865ed40735aaa36ca8536596972f0b98d238df8f22d22184c9a585d7aedd223b56cabc942f1cb9a3b03d8006f9692a048ccd9e1e85e5184608a5927374ce94` +[kubernetes-node-linux-arm.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-node-linux-arm.tar.gz) | `453d709310cad4def41d31583c8bb27090e2599befb28974e00fc40886a76ad42c618527be7c496a5b7e0aff71a1e0c044a3628fe428989b56823210a81ed371` +[kubernetes-node-linux-arm64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-node-linux-arm64.tar.gz) | `0975e8023b4e53b439b20e97378883b1e7c60f451ac853346a3fa6de9ca5186fb0fc1cf8a40874f9ff33cc3fa48be3c279abe1c55cd5a0f726b25f0942e40be0` +[kubernetes-node-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-node-linux-ppc64le.tar.gz) | `9f3e615e4422c4ffaaf4c583b0f5bbaf45ecc38c678f08621391e1bbb1d370f101f03e55c7585a7ede276ac3e0cd57bddfdaf036a75a5fe1db30c6aaf5fec117` +[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-node-linux-s390x.tar.gz) | `513125ab48ff96e632e17fe15b0e1eadbb77ae1ee19f91089e1f93403771c6b6a59c86a2d42dea4516409116a88db15335f969e27f82a9c761dc2579cee7515c` +[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.11.4/kubernetes-node-windows-amd64.tar.gz) | `5826b54be51abc9f874e79347677579fb68d9664e7b058851dbd057640b72bdcbe58cb48167c20eb6d8f3ac559c2b361564c15661c2ee01b22dc8323ce228b41` + +## Changelog since v1.11.3 + +### Other notable changes + +* support cross resource group for azure file ([#68117](https://github.com/kubernetes/kubernetes/pull/68117), [@andyzhangx](https://github.com/andyzhangx)) +* change default azure file mount permission to 0777 ([#69854](https://github.com/kubernetes/kubernetes/pull/69854), [@andyzhangx](https://github.com/andyzhangx)) +* Scheduling conformance tests related to daemonsets should set the annotation that relaxes node selection restrictions, if any are set. This ensures conformance tests can run on a wider array of clusters. ([#68793](https://github.com/kubernetes/kubernetes/pull/68793), [@aveshagarwal](https://github.com/aveshagarwal)) +* Add tolerations for Stackdriver Logging and Metadata Agents. ([#69737](https://github.com/kubernetes/kubernetes/pull/69737), [@qingling128](https://github.com/qingling128)) +* Fix scheduler crashes when Prioritize Map function returns error. ([#69618](https://github.com/kubernetes/kubernetes/pull/69618), [@DylanBLE](https://github.com/DylanBLE)) +* Add fallbacks to ARM API when getting empty node IP from Azure IMDS ([#69077](https://github.com/kubernetes/kubernetes/pull/69077), [@feiskyer](https://github.com/feiskyer)) +* Verify invalid secret/configmap/projected volumes before calling setup ([#68691](https://github.com/kubernetes/kubernetes/pull/68691), [@gnufied](https://github.com/gnufied)) +* Immediately close the other side of the connection when proxying. ([#67288](https://github.com/kubernetes/kubernetes/pull/67288), [@MHBauer](https://github.com/MHBauer)) +* fix a bug that overwhelming number of prometheus metrics are generated because $NAMESPACE is not replaced by string "{namespace}" ([#68530](https://github.com/kubernetes/kubernetes/pull/68530), [@wenjiaswe](https://github.com/wenjiaswe)) +* locking fix in vSphere cleanup function ([#68388](https://github.com/kubernetes/kubernetes/pull/68388), [@wgliang](https://github.com/wgliang)) + * The vSphere cloud provider has a cleanup function with a loop, + * inside of which a write lock was intended to prevent races against + * VM creation, but the usage of the sync.RWMutex type is incorrect, + * plus is placed in a defer call so the locking is effectively + * nonexistent. This patch adds an anonymous function call inside + * the loop to correctly handle acquiring the write lock with deferred + * unlock to run at that function's completion, following the normal + * golang lock/deferred-unlock pattern. +* fix UnmountDevice failure on Windows ([#68608](https://github.com/kubernetes/kubernetes/pull/68608), [@andyzhangx](https://github.com/andyzhangx)) +* Get public IP for Azure vmss nodes. ([#68498](https://github.com/kubernetes/kubernetes/pull/68498), [@feiskyer](https://github.com/feiskyer)) +* Role, ClusterRole and their bindings for cloud-provider is put under system namespace. Their addonmanager mode switches to EnsureExists. ([#67224](https://github.com/kubernetes/kubernetes/pull/67224), [@grayluck](https://github.com/grayluck)) +* Bump up version number of debian-base, debian-hyperkube-base and debian-iptables. ([#67026](https://github.com/kubernetes/kubernetes/pull/67026), [@satyasm](https://github.com/satyasm)) + * Also updates dependencies of users of debian-base. + * debian-base version 0.3.1 is already available. +* Update debian-iptables and hyperkube-base images to include CVE fixes. ([#67365](https://github.com/kubernetes/kubernetes/pull/67365), [@ixdy](https://github.com/ixdy)) +* Support configuring the Azure load balancer idle connection timeout for services ([#66045](https://github.com/kubernetes/kubernetes/pull/66045), [@cpuguy83](https://github.com/cpuguy83)) +* Let service controller retry creating load balancer when persistUpdate failed due to conflict. ([#68087](https://github.com/kubernetes/kubernetes/pull/68087), [@grayluck](https://github.com/grayluck)) +* Return apiserver panics as 500 errors instead terminating the apiserver process. ([#68001](https://github.com/kubernetes/kubernetes/pull/68001), [@sttts](https://github.com/sttts)) +* adjusted http/2 buffer sizes for apiservers to prevent starvation issues between concurrent streams ([#67902](https://github.com/kubernetes/kubernetes/pull/67902), [@liggitt](https://github.com/liggitt)) +* Reduced excessive logging from fluentd-gcp-scaler. ([#68837](https://github.com/kubernetes/kubernetes/pull/68837), [@x13n](https://github.com/x13n)) +* Fix potential panic when getting azure load balancer status ([#68609](https://github.com/kubernetes/kubernetes/pull/68609), [@feiskyer](https://github.com/feiskyer)) +* Fix an issue where filesystems are not unmounted when a backend is not reachable and returns EIO. ([#67097](https://github.com/kubernetes/kubernetes/pull/67097), [@chakri-nelluri](https://github.com/chakri-nelluri)) +* [GCE] Enable by default audit logging truncating backend. ([#68342](https://github.com/kubernetes/kubernetes/pull/68342), [@loburm](https://github.com/loburm)) +* [fluentd-gcp-scaler addon] Bump fluentd-gcp-scaler to 0.4 to pick up security fixes. ([#67691](https://github.com/kubernetes/kubernetes/pull/67691), [@loburm](https://github.com/loburm)) + * [prometheus-to-sd addon] Bump prometheus-to-sd to 0.3.1 to pick up security fixes, bug fixes and new features. + * [event-exporter addon] Bump event-exporter to 0.2.3 to pick up security fixes. +* [GCP] Added env variables to control CPU requests of kube-controller-manager and kube-scheduler. ([#68823](https://github.com/kubernetes/kubernetes/pull/68823), [@loburm](https://github.com/loburm)) +* Update Cluster Autoscaler to version 1.3.3. ([#68936](https://github.com/kubernetes/kubernetes/pull/68936), [@losipiuk](https://github.com/losipiuk)) +* Bump addon-manager to v8.7 ([#68299](https://github.com/kubernetes/kubernetes/pull/68299), [@MrHohn](https://github.com/MrHohn)) + * - Support extra `--prune-whitelist` resources in kube-addon-manager. + * - Update kubectl to v1.10.7. +* Support extra `--prune-whitelist` resources in kube-addon-manager. ([#67743](https://github.com/kubernetes/kubernetes/pull/67743), [@Random-Liu](https://github.com/Random-Liu)) + * Before, when users run admission webhook as an addon pod, after they remove the webhook, kube-addon-manager won't cleanup the webhook configuration `MutatingWebhookConfiguration`/`ValidationWebhookConfiguration`, because those resources are not prune-whitelisted. Cluster will go into a bad state that no pod can be admitted. + * With this feature, users can config kube-addon-manager to whitelist those resources to fix this issue. +* Bump ip-masq-agent to v2.1.1 ([#67916](https://github.com/kubernetes/kubernetes/pull/67916), [@MrHohn](https://github.com/MrHohn)) + * - Update debian-iptables image for CVEs. + * - Change chain name to IP-MASQ to be compatible with the + * pre-injected masquerade rules. +* If `TaintNodesByCondition` is enabled, add `node.kubernetes.io/unschedulable` and `node.kubernetes.io/network-unavailable` automatically to DaemonSet pods. ([#64954](https://github.com/kubernetes/kubernetes/pull/64954), [@k82cn](https://github.com/k82cn)) +* Fix VMWare VM freezing bug by reverting [#51066](https://github.com/kubernetes/kubernetes/pull/51066) ([#67825](https://github.com/kubernetes/kubernetes/pull/67825), [@nikopen](https://github.com/nikopen)) + + + # v1.11.3 [Documentation](https://docs.k8s.io) & [Examples](https://releases.k8s.io/release-1.11/examples) diff --git a/CHANGELOG-1.12.md b/CHANGELOG-1.12.md index d3ed528b27588..40e84d5a3527e 100644 --- a/CHANGELOG-1.12.md +++ b/CHANGELOG-1.12.md @@ -1,16 +1,23 @@ -- [v1.12.1](#v1121) - - [Downloads for v1.12.1](#downloads-for-v1121) +- [v1.12.2](#v1122) + - [Downloads for v1.12.2](#downloads-for-v1122) - [Client Binaries](#client-binaries) - [Server Binaries](#server-binaries) - [Node Binaries](#node-binaries) - - [Changelog since v1.12.0](#changelog-since-v1120) + - [Changelog since v1.12.1](#changelog-since-v1121) - [Other notable changes](#other-notable-changes) -- [v1.12.0](#v1120) - - [Downloads for v1.12.0](#downloads-for-v1120) +- [v1.12.1](#v1121) + - [Downloads for v1.12.1](#downloads-for-v1121) - [Client Binaries](#client-binaries-1) - [Server Binaries](#server-binaries-1) - [Node Binaries](#node-binaries-1) + - [Changelog since v1.12.0](#changelog-since-v1120) + - [Other notable changes](#other-notable-changes-1) +- [v1.12.0](#v1120) + - [Downloads for v1.12.0](#downloads-for-v1120) + - [Client Binaries](#client-binaries-2) + - [Server Binaries](#server-binaries-2) + - [Node Binaries](#node-binaries-2) - [Known Issues](#known-issues) - [Major Themes](#major-themes) - [SIG API Machinery](#sig-api-machinery) @@ -32,7 +39,7 @@ - [Deprecations and removals](#deprecations-and-removals) - [New Features](#new-features) - [API Changes](#api-changes) - - [Other Notable Changes](#other-notable-changes-1) + - [Other Notable Changes](#other-notable-changes-2) - [SIG API Machinery](#sig-api-machinery-1) - [SIG Apps](#sig-apps) - [SIG Auth](#sig-auth) @@ -51,54 +58,127 @@ - [SIG Storage](#sig-storage-1) - [SIG VMWare](#sig-vmware-1) - [SIG Windows](#sig-windows-1) - - [Other Notable Changes](#other-notable-changes-2) + - [Other Notable Changes](#other-notable-changes-3) - [Bug Fixes](#bug-fixes) - [Not Very Notable (that is, non-user-facing)](#not-very-notable-that-is-non-user-facing) - [External Dependencies](#external-dependencies) - [v1.12.0-rc.2](#v1120-rc2) - [Downloads for v1.12.0-rc.2](#downloads-for-v1120-rc2) - - [Client Binaries](#client-binaries-2) - - [Server Binaries](#server-binaries-2) - - [Node Binaries](#node-binaries-2) - - [Changelog since v1.12.0-rc.1](#changelog-since-v1120-rc1) - - [Other notable changes](#other-notable-changes-3) -- [v1.12.0-rc.1](#v1120-rc1) - - [Downloads for v1.12.0-rc.1](#downloads-for-v1120-rc1) - [Client Binaries](#client-binaries-3) - [Server Binaries](#server-binaries-3) - [Node Binaries](#node-binaries-3) - - [Changelog since v1.12.0-beta.2](#changelog-since-v1120-beta2) - - [Action Required](#action-required-1) + - [Changelog since v1.12.0-rc.1](#changelog-since-v1120-rc1) - [Other notable changes](#other-notable-changes-4) -- [v1.12.0-beta.2](#v1120-beta2) - - [Downloads for v1.12.0-beta.2](#downloads-for-v1120-beta2) +- [v1.12.0-rc.1](#v1120-rc1) + - [Downloads for v1.12.0-rc.1](#downloads-for-v1120-rc1) - [Client Binaries](#client-binaries-4) - [Server Binaries](#server-binaries-4) - [Node Binaries](#node-binaries-4) - - [Changelog since v1.12.0-beta.1](#changelog-since-v1120-beta1) - - [Action Required](#action-required-2) + - [Changelog since v1.12.0-beta.2](#changelog-since-v1120-beta2) + - [Action Required](#action-required-1) - [Other notable changes](#other-notable-changes-5) -- [v1.12.0-beta.1](#v1120-beta1) - - [Downloads for v1.12.0-beta.1](#downloads-for-v1120-beta1) +- [v1.12.0-beta.2](#v1120-beta2) + - [Downloads for v1.12.0-beta.2](#downloads-for-v1120-beta2) - [Client Binaries](#client-binaries-5) - [Server Binaries](#server-binaries-5) - [Node Binaries](#node-binaries-5) - - [Changelog since v1.12.0-alpha.1](#changelog-since-v1120-alpha1) - - [Action Required](#action-required-3) + - [Changelog since v1.12.0-beta.1](#changelog-since-v1120-beta1) + - [Action Required](#action-required-2) - [Other notable changes](#other-notable-changes-6) -- [v1.12.0-alpha.1](#v1120-alpha1) - - [Downloads for v1.12.0-alpha.1](#downloads-for-v1120-alpha1) +- [v1.12.0-beta.1](#v1120-beta1) + - [Downloads for v1.12.0-beta.1](#downloads-for-v1120-beta1) - [Client Binaries](#client-binaries-6) - [Server Binaries](#server-binaries-6) - [Node Binaries](#node-binaries-6) + - [Changelog since v1.12.0-alpha.1](#changelog-since-v1120-alpha1) + - [Action Required](#action-required-3) + - [Other notable changes](#other-notable-changes-7) +- [v1.12.0-alpha.1](#v1120-alpha1) + - [Downloads for v1.12.0-alpha.1](#downloads-for-v1120-alpha1) + - [Client Binaries](#client-binaries-7) + - [Server Binaries](#server-binaries-7) + - [Node Binaries](#node-binaries-7) - [Changelog since v1.11.0](#changelog-since-v1110) - [Action Required](#action-required-4) - - [Other notable changes](#other-notable-changes-7) + - [Other notable changes](#other-notable-changes-8) +# v1.12.2 + +[Documentation](https://docs.k8s.io) + +## Downloads for v1.12.2 + + +filename | sha512 hash +-------- | ----------- +[kubernetes.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes.tar.gz) | `289ecf691164c70e392cea6f9f5b642b081ae9bd19c83113fe1abce8e7dc96baeae807f21e1b86d894345c9db01c8b6c35792b23cff7409d459a62eef45e0d92` +[kubernetes-src.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-src.tar.gz) | `16d43d25e7a5f37e79b9cd91783e90af78566737c8ad22d2104f63af394377fc84d187c3c0090ba65805f50b3f992e170d0aea52c263c2ce374ef4db4843ccc8` + +### Client Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-client-darwin-386.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-darwin-386.tar.gz) | `cd1781ed2dc1f365a034727b37ba978c2e4ba5c321a2fb768e971f9b9a87276a70e184a61fcd9d87e97d7199ab696c3c92eb0847891fd21ba5b64e0b5417b337` +[kubernetes-client-darwin-amd64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-darwin-amd64.tar.gz) | `19422d4e4d47242f7d1ba67f647513d32f179e31a705c861188c1555faa8c521357f68fd81eabc4f14584bc4ab5eff22f8c71990a6c5af6fe701956cbff506a9` +[kubernetes-client-linux-386.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-linux-386.tar.gz) | `674ebc0ffdb4b5935d4718e80b457605f939ae70509f192aa09dfae206aa01c45052d7c5fe086cd936d9f2b01572ed72419cd9bf3e4c0675fa740533de9114b9` +[kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-linux-amd64.tar.gz) | `902f7de49be50bad61909790073aa46e9fab66b227fd06bebd6b0f7eecbd76b688e15fd45adf68e3ee88b0500169b8099ce1feceab27b98f0d635d5c6ffba2c7` +[kubernetes-client-linux-arm.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-linux-arm.tar.gz) | `27f0fe9a05af35bfdf9b870788c3474ab7c00dd5617f116f03848ff6f9e31b57e02991def1c16bbe1bc8f711aaad04815d3a4e6560aa2f96e157983711a91479` +[kubernetes-client-linux-arm64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-linux-arm64.tar.gz) | `f72944d2f8a16c5890048c3d06e087d9b2031f7d6f0f79a9bacdaa3cc4280495706b2ac71fa8bac0cd14210a7ca2cbac1cb6827660c6910eaff394a0c4908572` +[kubernetes-client-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-linux-ppc64le.tar.gz) | `62f3a806f4a74283a492e8a642d5d3ca625148be3ab7778fcdadc8d25da39f9857e4d060c4c9f3dd30800ef906bd8868b4cf8a09c7a56a1d65c965e4b3e14a00` +[kubernetes-client-linux-s390x.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-linux-s390x.tar.gz) | `63c1d6fc331297541b52edd4e59824bba50f8bef36fceaa16eb9792577af8ac09f939f8c6bea2f687b9bc703e6acadb227bad02b2a86aa5a2bf7c91c44403a94` +[kubernetes-client-windows-386.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-windows-386.tar.gz) | `4406456d3db26bb5cba408ad4d425dd595752745be683387ec043f945f186213e8a7f17713c38f26de4189b5ee9ebd6f15374a44b722a080b739bd31f92fb16c` +[kubernetes-client-windows-amd64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-client-windows-amd64.tar.gz) | `632853db2e1e2dd9f96406a9a6106c40aa34d1abbceea0b3b641599bb79bb924b01df19d597d42d007a03be0b24bedb107d8092268993b3713a1e0fb54cb6857` + +### Server Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-server-linux-amd64.tar.gz) | `37b6b05ff429c11895224d7bfff64dd7826b82456b4dbcc84a3adf5e86eec6a130e215de88c4204c45761009319aee3801b44e34344a874b7afeabebc74d7a2f` +[kubernetes-server-linux-arm.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-server-linux-arm.tar.gz) | `cd67cd06d90aad2e66b57abf103021f954c029efb8678df701c53e335c480a7520f423a58f11117b02a8b30a7221967c30ebca991b25e33ba422c2e7a782f15d` +[kubernetes-server-linux-arm64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-server-linux-arm64.tar.gz) | `b8a6a4d6f138e701a3acda8eaa3586ed2f5137463112f339b69bb0f46ff6c73c84df48b84e35efa4863d8f2d0722288ef9fe09eb2ec98d52568bd434661b9da9` +[kubernetes-server-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-server-linux-ppc64le.tar.gz) | `a55fb0b4e618c8e585bae7e526732b33021520947e182c846f85620c513d6610ee2e367b86d74b110903b9e29b4fd8491acef32db80a43dfdb296fc90b0b64a9` +[kubernetes-server-linux-s390x.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-server-linux-s390x.tar.gz) | `e63df3aa71a5e60189f7931dfc50764162c6d8d49c3df4dc92c4e10e576cf3656ac629ed18e7da729a6a0c3fa2f845716bef62a52b95ef4089e581596de2f390` + +### Node Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-node-linux-amd64.tar.gz) | `63a41ae964dd934e378c834998e7f20a4c14b819d68f39607344b6baacaf41f4bb7848be96ac0501e26114006560d89348d4be35aa34cc6650220cbd699bda8b` +[kubernetes-node-linux-arm.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-node-linux-arm.tar.gz) | `9379574f4458e91ab025a0c0aab5f4abedd991afad23d447b294c2d3293ca2f7f68b6e94eb9417a6fad06dee223877e858dfaaa2582d8b5c092bbb7bce860e14` +[kubernetes-node-linux-arm64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-node-linux-arm64.tar.gz) | `027b4f5149a3125ac713e7d974cbb8cba079a7b425b9b096877a74ea30697c8525060729de5556214e1caf34bf6b8a9820688e76fa18250165c2061a64446f47` +[kubernetes-node-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-node-linux-ppc64le.tar.gz) | `a486432f3e8a83d10c8e14811e24ba7d5d4e57e17fee7aed11429271aaf8b31ae38403480c2e8fbc2a7c0e2cd855607ce3b398a8b5de25b45c905dbd209669a6` +[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-node-linux-s390x.tar.gz) | `33e4bf55260aec16b4576c09144caa149811bb37868fff34b0138815fa2c159b2d5885c33c47fc4f71ad4edf6f90db6aa851380b05e1e4064f35b2f8e33c8b14` +[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.12.2/kubernetes-node-windows-amd64.tar.gz) | `e6abdf845e80942ea4757219900a7b0d16fd2d6313f22145d71e51fe22c161ac0b2f0f744d51f99682b2b153cdc8434d61b53c6d37c2585ea46aba6ee26be108` + +## Changelog since v1.12.1 + +### Other notable changes + +* IPVS proxier mode now support connection based graceful termination. ([#66012](https://github.com/kubernetes/kubernetes/pull/66012), [@Lion-Wei](https://github.com/Lion-Wei)) +* add more logging for azure disk diagnostics ([#70012](https://github.com/kubernetes/kubernetes/pull/70012), [@andyzhangx](https://github.com/andyzhangx)) +* Scheduling conformance tests related to daemonsets should set the annotation that relaxes node selection restrictions, if any are set. This ensures conformance tests can run on a wider array of clusters. ([#68793](https://github.com/kubernetes/kubernetes/pull/68793), [@aveshagarwal](https://github.com/aveshagarwal)) +* Disabled ScheduleDaemonSetPods if kubelet version less than 1.11; and ScheduleDaemonSetPods is not supported on a 1.13 control plane / 1.10 kubelet split. ([#69566](https://github.com/kubernetes/kubernetes/pull/69566), [@k82cn](https://github.com/k82cn)) +* kubeadm: fix an issue where 'config view' did not return a config in case of a 1.12 cluster ([#69969](https://github.com/kubernetes/kubernetes/pull/69969), [@neolit123](https://github.com/neolit123)) +* Updates defaultbackend to 1.5 ([#69380](https://github.com/kubernetes/kubernetes/pull/69380), [@bowei](https://github.com/bowei)) +* Restrict redirect following from the apiserver to same-host redirects, and ignore redirects in some cases. ([#66516](https://github.com/kubernetes/kubernetes/pull/66516), [@tallclair](https://github.com/tallclair)) +* Enable insertId generation, and update Stackdriver Logging Agent image to 0.5-1.5.36-1-k8s. This help reduce log duplication and guarantee log order. ([#68920](https://github.com/kubernetes/kubernetes/pull/68920), [@qingling128](https://github.com/qingling128)) +* Fix cluster autoscaler addon permissions so it can access batch/job. ([#69858](https://github.com/kubernetes/kubernetes/pull/69858), [@losipiuk](https://github.com/losipiuk)) +* Add tolerations for Stackdriver Logging and Metadata Agents. ([#69737](https://github.com/kubernetes/kubernetes/pull/69737), [@qingling128](https://github.com/qingling128)) +* change default azure file mount permission to 0777 ([#69854](https://github.com/kubernetes/kubernetes/pull/69854), [@andyzhangx](https://github.com/andyzhangx)) +* Fix a bug in the scheduler that could cause the scheduler to go to an infinite loop when all nodes in a zone are removed. ([#69758](https://github.com/kubernetes/kubernetes/pull/69758), [@bsalamat](https://github.com/bsalamat)) +* fix GetVolumeLimits log flushing issue ([#69558](https://github.com/kubernetes/kubernetes/pull/69558), [@andyzhangx](https://github.com/andyzhangx)) +* kube-apiserver: fixes `procMount` field incorrectly being marked as required in openapi schema ([#69744](https://github.com/kubernetes/kubernetes/pull/69744), [@jessfraz](https://github.com/jessfraz)) +* [GCE] Enable by default audit logging truncating backend. ([#68288](https://github.com/kubernetes/kubernetes/pull/68288), [@loburm](https://github.com/loburm)) +* kubeadm: fix a possible scenario where kubeadm can pull much newer control-plane images ([#69301](https://github.com/kubernetes/kubernetes/pull/69301), [@neolit123](https://github.com/neolit123)) +* The runtimeHandler field on the RuntimeClass resource now accepts the empty string. ([#69550](https://github.com/kubernetes/kubernetes/pull/69550), [@tallclair](https://github.com/tallclair)) +* OpenAPI spec and API reference now reflect dryRun query parameter for POST/PUT/PATCH operations ([#69359](https://github.com/kubernetes/kubernetes/pull/69359), [@roycaihw](https://github.com/roycaihw)) + + + # v1.12.1 [Documentation](https://docs.k8s.io) @@ -1433,6 +1513,8 @@ filename | sha256 hash * kube-apiserver: the `Priority` admission plugin is now enabled by default when using `--enable-admission-plugins`. If using `--admission-control` to fully specify the set of admission plugins, the `Priority` admission plugin should be added if using the `PodPriority` feature, which is enabled by default in 1.11. ([#65739](https://github.com/kubernetes/kubernetes/pull/65739), [@liggitt](https://github.com/liggitt)) * The `system-node-critical` and `system-cluster-critical` priority classes are now limited to the `kube-system` namespace by the `PodPriority` admission plugin. ([#65593](https://github.com/kubernetes/kubernetes/pull/65593), [@bsalamat](https://github.com/bsalamat)) * kubernetes-worker juju charm: Added support for setting the --enable-ssl-chain-completion option on the ingress proxy. "action required": if your installation relies on supplying incomplete certificate chains and using OCSP to fill them in, you must set "ingress-ssl-chain-completion" to "true" in your juju configuration. ([#63845](https://github.com/kubernetes/kubernetes/pull/63845), [@paulgear](https://github.com/paulgear)) +* In anticipation of CSI 1.0 in the next release, Kubernetes 1.12 calls the CSI `NodeGetInfo` RPC instead of `NodeGetId` RPC. Ensure your CSI Driver implements `NodeGetInfo(...)` before upgrading to 1.12. [@saad-ali](https://github.com/kubernetes/kubernetes/issues/68688) +* Kubernetes 1.12 also enables [Kubelet device plugin registration](https://github.com/kubernetes/features/issues/595) feature by default. Before upgrading to 1.12, ensure the `driver-registrar` CSI sidecar container for your CSI driver is configured to handle plugin registration (set the `--kubelet-registration-path` parameter on `driver-registrar` to expose a new unix domain socket to handle Kubelet Plugin Registration). ### Other notable changes diff --git a/CHANGELOG-1.13.md b/CHANGELOG-1.13.md index c050ea08a2b16..595fb21439019 100644 --- a/CHANGELOG-1.13.md +++ b/CHANGELOG-1.13.md @@ -1,17 +1,215 @@ -- [v1.13.0-alpha.1](#v1130-alpha1) - - [Downloads for v1.13.0-alpha.1](#downloads-for-v1130-alpha1) +- [v1.13.0-alpha.3](#v1130-alpha3) + - [Downloads for v1.13.0-alpha.3](#downloads-for-v1130-alpha3) - [Client Binaries](#client-binaries) - [Server Binaries](#server-binaries) - [Node Binaries](#node-binaries) + - [Changelog since v1.13.0-alpha.2](#changelog-since-v1130-alpha2) + - [Other notable changes](#other-notable-changes) +- [v1.13.0-alpha.2](#v1130-alpha2) + - [Downloads for v1.13.0-alpha.2](#downloads-for-v1130-alpha2) + - [Client Binaries](#client-binaries-1) + - [Server Binaries](#server-binaries-1) + - [Node Binaries](#node-binaries-1) + - [Changelog since v1.13.0-alpha.1](#changelog-since-v1130-alpha1) + - [Other notable changes](#other-notable-changes-1) +- [v1.13.0-alpha.1](#v1130-alpha1) + - [Downloads for v1.13.0-alpha.1](#downloads-for-v1130-alpha1) + - [Client Binaries](#client-binaries-2) + - [Server Binaries](#server-binaries-2) + - [Node Binaries](#node-binaries-2) - [Changelog since v1.12.0](#changelog-since-v1120) - [Action Required](#action-required) - - [Other notable changes](#other-notable-changes) + - [Other notable changes](#other-notable-changes-2) +# v1.13.0-alpha.3 + +[Documentation](https://docs.k8s.io) + +## Downloads for v1.13.0-alpha.3 + + +filename | sha512 hash +-------- | ----------- +[kubernetes.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes.tar.gz) | `1d50cfd34306ace7354516125c45f8c546bba3ca5081af2b21969b535967d302821c06e7d4d590ba05f3e1e89ba56cc3d890b2e5bf2e07456532ac28e7c6c4a8` +[kubernetes-src.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-src.tar.gz) | `bf097b99d7b9af15bc1d592ee3782da1e811d8eb68dc9ae9d287589ce9174d3743beaf51422283c42ad03775e43839954bdeb44b1aa5707f73eebabed0cc199e` + +### Client Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-client-darwin-386.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-darwin-386.tar.gz) | `77778ae2887eda52ee716fb0e843c17b2705b1284a67cdf53f91292eb7f1055ef942be1ae0eac25ad9f4c9062c802fd57943e57578113f875f0d1f8a227bbb25` +[kubernetes-client-darwin-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-darwin-amd64.tar.gz) | `b3399767df12b71ee4b7b30126bd8001a0c1396161eb7535d797fd5847c55bccc18fb475f1639c3bf8e5f5c484a61025108c01e35f71417a405e75580c3990f6` +[kubernetes-client-linux-386.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-linux-386.tar.gz) | `5ef0d318ff8da28c332ae25164e5a441272d2ee8ef2ac26438a47fe3e7e645ed0b132325243f3f33c93a8681431a117f6207893f0e5270738aacfee16d8bbd32` +[kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-linux-amd64.tar.gz) | `1f429eae5b0b1e39b1d4d30e3220a82d0ae6672a6f4b34a05246c3efc131a236f79e5876d7a98c56d98fbf243b96cfd8db5d1ab73905df9e000d7af2b710fcf3` +[kubernetes-client-linux-arm.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-linux-arm.tar.gz) | `5583aecdc9b4a54a4aa904fc1de66400f50628969e31b5a63ab1d3b6628e3c547a9cef9c2bc9e53a0eeb0155fa0f745f7ee47e92166ce66d0c79199ff20c41de` +[kubernetes-client-linux-arm64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-linux-arm64.tar.gz) | `2453b9100c06b11e8c424d59cfd1c5e111c22b596191a9cfb0b330d198abecd982e19eb2ac38d91c3d1ef226c9533c4f9a210b88295029985739e86363905de5` +[kubernetes-client-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-linux-ppc64le.tar.gz) | `4991ec4c19a82d50caed78bc8db51e7cdcd1f2896dfcaa45d84f347a72fe7ee0d0280c897af54afec93f548d2ce247cf70d2b439024752ff701b80b67c385913` +[kubernetes-client-linux-s390x.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-linux-s390x.tar.gz) | `c55f2802afb2e5d261bb26b6c396df8ebe6b95913ddab1e124cf177f59a00524a26cc9dd74cbf06cc7a6a2207ccba2d3a8585f20a37485214d9b1bebb27fdde7` +[kubernetes-client-windows-386.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-windows-386.tar.gz) | `df78465267e35ef078c3c0fd33f8898a9df26fbf411df3ed3283fbdc2e79380693abe2a2815d5a4d53742135db4b5a0a480ce301817ede5c0674b12ac9c9bac9` +[kubernetes-client-windows-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-client-windows-amd64.tar.gz) | `5b93fdaaa931ef8e24196e53c484f91ef9e50b7d11e1053ccb61b2d6bdc8164767dd1d885cdc4949fdb7ed05cfbc7c9f7cc3468ad7affc22f849836b311d855f` + +### Server Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-server-linux-amd64.tar.gz) | `922a93ce677e686e594c11db75e1969c995b23062bba511bff4a43d3a530e21e1d15cbe9b38d06af407de5a6c141f3b10cf24f50b848ed6b36e701249cece2c3` +[kubernetes-server-linux-arm.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-server-linux-arm.tar.gz) | `5dd550b58dedf25df020e66f1526e80c50b46d2df3ddd241bd02b6ebf10308599e7739917cbd9a3d2d3e787078d1271c4e3333f7f343a8a754ac5c08dedba0c9` +[kubernetes-server-linux-arm64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-server-linux-arm64.tar.gz) | `3e1037e71d85a74cd5d40dd836bd442b2dcc457f8ccc8247e4537f3deca6f99d6805857c44b4fd69a7655308a3b0b4be43faaf74017cc3e26e8ba81e84968f33` +[kubernetes-server-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-server-linux-ppc64le.tar.gz) | `a89c46b558613ad09efe44a81574ad18157a787d1e9c5d09c98d3911b499573cd9b9845b7a7526d4de5b93887267bedd96d043f79799552639b2168d3fea49ab` +[kubernetes-server-linux-s390x.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-server-linux-s390x.tar.gz) | `47a68668e38ac1b8cb801f4bff3b15060cd88801f446ebfbf06125dbc9aef52be79faa94acee65af46b93512af6f15c1f9f598324a368b82996f5a0f9aca0d14` + +### Node Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-node-linux-amd64.tar.gz) | `74d5d46ac6ba336fa8aaf55d0a15860f6ebde2ff58d377ca93063593da12fbd4c758fe92c6b3285df0e4cc23c354ce5802ae3f7c38ad4e63f9d1eeaef41f2f2b` +[kubernetes-node-linux-arm.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-node-linux-arm.tar.gz) | `90372cb5270ffe6179d5d7efd3fff6aa029f73853805038fef1a6f92683399d692aee7790eacc3a59681f66e2bd21b76c3abd87bef6404382782ec82fb726d59` +[kubernetes-node-linux-arm64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-node-linux-arm64.tar.gz) | `09693303a1a8489d9599d32f7fbf549d18f31eb53671fa2ed342fe5089f2fba9322d8c52088b141da2414bb2b7f8352634cf84f0c72f3a58afd057629c3e8e5b` +[kubernetes-node-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-node-linux-ppc64le.tar.gz) | `cbdb3b9ffd9be524ec0b38d72b0545b6dd1b3b789747f41a661fd7cbeffe942eb592c7e928a61e26152e7402b4894f5a74aad09cf2243d726b3b311d41cb0674` +[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-node-linux-s390x.tar.gz) | `fc296b386bc03bf10773559118cd4a3d5be3d4c296f09748507fac812a1c791b435881b2ae425846632404f7f53f3f3bf54fc582fb8aa4895310186371dbacfd` +[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.3/kubernetes-node-windows-amd64.tar.gz) | `ae79c62fcb0654a62606d65cf131188d93e4a10787a862e7b0363269942df19543b55fd119ec6ff73578b24db7774235611956103fe5e153eddf450750c4bbee` + +## Changelog since v1.13.0-alpha.2 + +### Other notable changes + +* kubelet --system-reserved and --kube-reserved are supported now on Windows nodes ([#69960](https://github.com/kubernetes/kubernetes/pull/69960), [@feiskyer](https://github.com/feiskyer)) +* CSI drivers now have access to mountOptions defined on the storage class when attaching volumes. ([#67898](https://github.com/kubernetes/kubernetes/pull/67898), [@bswartz](https://github.com/bswartz)) +* The `kubectl plugin list` command will now display discovered plugin paths in the same order as they are found in a user's PATH variable. ([#70443](https://github.com/kubernetes/kubernetes/pull/70443), [@juanvallejo](https://github.com/juanvallejo)) +* Handle Windows named pipes in host mounts. ([#69484](https://github.com/kubernetes/kubernetes/pull/69484), [@ddebroy](https://github.com/ddebroy)) +* kubeadm: Multiple API server endpoints support upon join is removed as it is now redundant. ([#69812](https://github.com/kubernetes/kubernetes/pull/69812), [@rosti](https://github.com/rosti)) +* OpenAPI spec marks delete request's body parameter as optional ([#70032](https://github.com/kubernetes/kubernetes/pull/70032), [@iamneha](https://github.com/iamneha)) +* kube-controller-manager and cloud-controller-manager now hold generated serving certificates in-memory unless a writeable location is specified with --cert-dir ([#69884](https://github.com/kubernetes/kubernetes/pull/69884), [@liggitt](https://github.com/liggitt)) +* Scheduler only activates unschedulable pods if node's scheduling related properties change. ([#70366](https://github.com/kubernetes/kubernetes/pull/70366), [@mlmhl](https://github.com/mlmhl)) +* --api-audiences now defaults to the --service-account-issuer if the issuer is provided but the API audience is not. ([#70308](https://github.com/kubernetes/kubernetes/pull/70308), [@mikedanese](https://github.com/mikedanese)) +* Refactor scheduler_test.go to use a fake k8s client. ([#70290](https://github.com/kubernetes/kubernetes/pull/70290), [@tossmilestone](https://github.com/tossmilestone)) +* `kubectl rollout undo` now returns errors when attempting to rollback a deployment to a non-existent revision ([#70039](https://github.com/kubernetes/kubernetes/pull/70039), [@liggitt](https://github.com/liggitt)) + * `kubectl rollout undo` no longer uses the deprecated extensions/v1beta1 rollback API, which means that Events are no longer emitted when rolling back a deployment +* - The builtin system:csi-external-provisioner and system:csi-external-attacher cluster roles ([#69868](https://github.com/kubernetes/kubernetes/pull/69868), [@pohly](https://github.com/pohly)) + * are deprecated and will not be updated for deployments of CSI sidecar container versions >= 0.4. + * Deployments with the current CSI sidecar containers have to provide their own RBAC + * definitions. The reason is that the rules depend on how the sidecar containers are used, + * which is defined by the deployment. +* Use debian-base instead of busybox as base image for server images ([#70245](https://github.com/kubernetes/kubernetes/pull/70245), [@ixdy](https://github.com/ixdy)) +* add support for projected volume in describe function ([#70158](https://github.com/kubernetes/kubernetes/pull/70158), [@WanLinghao](https://github.com/WanLinghao)) +* Speedup process lookup in /proc ([#66367](https://github.com/kubernetes/kubernetes/pull/66367), [@cpuguy83](https://github.com/cpuguy83)) +* Kubeadm reset now clean up custom etcd data path ([#70003](https://github.com/kubernetes/kubernetes/pull/70003), [@yagonobre](https://github.com/yagonobre)) +* We changed when the `metadata.generation` of a custom resource (CR) increments. ([#69059](https://github.com/kubernetes/kubernetes/pull/69059), [@caesarxuchao](https://github.com/caesarxuchao)) + * If the CR participates the spec/status convention, the metadata.generation of the CR increments when there is any change, except for the changes to the metadata or the changes to the status. + * If the CR does not participate the spec/status convention, the metadata.generation of the CR increments when there is any change to the CR, except for changes to the metadata. + * A CR is considered to participate the spec/status convention if and only if the "CustomResourceSubresources" feature gate is turned on and the CRD has `.spec.subresources.status={}`. +* Improve Azure instance metadata handling by adding caches. ([#70353](https://github.com/kubernetes/kubernetes/pull/70353), [@feiskyer](https://github.com/feiskyer)) +* adding cn-northwest-1 for AWS China Ningxia region ([#70155](https://github.com/kubernetes/kubernetes/pull/70155), [@pahud](https://github.com/pahud)) +* "kubectl get" no longer exits before printing all of its results if an error is found ([#70311](https://github.com/kubernetes/kubernetes/pull/70311), [@juanvallejo](https://github.com/juanvallejo)) +* kubeadm now automatically creates a new stacked etcd member when joining a new control plane node (does not applies to external etcd) ([#69486](https://github.com/kubernetes/kubernetes/pull/69486), [@fabriziopandini](https://github.com/fabriziopandini)) +* Critical pod annotation is deprecated. Pod priority should be used instead to mark pods as critical. ([#70298](https://github.com/kubernetes/kubernetes/pull/70298), [@bsalamat](https://github.com/bsalamat)) +* Display the usage of ephemeral-storage when using `kubectl describe node` ([#70268](https://github.com/kubernetes/kubernetes/pull/70268), [@Pingan2017](https://github.com/Pingan2017)) +* Added functionality to enable br_netfilter and ip_forward for debian packages to improve kubeadm support for CRI runtime besides Docker. ([#70152](https://github.com/kubernetes/kubernetes/pull/70152), [@ashwanikhemani](https://github.com/ashwanikhemani)) +* Add regions ap-northeast-3 and eu-west-3 to the list of well known AWS regions. ([#70252](https://github.com/kubernetes/kubernetes/pull/70252), [@nckturner](https://github.com/nckturner)) +* Remove kube-controller-manager flag '--insecure-experimental-approve-all-kubelet-csrs-for-group'(deprecated in v1.7) ([#69209](https://github.com/kubernetes/kubernetes/pull/69209), [@Pingan2017](https://github.com/Pingan2017)) +* GCE/GKE load balancer health check default interval changes from 2 seconds to 8 seconds, unhealthyThreshold to 3. ([#70099](https://github.com/kubernetes/kubernetes/pull/70099), [@grayluck](https://github.com/grayluck)) + * Health check parameters are configurable to be bigger than default values. +* The kubectl wait command must handle when a watch returns an error vs closing by printing out the error and retrying the watch. ([#69389](https://github.com/kubernetes/kubernetes/pull/69389), [@smarterclayton](https://github.com/smarterclayton)) +* Updates to use debian-iptables v11.0, debian-hyperkube-base 0.12.0, and kube-addon-manager:v8.9. ([#70209](https://github.com/kubernetes/kubernetes/pull/70209), [@ixdy](https://github.com/ixdy)) +* Fixed patch/update operations on multi-version custom resources ([#70087](https://github.com/kubernetes/kubernetes/pull/70087), [@liggitt](https://github.com/liggitt)) +* When `--rotate-server-certificates` is enabled, kubelet will no longer request a new certificate on startup if the current certificate on disk is satisfactory. ([#69991](https://github.com/kubernetes/kubernetes/pull/69991), [@agunnerson-ibm](https://github.com/agunnerson-ibm)) +* - Support for passing unknown provider names to the E2E test binaries is going to be deprecated. Use `--provider=skeleton` (no ssh access) or `--provider=local` (local cluster with ssh) instead. ([#70141](https://github.com/kubernetes/kubernetes/pull/70141), [@pohly](https://github.com/pohly)) +* Add scheduler benchmark tests for PodAffinity and NodeAffinity. ([#69898](https://github.com/kubernetes/kubernetes/pull/69898), [@Huang-Wei](https://github.com/Huang-Wei)) +* fix azure disk attachment error on Linux ([#70002](https://github.com/kubernetes/kubernetes/pull/70002), [@andyzhangx](https://github.com/andyzhangx)) + + + +# v1.13.0-alpha.2 + +[Documentation](https://docs.k8s.io) + +## Downloads for v1.13.0-alpha.2 + + +filename | sha512 hash +-------- | ----------- +[kubernetes.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes.tar.gz) | `cbe7ef29c7e7bbed82e173289f5f84d7a85ee4965cc5b7ccd16cf8236a3b8171bb8f52011d00ea4dd1119cfeee32a3326260e968038431f2834f194e84f6f070` +[kubernetes-src.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-src.tar.gz) | `8b0b8e1b635cd849c2974d755fe174f0ce8fe8c690721d8ac6312683bbd2ca2c6f7eada38e4e470d3a0172138b10a994fa3bebc01abd76d835431660247e8a71` + +### Client Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-client-darwin-386.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-darwin-386.tar.gz) | `fca661a5001e7f368374d0805f20910be24baa485bf4ae5d993185b974f70ff7241497e7a130658dca69abf335fd581c0f5be22de4f9937f32e9fb20fbd0f1e9` +[kubernetes-client-darwin-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-darwin-amd64.tar.gz) | `d31dfea475981c7f7b758c7f201aa5b866db48d87942c79d0a12d464b7cdf501dba2255282c72b53928ccac215282fc8c0a9069a7443e9683bbf39a59814d8c3` +[kubernetes-client-linux-386.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-linux-386.tar.gz) | `fecf8362c572fff48952fd2748ddcb9d375462cb484670cda4fda1387eb692713be0a323e93746bb1845a4ef3b15df288430c8b4a5e4f2892c388bb84a66ec9a` +[kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-linux-amd64.tar.gz) | `136cb82ac94bcd791d56e997a948a7e1bee4af03bcc69ce9c835895cdda75524f5916756c778ff8aa693624289824eaee4aff1e62a6d95d18f9b69a7473a3fe9` +[kubernetes-client-linux-arm.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-linux-arm.tar.gz) | `e561c37895edef44614ecd59f497d393275ee62455b6269b169a891873d661d46cbf68e6148447f142ebdddb45bd5c01f6927d8463e2e1c4072358fec205e53e` +[kubernetes-client-linux-arm64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-linux-arm64.tar.gz) | `c0d5eb49763e8bf50b5e8e3785c7889fecbd8bf7c0b3c18250fa894a1c5e58a14f796f7526279dbf41d5d47e69114d39e37a62403ff4abb1cc0cd20bd48c1c5a` +[kubernetes-client-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-linux-ppc64le.tar.gz) | `a5a8c150af163e7c726662eeddfc3de8e43f123daaa100b8e82c9bc786313a5ce8135cbaadd41ebbb6c2307aeebdadf43fc84037a5ac9d3c5d6e9052b7fc615b` +[kubernetes-client-linux-s390x.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-linux-s390x.tar.gz) | `fd162e0244e107f1892d79029f3452cdba84d8616ad1b15eebe197afb3b536328cd8cba9c73c0ce1cd8ac6faed9e0a4613d487bf07b45341fadf0d940062bafa` +[kubernetes-client-windows-386.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-windows-386.tar.gz) | `e01fedec8f700e037bc43cb13bc916b85601cd1c9361a0f63fd27092640f89d2faaff4a6157638af8af52538c5f7fa75d9c7674477a45e0215fd505095a62f21` +[kubernetes-client-windows-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-client-windows-amd64.tar.gz) | `d2601efcfa6a4ba8a017e9cac571fb454b21b7700a7b3f8e2fbabdd5301545ef2459da93eca3684c1aa73ea6a6d87bae0e27fffc8b05ed93729004ebbb9e3879` + +### Server Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-server-linux-amd64.tar.gz) | `4dda298d44bc309f250c067e9282eea37903838a140cf5abf6f861dca624d5a055ba1c43129454ae9abc8350f1fffb224677e34ef4268f7eb43c96fe48b28d78` +[kubernetes-server-linux-arm.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-server-linux-arm.tar.gz) | `e9c3bdf60272399bc6f85a15bbc55cd69db389c223b275661ddcab4ae8c3afcd2171ec3c35a53df2420376f8c6294af791776e16dc07a27438aaa3220d6c94a3` +[kubernetes-server-linux-arm64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-server-linux-arm64.tar.gz) | `d0a1701a34365f939799b6ea676129acdcfa1582bcf50e82a9751d9aafc73ebffd0fc0365fe352755caa9a2b791c4195d7eb04fbb1ce660f107cb5257d57a967` +[kubernetes-server-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-server-linux-ppc64le.tar.gz) | `1a23473960aaaa639e796020741b63c11dad8a93903926e80c871814b8209166ef06f5205172cd9b2438f8c8e9c9fb50b96d983f56737ab252530112f816b2d6` +[kubernetes-server-linux-s390x.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-server-linux-s390x.tar.gz) | `293d0eb93e2ed641d0c1e26d58423670c04c307dddb034a9fc252043abe5694f63e772d4dfe2bf505fc0b68c41f9d87800d867b87c7697dd6249b11c0efbc580` + +### Node Binaries + +filename | sha512 hash +-------- | ----------- +[kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-node-linux-amd64.tar.gz) | `e3cba71c2b2d151cdcc44937c1bea083ee0ceb829e7feb25cd37edd4d0bd7adac0a166144bd33f9aa616d730785d52c3fee70f0db272d892e79c38eb544cfd22` +[kubernetes-node-linux-arm.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-node-linux-arm.tar.gz) | `28d7f1cf4fecdc72da7f5f19836cc06bb08182f8e8fb1641dc01e9299247905e305b04c676efa9afbdb8b1ed649542148406b110b75b1e87c1daca7ffed6018c` +[kubernetes-node-linux-arm64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-node-linux-arm64.tar.gz) | `cfe22b11502cd857f0e277e7c1af08e6202f7ffc36f852c6154159bdd67bb330ffd18e5f768cf6968f0524aa80ffba6b7012207831ba94dec4084f1ce38a5289` +[kubernetes-node-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-node-linux-ppc64le.tar.gz) | `195a6785c49af419361a8901c99bb6613a6578a8eac5e8f08ec28077645be18c6d04c9afc2839d07de27b15595584f6dff5e5f9e78001fc2c6a3249e99b82247` +[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-node-linux-s390x.tar.gz) | `51f5b5ed47b50f5188d9e2f57b03555492d3e490494842247fa04fe81ea350c6694a52caa46ea50578ca07e48212f4f714b8614d8b1eb8924b424eaed73a8d24` +[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.13.0-alpha.2/kubernetes-node-windows-amd64.tar.gz) | `d2690d57cd485c0c7ebe425464ad59f2c7722870abd6f264ea7fae65a4e403c89446373ba9cd23cd43e8316902637aa9e0b23d571b0ac890c35ff8e9c3ff3c3b` + +## Changelog since v1.13.0-alpha.1 + +### Other notable changes + +* Corrected family type (inet6) for ipsets in ipv6-only clusters ([#68436](https://github.com/kubernetes/kubernetes/pull/68436), [@uablrek](https://github.com/uablrek)) +* Corrects check for non-Azure managed nodes with the Azure cloud provider ([#70135](https://github.com/kubernetes/kubernetes/pull/70135), [@marc-sensenich](https://github.com/marc-sensenich)) +* Windows runtime endpoints is now switched to 'npipe:////./pipe/dockershim' from 'tcp://localhost:3735'. ([#69516](https://github.com/kubernetes/kubernetes/pull/69516), [@feiskyer](https://github.com/feiskyer)) +* The caBundle and service fields in admission webhook API objects now correctly indicate they are optional ([#70138](https://github.com/kubernetes/kubernetes/pull/70138), [@liggitt](https://github.com/liggitt)) +* The --service-account-api-audiences on kube-apiserver is deprecated in favor of --api-audiences. ([#70105](https://github.com/kubernetes/kubernetes/pull/70105), [@mikedanese](https://github.com/mikedanese)) +* kubeadm: fix unnecessary upgrades caused by undefined order of Volumes and VolumeMounts in manifests ([#70027](https://github.com/kubernetes/kubernetes/pull/70027), [@bart0sh](https://github.com/bart0sh)) +* kubeadm: Implemented preflight check to ensure that number of CPUs ([#70048](https://github.com/kubernetes/kubernetes/pull/70048), [@bart0sh](https://github.com/bart0sh)) + * on the master node is not less than required. +* Reduce memory utilization of admission webhook metrics by removing resource related labels. ([#69895](https://github.com/kubernetes/kubernetes/pull/69895), [@jpbetz](https://github.com/jpbetz)) +* kubeadm: Introduce config print init/join-defaults that deprecate config print-defaults by decoupling init and join configs. ([#69617](https://github.com/kubernetes/kubernetes/pull/69617), [@rosti](https://github.com/rosti)) +* Images based on debian-base no longer include the libsystemd0 package. This should have no user-facing impact. ([#69995](https://github.com/kubernetes/kubernetes/pull/69995), [@ixdy](https://github.com/ixdy)) + * Additionally, the addon-manager image is updated to use kubectl v1.11.3. +* fix 'kubeadm upgrade' infinite loop waiting for pod restart ([#69886](https://github.com/kubernetes/kubernetes/pull/69886), [@bart0sh](https://github.com/bart0sh)) +* add more logging for azure disk diagnostics ([#70012](https://github.com/kubernetes/kubernetes/pull/70012), [@andyzhangx](https://github.com/andyzhangx)) +* Fluentd: concatenate long logs ([#68012](https://github.com/kubernetes/kubernetes/pull/68012), [@desaintmartin](https://github.com/desaintmartin)) +* CoreDNS is now the default DNS server in kube-up deployments. ([#69883](https://github.com/kubernetes/kubernetes/pull/69883), [@chrisohaver](https://github.com/chrisohaver)) +* Optimizes calculating stats when only CPU and Memory stats are returned from Kubelet stats/summary http endpoint. ([#68841](https://github.com/kubernetes/kubernetes/pull/68841), [@krzysztof-jastrzebski](https://github.com/krzysztof-jastrzebski)) +* kubeadm: Fix node join taints. ([#69846](https://github.com/kubernetes/kubernetes/pull/69846), [@andrewrynhard](https://github.com/andrewrynhard)) +* Opt out of chowning and chmoding from kubectl cp. ([#69573](https://github.com/kubernetes/kubernetes/pull/69573), [@bjhaid](https://github.com/bjhaid)) +* support Azure premium file for azure file plugin ([#69718](https://github.com/kubernetes/kubernetes/pull/69718), [@andyzhangx](https://github.com/andyzhangx)) +* `TaintBasedEvictions` feature is promoted to beta. ([#69824](https://github.com/kubernetes/kubernetes/pull/69824), [@Huang-Wei](https://github.com/Huang-Wei)) +* improves memory use and performance when processing large numbers of pods containing tolerations ([#65350](https://github.com/kubernetes/kubernetes/pull/65350), [@liggitt](https://github.com/liggitt)) +* Add dynamic audit configuration api ([#67547](https://github.com/kubernetes/kubernetes/pull/67547), [@pbarker](https://github.com/pbarker)) +* Promote resource limits priority function to beta ([#69437](https://github.com/kubernetes/kubernetes/pull/69437), [@ravisantoshgudimetla](https://github.com/ravisantoshgudimetla)) +* Fix cluster autoscaler addon permissions so it can access batch/job. ([#69858](https://github.com/kubernetes/kubernetes/pull/69858), [@losipiuk](https://github.com/losipiuk)) +* change default azure file mount permission to 0777 ([#69854](https://github.com/kubernetes/kubernetes/pull/69854), [@andyzhangx](https://github.com/andyzhangx)) +* kubeadm: JoinConfiguration now houses the discovery options in a nested Discovery structure, which in turn has a couple of other nested structures to house more specific options (BootstrapTokenDiscovery and FileDiscovery) ([#67763](https://github.com/kubernetes/kubernetes/pull/67763), [@rosti](https://github.com/rosti)) +* Fix tests to use fsync instead of sync ([#69755](https://github.com/kubernetes/kubernetes/pull/69755), [@mrunalp](https://github.com/mrunalp)) +* kube-proxy argument `hostname-override` can be used to override hostname defined in the configuration file ([#69340](https://github.com/kubernetes/kubernetes/pull/69340), [@stevesloka](https://github.com/stevesloka)) +* kube-apiserver: the `--deserialization-cache-size` flag is no longer used, is deprecated, and will be removed in a future release ([#69842](https://github.com/kubernetes/kubernetes/pull/69842), [@liggitt](https://github.com/liggitt)) +* Add support for JSON patch in fake client ([#69330](https://github.com/kubernetes/kubernetes/pull/69330), [@vaikas-google](https://github.com/vaikas-google)) + + + # v1.13.0-alpha.1 [Documentation](https://docs.k8s.io) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index b83fcfb8dba49..d62c84eae16ed 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,6 +1,6 @@ { "ImportPath": "k8s.io/kubernetes", - "GoVersion": "go1.10", + "GoVersion": "go1.11", "GodepVersion": "v80", "Packages": [ "github.com/onsi/ginkgo/ginkgo", @@ -26,43 +26,43 @@ }, { "ImportPath": "cloud.google.com/go/compute/metadata", - "Comment": "v0.1.0-115-g3b1ae453", + "Comment": "v0.1.0-115-g3b1ae45", "Rev": "3b1ae45394a234c385be014e9a488f2bb6eef821" }, { "ImportPath": "cloud.google.com/go/internal", - "Comment": "v0.1.0-115-g3b1ae453", + "Comment": "v0.1.0-115-g3b1ae45", "Rev": "3b1ae45394a234c385be014e9a488f2bb6eef821" }, { - "ImportPath": "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute", - "Comment": "v21.1.0", - "Rev": "6d20bdbae88c06c36d72eb512295417693bfdf4e" + "ImportPath": "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute", + "Comment": "v21.3.0", + "Rev": "da91af54816b4cf72949c225a2d0980f51fab01b" }, { "ImportPath": "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry", - "Comment": "v21.1.0", - "Rev": "6d20bdbae88c06c36d72eb512295417693bfdf4e" + "Comment": "v21.3.0", + "Rev": "da91af54816b4cf72949c225a2d0980f51fab01b" }, { "ImportPath": "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network", - "Comment": "v21.1.0", - "Rev": "6d20bdbae88c06c36d72eb512295417693bfdf4e" + "Comment": "v21.3.0", + "Rev": "da91af54816b4cf72949c225a2d0980f51fab01b" }, { "ImportPath": "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage", - "Comment": "v21.1.0", - "Rev": "6d20bdbae88c06c36d72eb512295417693bfdf4e" + "Comment": "v21.3.0", + "Rev": "da91af54816b4cf72949c225a2d0980f51fab01b" }, { "ImportPath": "github.com/Azure/azure-sdk-for-go/storage", - "Comment": "v21.1.0", - "Rev": "6d20bdbae88c06c36d72eb512295417693bfdf4e" + "Comment": "v21.3.0", + "Rev": "da91af54816b4cf72949c225a2d0980f51fab01b" }, { "ImportPath": "github.com/Azure/azure-sdk-for-go/version", - "Comment": "v21.1.0", - "Rev": "6d20bdbae88c06c36d72eb512295417693bfdf4e" + "Comment": "v21.3.0", + "Rev": "da91af54816b4cf72949c225a2d0980f51fab01b" }, { "ImportPath": "github.com/Azure/go-ansiterm", @@ -74,43 +74,43 @@ }, { "ImportPath": "github.com/Azure/go-autorest/autorest", - "Comment": "v10.15.4", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Comment": "v11.1.0", + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/autorest/adal", - "Comment": "v10.15.4", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Comment": "v11.1.0", + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/autorest/azure", - "Comment": "v10.15.4", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Comment": "v11.1.0", + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/autorest/date", - "Comment": "v10.15.4", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Comment": "v11.1.0", + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/autorest/to", - "Comment": "v10.15.4", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Comment": "v11.1.0", + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/autorest/validation", - "Comment": "v10.15.4", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Comment": "v11.1.0", + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/logger", - "Comment": "v10.15.4", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Comment": "v11.1.0", + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/version", - "Comment": "v10.15.4", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Comment": "v11.1.0", + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/GeertJohan/go.rice", @@ -181,8 +181,8 @@ }, { "ImportPath": "github.com/asaskevich/govalidator", - "Comment": "v4-12-g593d645", - "Rev": "593d64559f7600f29581a3ee42177f5dbded27a9" + "Comment": "v9-26-gf9ffefc", + "Rev": "f9ffefc3facfbe0caee3fea233cbb6e8208f4541" }, { "ImportPath": "github.com/aws/aws-sdk-go/aws", @@ -361,78 +361,83 @@ }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/cmd/gazelle", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/config", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/flag", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/label", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/language", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/language/go", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/language/proto", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/merger", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/pathtools", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/repos", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/resolve", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/rule", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" + }, + { + "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/testtools", + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/version", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/walk", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/bazel-gazelle/internal/wspace", - "Comment": "0.14.0", - "Rev": "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1" + "Comment": "0.15.0", + "Rev": "c728ce9f663e2bff26361ba5978ec5c9e6816a3c" }, { "ImportPath": "github.com/bazelbuild/buildtools/build", @@ -897,368 +902,368 @@ }, { "ImportPath": "github.com/coreos/etcd/alarm", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/auth", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/client", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/concurrency", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/namespace", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/naming", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/compactor", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/discovery", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/embed", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/error", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/etcdhttp", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2v3", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3client", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/auth", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb/gw", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/membership", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/stats", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/integration", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease/leasehttp", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease/leasepb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc/backend", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/adt", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/contention", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/cors", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/cpuutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/crc", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/debugutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/httputil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/idutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/ioutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/logutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/netutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/pbutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/runtime", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/schedule", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/srv", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/testutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/wait", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/adapter", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/cache", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/raft", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/raft/raftpb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/rafthttp", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/snap", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/snap/snappb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/store", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/version", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/wal", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/wal/walpb", - "Comment": "v3.3.9", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Comment": "v3.3.10", + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/go-oidc", @@ -1266,37 +1271,38 @@ }, { "ImportPath": "github.com/coreos/go-semver/semver", - "Rev": "568e959cd89871e61434c1143528d9162da89ef2" + "Comment": "v0.2.0-9-ge214231", + "Rev": "e214231b295a8ea9479f11b70b35d5acf3556d9b" }, { "ImportPath": "github.com/coreos/go-systemd/daemon", - "Comment": "v14", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Comment": "v17", + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/coreos/go-systemd/dbus", - "Comment": "v14", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Comment": "v17", + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/coreos/go-systemd/journal", - "Comment": "v14", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Comment": "v17", + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/coreos/go-systemd/util", - "Comment": "v14", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Comment": "v17", + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/coreos/pkg/capnslog", - "Comment": "v2-8-gfa29b1d", - "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" + "Comment": "v4", + "Rev": "97fdf19511ea361ae1c100dd393cc47f8dcfa1e1" }, { "ImportPath": "github.com/coreos/pkg/dlopen", - "Comment": "v2-8-gfa29b1d", - "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" + "Comment": "v4", + "Rev": "97fdf19511ea361ae1c100dd393cc47f8dcfa1e1" }, { "ImportPath": "github.com/coreos/rkt/api/v1alpha", @@ -1351,147 +1357,147 @@ }, { "ImportPath": "github.com/docker/docker/api", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/blkiodev", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/container", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/events", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/filters", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/image", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/mount", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/network", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/registry", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/strslice", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/swarm", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/swarm/runtime", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/time", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/versions", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/api/types/volume", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/client", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/pkg/jsonmessage", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/pkg/mount", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/pkg/parsers", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/pkg/parsers/operatingsystem", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/pkg/stdcopy", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/pkg/sysinfo", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/pkg/term", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/docker/pkg/term/windows", - "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d", + "Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8dd", "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d" }, { "ImportPath": "github.com/docker/go-connections/nat", - "Comment": "v0.3.0", + "Comment": "v0.2.1-30-g3ede32e", "Rev": "3ede32e2033de7505e6500d6c868c2b9ed9f169d" }, { "ImportPath": "github.com/docker/go-connections/sockets", - "Comment": "v0.3.0", + "Comment": "v0.2.1-30-g3ede32e", "Rev": "3ede32e2033de7505e6500d6c868c2b9ed9f169d" }, { "ImportPath": "github.com/docker/go-connections/tlsconfig", - "Comment": "v0.3.0", + "Comment": "v0.2.1-30-g3ede32e", "Rev": "3ede32e2033de7505e6500d6c868c2b9ed9f169d" }, { @@ -1561,8 +1567,19 @@ }, { "ImportPath": "github.com/ghodss/yaml", + "Comment": "v1.0.0-4-gc7ce166", "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577" }, + { + "ImportPath": "github.com/globalsign/mgo/bson", + "Comment": "r2018.06.15-9-geeefdec", + "Rev": "eeefdecb41b842af6dc652aaea4026e8403e62df" + }, + { + "ImportPath": "github.com/globalsign/mgo/internal/json", + "Comment": "r2018.06.15-9-geeefdec", + "Rev": "eeefdecb41b842af6dc652aaea4026e8403e62df" + }, { "ImportPath": "github.com/go-ini/ini", "Comment": "v1.25.4", @@ -1570,43 +1587,58 @@ }, { "ImportPath": "github.com/go-openapi/analysis", - "Rev": "b44dc874b601d9e4e2f6e19140e794ba24bead3b" + "Comment": "v0.17.2", + "Rev": "c701774f4e604d952e4e8c56dee260be696e33c3" + }, + { + "ImportPath": "github.com/go-openapi/analysis/internal", + "Comment": "v0.17.2", + "Rev": "c701774f4e604d952e4e8c56dee260be696e33c3" }, { "ImportPath": "github.com/go-openapi/errors", - "Rev": "d24ebc2075bad502fac3a8ae27aa6dd58e1952dc" + "Comment": "v0.17.2", + "Rev": "d9664f9fab8994271e573ed69cf2adfc09b7a800" }, { "ImportPath": "github.com/go-openapi/jsonpointer", - "Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98" + "Comment": "v0.17.2", + "Rev": "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004" }, { "ImportPath": "github.com/go-openapi/jsonreference", - "Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272" + "Comment": "v0.17.2", + "Rev": "8483a886a90412cd6858df4ea3483dce9c8e35a3" }, { "ImportPath": "github.com/go-openapi/loads", - "Rev": "a80dea3052f00e5f032e860dd7355cd0cc67e24d" + "Comment": "v0.17.2", + "Rev": "150d36912387ec2f607be674c5be309ddccc0eed" }, { "ImportPath": "github.com/go-openapi/runtime", - "Rev": "11e322eeecc1032d5a0a96c566ed53f2b5c26e22" + "Comment": "v0.17.2", + "Rev": "231d7876b7019dbcbfc97a7ba764379497b67c1d" }, { "ImportPath": "github.com/go-openapi/spec", - "Rev": "1de3e0542de65ad8d75452a595886fdd0befb363" + "Comment": "v0.17.1", + "Rev": "5bae59e25b21498baea7f9d46e9c147ec106a42e" }, { "ImportPath": "github.com/go-openapi/strfmt", - "Rev": "d65c7fdb29eca313476e529628176fe17e58c488" + "Comment": "v0.17.0", + "Rev": "35fe47352985e13cc75f13120d70d26fd764ed51" }, { "ImportPath": "github.com/go-openapi/swag", - "Rev": "f3f9494671f93fcff853e3c6e9e948b3eb71e590" + "Comment": "v0.17.2", + "Rev": "5899d5c5e619fda5fa86e14795a835f473ca284c" }, { "ImportPath": "github.com/go-openapi/validate", - "Rev": "d509235108fcf6ab4913d2dcb3a2260c0db2108e" + "Comment": "v0.17.1", + "Rev": "d2eab7d93009e9215fc85b2faa2c2f2a98c2af48" }, { "ImportPath": "github.com/go-sql-driver/mysql", @@ -2183,6 +2215,11 @@ "ImportPath": "github.com/gregjones/httpcache/diskcache", "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" }, + { + "ImportPath": "github.com/grpc-ecosystem/go-grpc-middleware", + "Comment": "v1.0.0-4-g498ae20", + "Rev": "498ae206fc3cfe81cd82e48c1d4354026fa5f9ec" + }, { "ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus", "Comment": "v1.1-4-g2500245", @@ -2269,7 +2306,6 @@ }, { "ImportPath": "github.com/inconshreveable/mousetrap", - "Comment": "v1.0", "Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" }, { @@ -2411,7 +2447,7 @@ }, { "ImportPath": "github.com/matttproud/golang_protobuf_extensions/pbutil", - "Comment": "v1.0.1", + "Comment": "v1.0.0-2-gc12348c", "Rev": "c12348ce28de40eed0136aa2b644d0ee0650e56c" }, { @@ -3268,6 +3304,46 @@ "Comment": "0.0.1", "Rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2" }, + { + "ImportPath": "go.uber.org/atomic", + "Comment": "v1.3.2-3-g8dc6146", + "Rev": "8dc6146f7569370a472715e178d8ae31172ee6da" + }, + { + "ImportPath": "go.uber.org/multierr", + "Comment": "v1.1.0-2-gddea229", + "Rev": "ddea229ff1dff9e6fe8a6c0344ac73b09e81fce5" + }, + { + "ImportPath": "go.uber.org/zap", + "Comment": "v1.9.1-1-g67bc79d", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/buffer", + "Comment": "v1.9.1-1-g67bc79d", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/bufferpool", + "Comment": "v1.9.1-1-g67bc79d", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/color", + "Comment": "v1.9.1-1-g67bc79d", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/exit", + "Comment": "v1.9.1-1-g67bc79d", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/zapcore", + "Comment": "v1.9.1-1-g67bc79d", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, { "ImportPath": "golang.org/x/crypto/bcrypt", "Rev": "de0752318171da717af4ce24d0a2e8626afaeb11" @@ -3342,51 +3418,51 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/context/ctxhttp", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/html", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/html/atom", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/internal/timeseries", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/proxy", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/trace", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/websocket", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -3816,6 +3892,7 @@ }, { "ImportPath": "gopkg.in/yaml.v2", + "Comment": "v2.2.1", "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183" }, { @@ -3865,55 +3942,55 @@ }, { "ImportPath": "k8s.io/kube-openapi/cmd/openapi-gen", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/cmd/openapi-gen/args", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/aggregator", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/generators", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/generators/rules", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto/testing", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto/validation", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/sets", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/utils/clock", diff --git a/Godeps/LICENSES b/Godeps/LICENSES index f7ef753bcbcd0..6325125279407 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -8137,7 +8137,7 @@ SOFTWARE. ================================================================================ -= vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute licensed under: = += vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute licensed under: = Apache License @@ -13566,6 +13566,216 @@ THE SOFTWARE. ================================================================================ +================================================================================ += vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools licensed under: = + + + 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. + += vendor/github.com/bazelbuild/bazel-gazelle/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 +================================================================================ + + ================================================================================ = vendor/github.com/bazelbuild/bazel-gazelle/internal/version licensed under: = @@ -45995,6 +46205,72 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ +================================================================================ += vendor/github.com/globalsign/mgo/bson licensed under: = + +mgo - MongoDB driver for Go + +Copyright (c) 2010-2013 - Gustavo Niemeyer + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + += vendor/github.com/globalsign/mgo/LICENSE 566e96676859b5704130b80941bc9f1f +================================================================================ + + +================================================================================ += vendor/github.com/globalsign/mgo/internal/json licensed under: = + +mgo - MongoDB driver for Go + +Copyright (c) 2010-2013 - Gustavo Niemeyer + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + += vendor/github.com/globalsign/mgo/LICENSE 566e96676859b5704130b80941bc9f1f +================================================================================ + + ================================================================================ = vendor/github.com/go-ini/ini licensed under: = @@ -46404,6 +46680,216 @@ third-party archives. ================================================================================ +================================================================================ += vendor/github.com/go-openapi/analysis/internal licensed under: = + + + 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. + += vendor/github.com/go-openapi/analysis/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 +================================================================================ + + ================================================================================ = vendor/github.com/go-openapi/errors licensed under: = @@ -54151,7 +54637,403 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/fs licensed under: = += vendor/github.com/google/cadvisor/fs licensed under: = + + Copyright 2014 The cAdvisor 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. + + 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 + += vendor/github.com/google/cadvisor/LICENSE e7790b946bfacb700e8a8f2baedb3205 +================================================================================ + + +================================================================================ += vendor/github.com/google/cadvisor/info/v1 licensed under: = + + Copyright 2014 The cAdvisor 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. + + 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 + += vendor/github.com/google/cadvisor/LICENSE e7790b946bfacb700e8a8f2baedb3205 +================================================================================ + + +================================================================================ += vendor/github.com/google/cadvisor/info/v2 licensed under: = Copyright 2014 The cAdvisor Authors @@ -54349,7 +55231,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/info/v1 licensed under: = += vendor/github.com/google/cadvisor/machine licensed under: = Copyright 2014 The cAdvisor Authors @@ -54547,7 +55429,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/info/v2 licensed under: = += vendor/github.com/google/cadvisor/manager licensed under: = Copyright 2014 The cAdvisor Authors @@ -54745,7 +55627,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/machine licensed under: = += vendor/github.com/google/cadvisor/manager/watcher licensed under: = Copyright 2014 The cAdvisor Authors @@ -54943,7 +55825,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/manager licensed under: = += vendor/github.com/google/cadvisor/manager/watcher/raw licensed under: = Copyright 2014 The cAdvisor Authors @@ -55141,7 +56023,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/manager/watcher licensed under: = += vendor/github.com/google/cadvisor/manager/watcher/rkt licensed under: = Copyright 2014 The cAdvisor Authors @@ -55339,7 +56221,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/manager/watcher/raw licensed under: = += vendor/github.com/google/cadvisor/metrics licensed under: = Copyright 2014 The cAdvisor Authors @@ -55537,7 +56419,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/manager/watcher/rkt licensed under: = += vendor/github.com/google/cadvisor/storage licensed under: = Copyright 2014 The cAdvisor Authors @@ -55735,7 +56617,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/metrics licensed under: = += vendor/github.com/google/cadvisor/summary licensed under: = Copyright 2014 The cAdvisor Authors @@ -55933,7 +56815,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/storage licensed under: = += vendor/github.com/google/cadvisor/utils licensed under: = Copyright 2014 The cAdvisor Authors @@ -56131,7 +57013,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/summary licensed under: = += vendor/github.com/google/cadvisor/utils/cloudinfo licensed under: = Copyright 2014 The cAdvisor Authors @@ -56329,7 +57211,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/utils licensed under: = += vendor/github.com/google/cadvisor/utils/cpuload licensed under: = Copyright 2014 The cAdvisor Authors @@ -56527,7 +57409,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/utils/cloudinfo licensed under: = += vendor/github.com/google/cadvisor/utils/cpuload/netlink licensed under: = Copyright 2014 The cAdvisor Authors @@ -56725,7 +57607,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/utils/cpuload licensed under: = += vendor/github.com/google/cadvisor/utils/docker licensed under: = Copyright 2014 The cAdvisor Authors @@ -56923,7 +57805,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/utils/cpuload/netlink licensed under: = += vendor/github.com/google/cadvisor/utils/oomparser licensed under: = Copyright 2014 The cAdvisor Authors @@ -57121,7 +58003,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/utils/docker licensed under: = += vendor/github.com/google/cadvisor/utils/sysfs licensed under: = Copyright 2014 The cAdvisor Authors @@ -57319,7 +58201,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/utils/oomparser licensed under: = += vendor/github.com/google/cadvisor/utils/sysinfo licensed under: = Copyright 2014 The cAdvisor Authors @@ -57517,7 +58399,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/utils/sysfs licensed under: = += vendor/github.com/google/cadvisor/version licensed under: = Copyright 2014 The cAdvisor Authors @@ -57715,7 +58597,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/utils/sysinfo licensed under: = += vendor/github.com/google/cadvisor/zfs licensed under: = Copyright 2014 The cAdvisor Authors @@ -57913,21 +58795,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/cadvisor/version licensed under: = - - Copyright 2014 The cAdvisor 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 += vendor/github.com/google/certificate-transparency-go licensed under: = - 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. Apache License Version 2.0, January 2004 @@ -58106,14 +58975,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. END OF TERMS AND CONDITIONS -= vendor/github.com/google/cadvisor/LICENSE e7790b946bfacb700e8a8f2baedb3205 -================================================================================ - + APPENDIX: How to apply the Apache License to your work. -================================================================================ -= vendor/github.com/google/cadvisor/zfs licensed under: = + 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 2014 The cAdvisor Authors + 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. @@ -58127,189 +59000,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. See the License for the specific language governing permissions and limitations under the License. - 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 - -= vendor/github.com/google/cadvisor/LICENSE e7790b946bfacb700e8a8f2baedb3205 += vendor/github.com/google/certificate-transparency-go/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 ================================================================================ ================================================================================ -= vendor/github.com/google/certificate-transparency-go licensed under: = += vendor/github.com/google/certificate-transparency-go/asn1 licensed under: = Apache License @@ -58519,7 +59215,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/certificate-transparency-go/asn1 licensed under: = += vendor/github.com/google/certificate-transparency-go/client licensed under: = Apache License @@ -58729,7 +59425,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/certificate-transparency-go/client licensed under: = += vendor/github.com/google/certificate-transparency-go/client/configpb licensed under: = Apache License @@ -58939,7 +59635,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/certificate-transparency-go/client/configpb licensed under: = += vendor/github.com/google/certificate-transparency-go/jsonclient licensed under: = Apache License @@ -59149,7 +59845,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/certificate-transparency-go/jsonclient licensed under: = += vendor/github.com/google/certificate-transparency-go/tls licensed under: = Apache License @@ -59359,7 +60055,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/certificate-transparency-go/tls licensed under: = += vendor/github.com/google/certificate-transparency-go/x509 licensed under: = Apache License @@ -59569,7 +60265,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/certificate-transparency-go/x509 licensed under: = += vendor/github.com/google/certificate-transparency-go/x509/pkix licensed under: = Apache License @@ -59779,7 +60475,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/google/certificate-transparency-go/x509/pkix licensed under: = += vendor/github.com/google/gofuzz licensed under: = Apache License @@ -59984,12 +60680,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. See the License for the specific language governing permissions and limitations under the License. -= vendor/github.com/google/certificate-transparency-go/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 += vendor/github.com/google/gofuzz/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 ================================================================================ ================================================================================ -= vendor/github.com/google/gofuzz licensed under: = += vendor/github.com/google/uuid licensed under: = + +Copyright (c) 2009,2014 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + += vendor/github.com/google/uuid/LICENSE 88073b6dd8ec00fe09da59e0b6dfded1 +================================================================================ + + +================================================================================ += vendor/github.com/googleapis/gnostic/compiler licensed under: = Apache License @@ -60194,47 +60925,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. See the License for the specific language governing permissions and limitations under the License. -= vendor/github.com/google/gofuzz/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 -================================================================================ - - -================================================================================ -= vendor/github.com/google/uuid licensed under: = - -Copyright (c) 2009,2014 Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -= vendor/github.com/google/uuid/LICENSE 88073b6dd8ec00fe09da59e0b6dfded1 += vendor/github.com/googleapis/gnostic/LICENSE b1e01b26bacfc2232046c90a330332b3 ================================================================================ ================================================================================ -= vendor/github.com/googleapis/gnostic/compiler licensed under: = += vendor/github.com/googleapis/gnostic/extensions licensed under: = Apache License @@ -60445,7 +61142,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/googleapis/gnostic/extensions licensed under: = += vendor/github.com/googleapis/gnostic/OpenAPIv2 licensed under: = Apache License @@ -60656,10 +61353,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -= vendor/github.com/googleapis/gnostic/OpenAPIv2 licensed under: = += vendor/github.com/gophercloud/gophercloud licensed under: = +Copyright 2012-2013 Rackspace, Inc. - Apache License +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. + +------ + + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -60836,38 +61547,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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. - - -= vendor/github.com/googleapis/gnostic/LICENSE b1e01b26bacfc2232046c90a330332b3 += vendor/github.com/gophercloud/gophercloud/LICENSE dd19699707373c2ca31531a659130416 ================================================================================ ================================================================================ -= vendor/github.com/gophercloud/gophercloud licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -61066,7 +61751,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -61265,7 +61950,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -61464,7 +62149,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -61663,7 +62348,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -61862,7 +62547,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/common/extensions licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -62061,7 +62746,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/common/extensions licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -62260,7 +62945,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -62459,7 +63144,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -62658,7 +63343,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -62857,7 +63542,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -63056,7 +63741,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -63255,7 +63940,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -63454,7 +64139,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -63653,7 +64338,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -63852,7 +64537,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -64051,7 +64736,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -64250,7 +64935,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -64449,7 +65134,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -64648,7 +65333,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -64847,7 +65532,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -65046,7 +65731,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -65245,7 +65930,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -65444,7 +66129,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -65643,7 +66328,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -65842,7 +66527,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -66041,7 +66726,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -66240,7 +66925,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports licensed under: = += vendor/github.com/gophercloud/gophercloud/openstack/utils licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -66439,7 +67124,7 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/openstack/utils licensed under: = += vendor/github.com/gophercloud/gophercloud/pagination licensed under: = Copyright 2012-2013 Rackspace, Inc. @@ -66638,24 +67323,67 @@ specific language governing permissions and limitations under the License. ================================================================================ -= vendor/github.com/gophercloud/gophercloud/pagination licensed under: = += vendor/github.com/gorilla/websocket licensed under: = -Copyright 2012-2013 Rackspace, Inc. +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. -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 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: - http://www.apache.org/licenses/LICENSE-2.0 + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. -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. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. ------- - - Apache License +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + += vendor/github.com/gorilla/websocket/LICENSE c007b54a1743d596f46b2748d9f8c044 +================================================================================ + + +================================================================================ += vendor/github.com/gregjones/httpcache licensed under: = + +Copyright © 2012 Greg Jones (greg.jones@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. += vendor/github.com/gregjones/httpcache/LICENSE.txt 3cfef421226b2dacde78a4871380ac24 +================================================================================ + + +================================================================================ += vendor/github.com/gregjones/httpcache/diskcache licensed under: = + +Copyright © 2012 Greg Jones (greg.jones@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. += vendor/github.com/gregjones/httpcache/LICENSE.txt 3cfef421226b2dacde78a4871380ac24 +================================================================================ + + +================================================================================ += vendor/github.com/grpc-ecosystem/go-grpc-middleware licensed under: = + + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -66832,65 +67560,31 @@ specific language governing permissions and limitations under the License. END OF TERMS AND CONDITIONS -= vendor/github.com/gophercloud/gophercloud/LICENSE dd19699707373c2ca31531a659130416 -================================================================================ - - -================================================================================ -= vendor/github.com/gorilla/websocket licensed under: = - -Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -= vendor/github.com/gorilla/websocket/LICENSE c007b54a1743d596f46b2748d9f8c044 -================================================================================ - - -================================================================================ -= vendor/github.com/gregjones/httpcache licensed under: = - -Copyright © 2012 Greg Jones (greg.jones@gmail.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -= vendor/github.com/gregjones/httpcache/LICENSE.txt 3cfef421226b2dacde78a4871380ac24 -================================================================================ - + APPENDIX: How to apply the Apache License to your work. -================================================================================ -= vendor/github.com/gregjones/httpcache/diskcache licensed under: = + 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 © 2012 Greg Jones (greg.jones@gmail.com) + Copyright [yyyy] [name of copyright owner] -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + 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 -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + http://www.apache.org/licenses/LICENSE-2.0 -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -= vendor/github.com/gregjones/httpcache/LICENSE.txt 3cfef421226b2dacde78a4871380ac24 + 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. += vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE 7ab5c73bb7e4679b16dd7c11b3559acf ================================================================================ @@ -97074,6 +97768,222 @@ SOFTWARE. ================================================================================ +================================================================================ += vendor/go.uber.org/atomic licensed under: = + +Copyright (c) 2016 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + += vendor/go.uber.org/atomic/LICENSE.txt 1caee86519456feda989f8a838102b50 +================================================================================ + + +================================================================================ += vendor/go.uber.org/multierr licensed under: = + +Copyright (c) 2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + += vendor/go.uber.org/multierr/LICENSE.txt f65b21a547112d1bc7b11b90f9b31997 +================================================================================ + + +================================================================================ += vendor/go.uber.org/zap licensed under: = + +Copyright (c) 2016-2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + += vendor/go.uber.org/zap/LICENSE.txt 5e8153e456a82529ea845e0d511abb69 +================================================================================ + + +================================================================================ += vendor/go.uber.org/zap/buffer licensed under: = + +Copyright (c) 2016-2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + += vendor/go.uber.org/zap/LICENSE.txt 5e8153e456a82529ea845e0d511abb69 +================================================================================ + + +================================================================================ += vendor/go.uber.org/zap/internal/bufferpool licensed under: = + +Copyright (c) 2016-2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + += vendor/go.uber.org/zap/LICENSE.txt 5e8153e456a82529ea845e0d511abb69 +================================================================================ + + +================================================================================ += vendor/go.uber.org/zap/internal/color licensed under: = + +Copyright (c) 2016-2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + += vendor/go.uber.org/zap/LICENSE.txt 5e8153e456a82529ea845e0d511abb69 +================================================================================ + + +================================================================================ += vendor/go.uber.org/zap/internal/exit licensed under: = + +Copyright (c) 2016-2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + += vendor/go.uber.org/zap/LICENSE.txt 5e8153e456a82529ea845e0d511abb69 +================================================================================ + + +================================================================================ += vendor/go.uber.org/zap/zapcore licensed under: = + +Copyright (c) 2016-2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + += vendor/go.uber.org/zap/LICENSE.txt 5e8153e456a82529ea845e0d511abb69 +================================================================================ + + ================================================================================ = vendor/golang.org/x/crypto/bcrypt licensed under: = diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 7e20f814cdffa..88959953bde86 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -1,4 +1,128 @@ aliases: + # sig-auth subproject aliases + sig-auth-audit-approvers: + - sttts + - tallclair + sig-auth-audit-reviewers: + - CaoShuFeng + - hzxuzhonghu + - lavalamp + - sttts + - tallclair + + sig-auth-authenticators-approvers: + - deads2k + - liggitt + - mikedanese + sig-auth-authenticators-reviewers: + - deads2k + - enj + - jianhuiz + - lavalamp + - liggitt + - mbohlool + - mikedanese + - sttts + - wojtek-t + + sig-auth-authorizers-approvers: + - deads2k + - liggitt + - mikedanese + sig-auth-authorizers-reviewers: + - david-mcmahon + - deads2k + - dims + - enj + - erictune + - jianhuiz + - krousey + - lavalamp + - liggitt + - mbohlool + - mikedanese + - mml + - ncdc + - nikhiljindal + - smarterclayton + - sttts + - thockin + - wojtek-t + + sig-auth-certificates-approvers: + - liggitt + - mikedanese + - smarterclayton + sig-auth-certificates-reviewers: + - awly + - caesarxuchao + - david-mcmahon + - deads2k + - dims + - enj + - errordeveloper + - hongchaodeng + - jianhuiz + - lavalamp + - liggitt + - mbohlool + - mikedanese + - smarterclayton + - sttts + - thockin + - timothysc + - wojtek-t + + sig-auth-encryption-at-rest-approvers: + - immutableT + - smarterclayton + sig-auth-encryption-at-rest-reviewers: + - enj + - immutableT + - lavalamp + - liggitt + - sakshamsharma + - smarterclayton + - wojtek-t + + sig-auth-node-isolation-approvers: + - deads2k + - liggitt + - mikedanese + - tallclair + sig-auth-node-isolation-reviewers: + - deads2k + - liggitt + - mikedanese + - tallclair + + sig-auth-policy-approvers: + - deads2k + - liggitt + - tallclair + sig-auth-policy-reviewers: + - deads2k + - hongchaodeng + - jianhuiz + - liggitt + - mbohlool + - pweil- + - tallclair + + sig-auth-serviceaccounts-approvers: + - deads2k + - liggitt + - mikedanese + sig-auth-serviceaccounts-reviewers: + - awly + - deads2k + - enj + - liggitt + - mikedanese + + sig-storage-reviewers: + - saad-ali + - childsb sig-scheduling-maintainers: - bsalamat - davidopp @@ -9,15 +133,11 @@ aliases: - ravisantoshgudimetla sig-scheduling: - bsalamat - - davidopp - - jayunit100 - k82cn - resouer - - timothysc - - wojtek-t - - aveshagarwal - ravisantoshgudimetla - misterikkit + - Huang-Wei sig-cli-maintainers: - adohe - brendandburns @@ -74,6 +194,7 @@ aliases: - vishh - yifan-gu - yujuhong + - krmayankk sig-network-approvers: - bowei - caseydavenport diff --git a/api/api-rules/README.md b/api/api-rules/README.md index 9c77208d298ae..026e5923ba9ae 100644 --- a/api/api-rules/README.md +++ b/api/api-rules/README.md @@ -1,9 +1,11 @@ -## Existing API Rule Violations +# Existing API Rule Violations This folder contains the checked-in report file of known API rule violations. The file violation\_exceptions.list is used by Make rule during OpenAPI spec generation to make sure that no new API rule violation is introduced into our code base. +## API Rule Violation Format + The report file [violation\_exceptions.list](./violation_exceptions.list) is in format of: * ***API rule violation: \,\,\,\*** @@ -12,11 +14,29 @@ e.g. * ***API rule violation: names_match,k8s.io/api/core/v1,Event,ReportingController*** +And the violation list is sorted alphabetically in each of the \, \, \, \ levels. + +## How to resolve API Rule Check Failure + Make rule returns an error when the newly generated violation report differs from this -checked-in violation report. If a new API rule violation is detected, please fix -the API Go source file to pass the API rule check. **The entries in the checked-in -violation report should only be removed when existing API rule violation is -being fixed, but not added.** +checked-in violation report. + +Our goal is that exceptions should never be added to this list, only fixed and removed. +For new APIs, this is a hard requirement. For APIs that are e.g. being moved between +versions or groups without other changes, it is OK for your API reviewer to make an +exception. + +If you're removing violations from the exception list, or if you have good +reasons to add new violations to this list, please update the file using: + + - `make generated_files UPDATE_API_KNOWN_VIOLATIONS=true` + +It is up to API reviewers to review the list and make sure new APIs follow our API conventions. + +**NOTE**: please don't hide changes to this file in a "generated changes" commit, treat it as +source code instead. + +## API Rules Being Enforced For more information about the API rules being checked, please refer to https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators/rules diff --git a/api/api-rules/violation_exceptions.list b/api/api-rules/violation_exceptions.list index 4bb9079c920ae..6e1f831554f50 100644 --- a/api/api-rules/violation_exceptions.list +++ b/api/api-rules/violation_exceptions.list @@ -24,89 +24,85 @@ API rule violation: names_match,k8s.io/api/core/v1,RBDVolumeSource,RBDPool API rule violation: names_match,k8s.io/api/core/v1,RBDVolumeSource,RadosUser API rule violation: names_match,k8s.io/api/core/v1,VolumeSource,CephFS API rule violation: names_match,k8s.io/api/core/v1,VolumeSource,StorageOS -API rule violation: names_match,k8s.io/api/extensions/v1beta1,CustomMetricCurrentStatus,CurrentValue -API rule violation: names_match,k8s.io/api/extensions/v1beta1,CustomMetricTarget,TargetValue API rule violation: names_match,k8s.io/api/policy/v1beta1,PodDisruptionBudgetStatus,PodDisruptionsAllowed API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceColumnDefinition,JSONPath API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSON,Raw -API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,Schema API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,Ref -API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrArray,Schema +API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,Schema API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrArray,JSONSchemas +API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrArray,Schema API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrBool,Allows API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrBool,Schema -API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrStringArray,Schema API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrStringArray,Property -API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,i +API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrStringArray,Schema +API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,Format API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,d +API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,i API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,s -API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,Format -API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,int64Amount,value API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,int64Amount,scale +API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,int64Amount,value API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,APIResourceList,APIResources API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,Duration,Duration -API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,InternalEvent,Type API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,InternalEvent,Object +API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,InternalEvent,Type API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,MicroTime,Time API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,StatusCause,Type API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,Time,Time API rule violation: names_match,k8s.io/apimachinery/pkg/runtime,RawExtension,Raw -API rule violation: names_match,k8s.io/apimachinery/pkg/runtime,Unknown,Raw API rule violation: names_match,k8s.io/apimachinery/pkg/runtime,Unknown,ContentEncoding API rule violation: names_match,k8s.io/apimachinery/pkg/runtime,Unknown,ContentType -API rule violation: names_match,k8s.io/apimachinery/pkg/util/intstr,IntOrString,Type +API rule violation: names_match,k8s.io/apimachinery/pkg/runtime,Unknown,Raw API rule violation: names_match,k8s.io/apimachinery/pkg/util/intstr,IntOrString,IntVal API rule violation: names_match,k8s.io/apimachinery/pkg/util/intstr,IntOrString,StrVal +API rule violation: names_match,k8s.io/apimachinery/pkg/util/intstr,IntOrString,Type API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,AttachDetachControllerConfiguration,DisableAttachDetachReconcilerSync API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,AttachDetachControllerConfiguration,ReconcilerSyncLoopPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,ClusterSigningCertFile -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,ClusterSigningKeyFile API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,ClusterSigningDuration -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CloudProviderConfiguration,Name +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,ClusterSigningKeyFile API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CloudProviderConfiguration,CloudConfigFile +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CloudProviderConfiguration,Name API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,DaemonSetControllerConfiguration,ConcurrentDaemonSetSyncs API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,DeploymentControllerConfiguration,ConcurrentDeploymentSyncs API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,DeploymentControllerConfiguration,DeploymentControllerSyncPeriod -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,DeprecatedControllerConfiguration,DeletingPodsQPS API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,DeprecatedControllerConfiguration,DeletingPodsBurst +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,DeprecatedControllerConfiguration,DeletingPodsQPS API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,DeprecatedControllerConfiguration,RegisterRetryCount API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,EndpointControllerConfiguration,ConcurrentEndpointSyncs -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GarbageCollectorControllerConfiguration,EnableGarbageCollector API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GarbageCollectorControllerConfiguration,ConcurrentGCSyncs +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GarbageCollectorControllerConfiguration,EnableGarbageCollector API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GarbageCollectorControllerConfiguration,GCIgnoredResources -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,Port API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,Address -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,MinResyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,ClientConnection API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,ControllerStartInterval -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,LeaderElection API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,Controllers API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,Debugging +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,LeaderElection +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,MinResyncPeriod +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,Port API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GroupResource,Group API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,GroupResource,Resource -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerSyncPeriod -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerUpscaleForbiddenWindow -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerDownscaleStabilizationWindow +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerCPUInitializationPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerDownscaleForbiddenWindow +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerDownscaleStabilizationWindow +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerInitialReadinessDelay +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerSyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerTolerance +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerUpscaleForbiddenWindow API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerUseRESTClients -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerCPUInitializationPeriod -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerInitialReadinessDelay API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,JobControllerConfiguration,ConcurrentJobSyncs -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,CloudProvider -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,ExternalCloudVolumePlugin -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,UseServiceAccountCredentials -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,AllowUntaggedCloud -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,RouteReconciliationPeriod -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,NodeMonitorPeriod -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,ClusterName -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,ClusterCIDR API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,AllocateNodeCIDRs +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,AllowUntaggedCloud API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,CIDRAllocatorType +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,CloudProvider +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,ClusterCIDR +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,ClusterName API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,ConfigureCloudRoutes +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,ExternalCloudVolumePlugin +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,NodeMonitorPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,NodeSyncPeriod -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,Generic -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,KubeCloudShared +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,RouteReconciliationPeriod +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeCloudSharedConfiguration,UseServiceAccountCredentials API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,AttachDetachController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,CSRSigningController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,DaemonSetController @@ -114,8 +110,10 @@ API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,K API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,DeprecatedController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,EndpointController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,GarbageCollectorController +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,Generic API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,HPAController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,JobController +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,KubeCloudShared API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,NamespaceController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,NodeIPAMController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,NodeLifecycleController @@ -127,48 +125,48 @@ API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,K API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,SAController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,ServiceController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,TTLAfterFinishedController -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NamespaceControllerConfiguration,NamespaceSyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NamespaceControllerConfiguration,ConcurrentNamespaceSyncs -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,ServiceCIDR +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NamespaceControllerConfiguration,NamespaceSyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,NodeCIDRMaskSize +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,ServiceCIDR API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,EnableTaintManager +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,LargeClusterSizeThreshold API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,NodeEvictionRate -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,SecondaryNodeEvictionRate -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,NodeStartupGracePeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,NodeMonitorGracePeriod +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,NodeStartupGracePeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,PodEvictionTimeout -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,LargeClusterSizeThreshold +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,SecondaryNodeEvictionRate API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,UnhealthyZoneThreshold API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeBinderControllerConfiguration,PVClaimBinderSyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeBinderControllerConfiguration,VolumeConfiguration +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,IncrementTimeoutHostPath +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,IncrementTimeoutNFS API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,MaximumRetry +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,MinimumTimeoutHostPath API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,MinimumTimeoutNFS -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,PodTemplateFilePathNFS -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,IncrementTimeoutNFS API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,PodTemplateFilePathHostPath -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,MinimumTimeoutHostPath -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,IncrementTimeoutHostPath +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PersistentVolumeRecyclerConfiguration,PodTemplateFilePathNFS API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,PodGCControllerConfiguration,TerminatedPodGCThreshold API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,ReplicaSetControllerConfiguration,ConcurrentRSSyncs API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,ReplicationControllerConfiguration,ConcurrentRCSyncs -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,ResourceQuotaControllerConfiguration,ResourceQuotaSyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,ResourceQuotaControllerConfiguration,ConcurrentResourceQuotaSyncs -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,SAControllerConfiguration,ServiceAccountKeyFile +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,ResourceQuotaControllerConfiguration,ResourceQuotaSyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,SAControllerConfiguration,ConcurrentSATokenSyncs API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,SAControllerConfiguration,RootCAFile +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,SAControllerConfiguration,ServiceAccountKeyFile API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,ServiceControllerConfiguration,ConcurrentServiceSyncs API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,TTLAfterFinishedControllerConfiguration,ConcurrentTTLSyncs -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,EnableHostPathProvisioning API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,EnableDynamicProvisioning -API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,PersistentVolumeRecyclerConfiguration +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,EnableHostPathProvisioning API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,FlexVolumePluginDir +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,PersistentVolumeRecyclerConfiguration API rule violation: names_match,k8s.io/kube-proxy/config/v1alpha1,KubeProxyConfiguration,IPTables -API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,ResolverConfig -API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,IPTablesMasqueradeBit API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,IPTablesDropBit +API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,IPTablesMasqueradeBit +API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,ResolverConfig API rule violation: names_match,k8s.io/kubernetes/cmd/cloud-controller-manager/app/apis/config/v1alpha1,CloudControllerManagerConfiguration,Generic API rule violation: names_match,k8s.io/kubernetes/cmd/cloud-controller-manager/app/apis/config/v1alpha1,CloudControllerManagerConfiguration,KubeCloudShared -API rule violation: names_match,k8s.io/kubernetes/cmd/cloud-controller-manager/app/apis/config/v1alpha1,CloudControllerManagerConfiguration,ServiceController API rule violation: names_match,k8s.io/kubernetes/cmd/cloud-controller-manager/app/apis/config/v1alpha1,CloudControllerManagerConfiguration,NodeStatusUpdateFrequency +API rule violation: names_match,k8s.io/kubernetes/cmd/cloud-controller-manager/app/apis/config/v1alpha1,CloudControllerManagerConfiguration,ServiceController API rule violation: names_match,k8s.io/metrics/pkg/apis/custom_metrics/v1beta1,MetricValue,WindowSeconds API rule violation: names_match,k8s.io/metrics/pkg/apis/external_metrics/v1beta1,ExternalMetricValue,WindowSeconds diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 503ed1be274ad..e7798e91c7bb9 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -2,7 +2,7 @@ "swagger": "2.0", "info": { "title": "Kubernetes", - "version": "v1.13.0" + "version": "v1.14.0" }, "paths": { "/api/": { @@ -1300,7 +1300,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -1833,7 +1832,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -2366,7 +2364,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -2899,7 +2896,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -3432,7 +3428,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -4139,7 +4134,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -6020,7 +6014,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -6553,7 +6546,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -7434,7 +7426,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -8141,7 +8132,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -8674,7 +8664,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -9121,7 +9110,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -10088,7 +10076,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -10848,7 +10835,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -12143,7 +12129,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -18333,7 +18318,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -19099,7 +19083,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -19616,7 +19599,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -20631,7 +20613,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -21596,7 +21577,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -22528,7 +22508,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -23813,7 +23792,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -24346,7 +24324,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -25053,7 +25030,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -25934,7 +25910,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -26815,7 +26790,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -29825,7 +29799,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -30358,7 +30331,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -31337,7 +31309,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -33675,7 +33646,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -34208,7 +34178,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -34915,7 +34884,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -35796,7 +35764,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -36677,7 +36644,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -39504,7 +39470,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -41449,7 +41414,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -42629,7 +42593,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -43809,7 +43772,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -45022,7 +44984,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -46202,7 +46163,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -47382,7 +47342,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -48483,7 +48442,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -49637,7 +49595,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -50676,7 +50633,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -51923,7 +51879,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -52630,7 +52585,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -53609,7 +53563,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -54316,7 +54269,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -54849,7 +54801,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -56000,7 +55951,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -58591,7 +58541,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -59630,7 +59579,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -60433,7 +60381,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -61552,7 +61499,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -62053,7 +61999,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -62562,7 +62507,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -63079,7 +63023,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -64933,7 +64876,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -65434,7 +65376,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -65943,7 +65884,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -66460,7 +66400,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -68314,7 +68253,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -68815,7 +68753,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -69324,7 +69261,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -69841,7 +69777,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -71744,7 +71679,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -72510,7 +72444,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -73317,7 +73250,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -74348,7 +74280,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -75114,7 +75045,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -75880,7 +75810,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -76397,7 +76326,6 @@ { "name": "body", "in": "body", - "required": true, "schema": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" } @@ -77381,7 +77309,7 @@ "$ref": "#/definitions/io.k8s.api.admissionregistration.v1beta1.ServiceReference" }, "url": { - "description": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", + "description": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", "type": "string" } } @@ -77796,6 +77724,7 @@ }, "strategy": { "description": "The deployment strategy to use to replace existing pods with new ones.", + "x-kubernetes-patch-strategy": "retainKeys", "$ref": "#/definitions/io.k8s.api.apps.v1.DeploymentStrategy" }, "template": { @@ -78516,6 +78445,7 @@ }, "strategy": { "description": "The deployment strategy to use to replace existing pods with new ones.", + "x-kubernetes-patch-strategy": "retainKeys", "$ref": "#/definitions/io.k8s.api.apps.v1beta1.DeploymentStrategy" }, "template": { @@ -79301,6 +79231,7 @@ }, "strategy": { "description": "The deployment strategy to use to replace existing pods with new ones.", + "x-kubernetes-patch-strategy": "retainKeys", "$ref": "#/definitions/io.k8s.api.apps.v1beta2.DeploymentStrategy" }, "template": { @@ -79985,7 +79916,7 @@ "$ref": "#/definitions/io.k8s.api.auditregistration.v1alpha1.ServiceReference" }, "url": { - "description": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", + "description": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", "type": "string" } } @@ -83370,6 +83301,11 @@ "items": { "$ref": "#/definitions/io.k8s.api.core.v1.ContainerPort" }, + "x-kubernetes-list-map-keys": [ + "containerPort", + "protocol" + ], + "x-kubernetes-list-type": "map", "x-kubernetes-patch-merge-key": "containerPort", "x-kubernetes-patch-strategy": "merge" }, @@ -91887,6 +91823,22 @@ } } }, + "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceConversion": { + "description": "CustomResourceConversion describes how to convert different versions of a CR.", + "required": [ + "strategy" + ], + "properties": { + "strategy": { + "description": "`strategy` specifies the conversion strategy. Allowed values are: - `None`: The converter only change the apiVersion and would not touch any other field in the CR. - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option.", + "type": "string" + }, + "webhookClientConfig": { + "description": "`webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`. This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.", + "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.WebhookClientConfig" + } + } + }, "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition": { "description": "CustomResourceDefinition represents a resource that should be exposed on the API server. Its name MUST be in the format \u003c.spec.name\u003e.\u003c.spec.group\u003e.", "required": [ @@ -92031,12 +91983,16 @@ ], "properties": { "additionalPrinterColumns": { - "description": "AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column.", + "description": "AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column. Optional, the global columns for all versions. Top-level and per-version columns are mutually exclusive.", "type": "array", "items": { "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition" } }, + "conversion": { + "description": "`conversion` defines conversion settings for the CRD.", + "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceConversion" + }, "group": { "description": "Group is the group this resource belongs in", "type": "string" @@ -92050,11 +92006,11 @@ "type": "string" }, "subresources": { - "description": "Subresources describes the subresources for CustomResources", + "description": "Subresources describes the subresources for CustomResource Optional, the global subresources for all versions. Top-level and per-version subresources are mutually exclusive.", "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceSubresources" }, "validation": { - "description": "Validation describes the validation methods for CustomResources", + "description": "Validation describes the validation methods for CustomResources Optional, the global validation schema for all versions. Top-level and per-version schemas are mutually exclusive.", "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceValidation" }, "version": { @@ -92099,16 +92055,28 @@ } }, "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionVersion": { + "description": "CustomResourceDefinitionVersion describes a version for CRD.", "required": [ "name", "served", "storage" ], "properties": { + "additionalPrinterColumns": { + "description": "AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column. Top-level and per-version columns are mutually exclusive. Per-version columns must not all be set to identical values (top-level columns should be used instead) This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. NOTE: CRDs created prior to 1.13 populated the top-level additionalPrinterColumns field by default. To apply an update that changes to per-version additionalPrinterColumns, the top-level additionalPrinterColumns field must be explicitly set to null", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition" + } + }, "name": { "description": "Name is the version name, e.g. “v1”, “v2beta1”, etc.", "type": "string" }, + "schema": { + "description": "Schema describes the schema for CustomResource used in validation, pruning, and defaulting. Top-level and per-version schemas are mutually exclusive. Per-version schemas must not all be set to identical values (top-level validation schema should be used instead) This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.", + "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceValidation" + }, "served": { "description": "Served is a flag enabling/disabling this version from being served via REST APIs", "type": "boolean" @@ -92116,6 +92084,10 @@ "storage": { "description": "Storage flags the version as storage version. There must be exactly one flagged as storage version.", "type": "boolean" + }, + "subresources": { + "description": "Subresources describes the subresources for CustomResource Top-level and per-version subresources are mutually exclusive. Per-version subresources must not all be set to identical values (top-level subresources should be used instead) This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.", + "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceSubresources" } } }, @@ -92337,6 +92309,45 @@ "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrStringArray": { "description": "JSONSchemaPropsOrStringArray represents a JSONSchemaProps or a string array." }, + "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.ServiceReference": { + "description": "ServiceReference holds a reference to Service.legacy.k8s.io", + "required": [ + "namespace", + "name" + ], + "properties": { + "name": { + "description": "`name` is the name of the service. Required", + "type": "string" + }, + "namespace": { + "description": "`namespace` is the namespace of the service. Required", + "type": "string" + }, + "path": { + "description": "`path` is an optional URL path which will be sent in any request to this service.", + "type": "string" + } + } + }, + "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.WebhookClientConfig": { + "description": "WebhookClientConfig contains the information to make a TLS connection with the webhook. It has the same field as admissionregistration.v1beta1.WebhookClientConfig.", + "properties": { + "caBundle": { + "description": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.", + "type": "string", + "format": "byte" + }, + "service": { + "description": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.\n\nPort 443 will be used if it is open, otherwise it is an error.", + "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.ServiceReference" + }, + "url": { + "description": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", + "type": "string" + } + } + }, "io.k8s.apimachinery.pkg.api.resource.Quantity": { "description": "Quantity is a fixed-point representation of a number. It provides convenient marshaling/unmarshaling in JSON and YAML, in addition to String() and Int64() accessors.\n\nThe serialization format is:\n\n\u003cquantity\u003e ::= \u003csignedNumber\u003e\u003csuffix\u003e\n (Note that \u003csuffix\u003e may be empty, from the \"\" case in \u003cdecimalSI\u003e.)\n\u003cdigit\u003e ::= 0 | 1 | ... | 9 \u003cdigits\u003e ::= \u003cdigit\u003e | \u003cdigit\u003e\u003cdigits\u003e \u003cnumber\u003e ::= \u003cdigits\u003e | \u003cdigits\u003e.\u003cdigits\u003e | \u003cdigits\u003e. | .\u003cdigits\u003e \u003csign\u003e ::= \"+\" | \"-\" \u003csignedNumber\u003e ::= \u003cnumber\u003e | \u003csign\u003e\u003cnumber\u003e \u003csuffix\u003e ::= \u003cbinarySI\u003e | \u003cdecimalExponent\u003e | \u003cdecimalSI\u003e \u003cbinarySI\u003e ::= Ki | Mi | Gi | Ti | Pi | Ei\n (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)\n\u003cdecimalSI\u003e ::= m | \"\" | k | M | G | T | P | E\n (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)\n\u003cdecimalExponent\u003e ::= \"e\" \u003csignedNumber\u003e | \"E\" \u003csignedNumber\u003e\n\nNo matter which of the three exponent forms is used, no quantity may represent a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal places. Numbers larger or more precise will be capped or rounded up. (E.g.: 0.1m will rounded up to 1m.) This may be extended in the future if we require larger or smaller quantities.\n\nWhen a Quantity is parsed from a string, it will remember the type of suffix it had, and will use the same type again when it is serialized.\n\nBefore serializing, Quantity will be put in \"canonical form\". This means that Exponent/suffix will be adjusted up or down (with a corresponding increase or decrease in Mantissa) such that:\n a. No precision is lost\n b. No fractional digits will be emitted\n c. The exponent (or suffix) is as large as possible.\nThe sign will be omitted unless the number is negative.\n\nExamples:\n 1.5 will be serialized as \"1500m\"\n 1.5Gi will be serialized as \"1536Mi\"\n\nNote that the quantity will NEVER be internally represented by a floating point number. That is the whole point of this exercise.\n\nNon-canonical values will still parse as long as they are well formed, but will be re-emitted in their canonical form. (So always use canonical form, or don't diff.)\n\nThis format is intended to make it difficult to use these numbers without writing some sort of special handling code in the hopes that that will cause implementors to also use a fixed point implementation.", "type": "string" @@ -92975,7 +92986,7 @@ } }, "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": { - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json b/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json index 86725ba13262b..cea6a7054af09 100644 --- a/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json +++ b/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -923,7 +923,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/admissionregistration.k8s.io_v1beta1.json b/api/swagger-spec/admissionregistration.k8s.io_v1beta1.json index 80d0aa79c55c2..ee8deb2f6f468 100644 --- a/api/swagger-spec/admissionregistration.k8s.io_v1beta1.json +++ b/api/swagger-spec/admissionregistration.k8s.io_v1beta1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1308,7 +1308,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1662,7 +1662,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", @@ -1863,7 +1863,7 @@ "properties": { "url": { "type": "string", - "description": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either." + "description": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either." }, "service": { "$ref": "v1beta1.ServiceReference", diff --git a/api/swagger-spec/apps_v1.json b/api/swagger-spec/apps_v1.json index 9559b6c83efc5..e1f00418afac9 100644 --- a/api/swagger-spec/apps_v1.json +++ b/api/swagger-spec/apps_v1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1642,7 +1642,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -2845,7 +2845,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -4234,7 +4234,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -5623,7 +5623,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -6576,7 +6576,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/apps_v1beta1.json b/api/swagger-spec/apps_v1beta1.json index 806eb3495c350..78bc79c312ec9 100644 --- a/api/swagger-spec/apps_v1beta1.json +++ b/api/swagger-spec/apps_v1beta1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1642,7 +1642,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3118,7 +3118,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -4071,7 +4071,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/apps_v1beta2.json b/api/swagger-spec/apps_v1beta2.json index 5e1cbb1c4b879..c120736f4334d 100644 --- a/api/swagger-spec/apps_v1beta2.json +++ b/api/swagger-spec/apps_v1beta2.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1642,7 +1642,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -2845,7 +2845,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -4234,7 +4234,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -5623,7 +5623,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -6576,7 +6576,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/auditregistration.k8s.io_v1alpha1.json b/api/swagger-spec/auditregistration.k8s.io_v1alpha1.json index 44634e054215f..0dca8cb513867 100644 --- a/api/swagger-spec/auditregistration.k8s.io_v1alpha1.json +++ b/api/swagger-spec/auditregistration.k8s.io_v1alpha1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -918,7 +918,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", @@ -1158,7 +1158,7 @@ "properties": { "url": { "type": "string", - "description": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either." + "description": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either." }, "service": { "$ref": "v1alpha1.ServiceReference", diff --git a/api/swagger-spec/authentication.k8s.io_v1.json b/api/swagger-spec/authentication.k8s.io_v1.json index b5aefe5391ad2..74e689e0cdcca 100644 --- a/api/swagger-spec/authentication.k8s.io_v1.json +++ b/api/swagger-spec/authentication.k8s.io_v1.json @@ -212,7 +212,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/authentication.k8s.io_v1beta1.json b/api/swagger-spec/authentication.k8s.io_v1beta1.json index 09eb2f9242aaf..ab5cf7822dc6a 100644 --- a/api/swagger-spec/authentication.k8s.io_v1beta1.json +++ b/api/swagger-spec/authentication.k8s.io_v1beta1.json @@ -212,7 +212,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/authorization.k8s.io_v1.json b/api/swagger-spec/authorization.k8s.io_v1.json index fda6029a1ecfc..2762233b59c7a 100644 --- a/api/swagger-spec/authorization.k8s.io_v1.json +++ b/api/swagger-spec/authorization.k8s.io_v1.json @@ -433,7 +433,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/authorization.k8s.io_v1beta1.json b/api/swagger-spec/authorization.k8s.io_v1beta1.json index 13c79f300be90..55ac86b634aba 100644 --- a/api/swagger-spec/authorization.k8s.io_v1beta1.json +++ b/api/swagger-spec/authorization.k8s.io_v1beta1.json @@ -433,7 +433,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/autoscaling_v1.json b/api/swagger-spec/autoscaling_v1.json index 97fc0921f1868..d8d78c70c3863 100644 --- a/api/swagger-spec/autoscaling_v1.json +++ b/api/swagger-spec/autoscaling_v1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1388,7 +1388,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/autoscaling_v2beta1.json b/api/swagger-spec/autoscaling_v2beta1.json index 8801184f411ce..e0e93de4f13cb 100644 --- a/api/swagger-spec/autoscaling_v2beta1.json +++ b/api/swagger-spec/autoscaling_v2beta1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1388,7 +1388,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/autoscaling_v2beta2.json b/api/swagger-spec/autoscaling_v2beta2.json index 173545e98f9f0..4d56d0275116f 100644 --- a/api/swagger-spec/autoscaling_v2beta2.json +++ b/api/swagger-spec/autoscaling_v2beta2.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1388,7 +1388,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/batch_v1.json b/api/swagger-spec/batch_v1.json index 6d1e25646d695..d42ab3d3d818b 100644 --- a/api/swagger-spec/batch_v1.json +++ b/api/swagger-spec/batch_v1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1388,7 +1388,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/batch_v1beta1.json b/api/swagger-spec/batch_v1beta1.json index 337f14b1c0302..dcf1a670d31d4 100644 --- a/api/swagger-spec/batch_v1beta1.json +++ b/api/swagger-spec/batch_v1beta1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1388,7 +1388,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/batch_v2alpha1.json b/api/swagger-spec/batch_v2alpha1.json index 908fccb7bf13c..ec644ae949573 100644 --- a/api/swagger-spec/batch_v2alpha1.json +++ b/api/swagger-spec/batch_v2alpha1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1388,7 +1388,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/certificates.k8s.io_v1beta1.json b/api/swagger-spec/certificates.k8s.io_v1beta1.json index 82d66e9a95a92..8eb149b3960eb 100644 --- a/api/swagger-spec/certificates.k8s.io_v1beta1.json +++ b/api/swagger-spec/certificates.k8s.io_v1beta1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1148,7 +1148,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/coordination.k8s.io_v1beta1.json b/api/swagger-spec/coordination.k8s.io_v1beta1.json index 64e64e51bc7bc..7a295215a5372 100644 --- a/api/swagger-spec/coordination.k8s.io_v1beta1.json +++ b/api/swagger-spec/coordination.k8s.io_v1beta1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1198,7 +1198,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/events.k8s.io_v1beta1.json b/api/swagger-spec/events.k8s.io_v1beta1.json index 227738e9a0cd3..ffa3f94062002 100644 --- a/api/swagger-spec/events.k8s.io_v1beta1.json +++ b/api/swagger-spec/events.k8s.io_v1beta1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1255,7 +1255,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json index e8141bbb0cb00..00e23d5fb129c 100644 --- a/api/swagger-spec/extensions_v1beta1.json +++ b/api/swagger-spec/extensions_v1beta1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1828,7 +1828,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3304,7 +3304,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -4507,7 +4507,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -5468,7 +5468,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -6263,7 +6263,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -7398,7 +7398,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/networking.k8s.io_v1.json b/api/swagger-spec/networking.k8s.io_v1.json index 83829d743e204..ef1be89e24c4e 100644 --- a/api/swagger-spec/networking.k8s.io_v1.json +++ b/api/swagger-spec/networking.k8s.io_v1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1198,7 +1198,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/policy_v1beta1.json b/api/swagger-spec/policy_v1beta1.json index 54a04eab1beb6..ff5260f2e2abf 100644 --- a/api/swagger-spec/policy_v1beta1.json +++ b/api/swagger-spec/policy_v1beta1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1772,7 +1772,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -2124,7 +2124,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/rbac.authorization.k8s.io_v1.json b/api/swagger-spec/rbac.authorization.k8s.io_v1.json index b897d9261c977..c06d5b8604e7c 100644 --- a/api/swagger-spec/rbac.authorization.k8s.io_v1.json +++ b/api/swagger-spec/rbac.authorization.k8s.io_v1.json @@ -553,7 +553,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1276,7 +1276,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -2055,7 +2055,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3056,7 +3056,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3639,7 +3639,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json b/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json index f131ca8be6b88..fc589c4b6cc69 100644 --- a/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json +++ b/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json @@ -553,7 +553,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1276,7 +1276,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -2055,7 +2055,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3056,7 +3056,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3639,7 +3639,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json b/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json index 964e26509f192..12a1b11a8a20b 100644 --- a/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json +++ b/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json @@ -553,7 +553,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1276,7 +1276,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -2055,7 +2055,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3056,7 +3056,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3639,7 +3639,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/scheduling.k8s.io_v1alpha1.json b/api/swagger-spec/scheduling.k8s.io_v1alpha1.json index b12808a1e381a..a5d2646bc3181 100644 --- a/api/swagger-spec/scheduling.k8s.io_v1alpha1.json +++ b/api/swagger-spec/scheduling.k8s.io_v1alpha1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -932,7 +932,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/scheduling.k8s.io_v1beta1.json b/api/swagger-spec/scheduling.k8s.io_v1beta1.json index 7875abb587223..8703cda70b30a 100644 --- a/api/swagger-spec/scheduling.k8s.io_v1beta1.json +++ b/api/swagger-spec/scheduling.k8s.io_v1beta1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -932,7 +932,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/settings.k8s.io_v1alpha1.json b/api/swagger-spec/settings.k8s.io_v1alpha1.json index 7542a7771966c..c8d6b2f72b391 100644 --- a/api/swagger-spec/settings.k8s.io_v1alpha1.json +++ b/api/swagger-spec/settings.k8s.io_v1alpha1.json @@ -625,7 +625,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1196,7 +1196,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/storage.k8s.io_v1.json b/api/swagger-spec/storage.k8s.io_v1.json index a7e55e8775054..265b173984f7b 100644 --- a/api/swagger-spec/storage.k8s.io_v1.json +++ b/api/swagger-spec/storage.k8s.io_v1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -953,7 +953,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/storage.k8s.io_v1alpha1.json b/api/swagger-spec/storage.k8s.io_v1alpha1.json index ddc382033bf5b..7c426ef148e23 100644 --- a/api/swagger-spec/storage.k8s.io_v1alpha1.json +++ b/api/swagger-spec/storage.k8s.io_v1alpha1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -927,7 +927,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/storage.k8s.io_v1beta1.json b/api/swagger-spec/storage.k8s.io_v1beta1.json index a713834c104c3..aad4df3ded6c9 100644 --- a/api/swagger-spec/storage.k8s.io_v1beta1.json +++ b/api/swagger-spec/storage.k8s.io_v1beta1.json @@ -569,7 +569,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1308,7 +1308,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1692,7 +1692,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/api/swagger-spec/v1.json b/api/swagger-spec/v1.json index 78b272848d632..d0aa3e77b22bc 100644 --- a/api/swagger-spec/v1.json +++ b/api/swagger-spec/v1.json @@ -852,7 +852,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -1869,7 +1869,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -2886,7 +2886,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -3903,7 +3903,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -4769,7 +4769,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -5736,7 +5736,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -7181,7 +7181,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -8328,7 +8328,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -9285,7 +9285,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -11762,7 +11762,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -12779,7 +12779,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -14168,7 +14168,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -15371,7 +15371,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -16388,7 +16388,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -17302,7 +17302,7 @@ "paramType": "body", "name": "body", "description": "", - "required": true, + "required": false, "allowMultiple": false }, { @@ -18618,7 +18618,7 @@ }, "v1.OwnerReference": { "id": "v1.OwnerReference", - "description": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "required": [ "apiVersion", "kind", diff --git a/build/BUILD b/build/BUILD index b6bc8c2de2f1d..8c5b6164b6a72 100644 --- a/build/BUILD +++ b/build/BUILD @@ -21,32 +21,23 @@ filegroup( tags = ["automanaged"], ) -# ensure /etc/nsswitch.conf exists so go's resolver respects /etc/hosts -container_image( - name = "busybox-with-nsswitch", - base = "@official_busybox//image", - directory = "/etc", - files = ["nsswitch.conf"], - mode = "0644", -) - # This list should roughly match kube::build::get_docker_wrapped_binaries() # in build/common.sh. DOCKERIZED_BINARIES = { "cloud-controller-manager": { - "base": ":busybox-with-nsswitch", + "base": "@debian-base-amd64//image", "target": "//cmd/cloud-controller-manager:cloud-controller-manager", }, "kube-apiserver": { - "base": ":busybox-with-nsswitch", + "base": "@debian-base-amd64//image", "target": "//cmd/kube-apiserver:kube-apiserver", }, "kube-controller-manager": { - "base": ":busybox-with-nsswitch", + "base": "@debian-base-amd64//image", "target": "//cmd/kube-controller-manager:kube-controller-manager", }, "kube-scheduler": { - "base": ":busybox-with-nsswitch", + "base": "@debian-base-amd64//image", "target": "//cmd/kube-scheduler:kube-scheduler", }, "kube-proxy": { diff --git a/build/build-image/cross/Dockerfile b/build/build-image/cross/Dockerfile index c9d058d26028c..8e4bc0f884392 100644 --- a/build/build-image/cross/Dockerfile +++ b/build/build-image/cross/Dockerfile @@ -15,7 +15,7 @@ # This file creates a standard build environment for building cross # platform go binary for the architecture kubernetes cares about. -FROM golang:1.11.1 +FROM golang:1.11.2 ENV GOARM 7 ENV KUBE_DYNAMIC_CROSSPLATFORMS \ diff --git a/build/build-image/cross/VERSION b/build/build-image/cross/VERSION index 7cd7543d29979..19abf8ebbbf01 100644 --- a/build/build-image/cross/VERSION +++ b/build/build-image/cross/VERSION @@ -1 +1 @@ -v1.11.1-2 +v1.11.2-1 diff --git a/build/common.sh b/build/common.sh index 28d0f2a683e40..b3b7748a6abbb 100755 --- a/build/common.sh +++ b/build/common.sh @@ -88,51 +88,18 @@ readonly KUBE_CONTAINER_RSYNC_PORT=8730 # # $1 - server architecture kube::build::get_docker_wrapped_binaries() { - debian_iptables_version=v10.2 + local arch=$1 + local debian_base_version=0.4.0 + local debian_iptables_version=v11.0 ### If you change any of these lists, please also update DOCKERIZED_BINARIES ### in build/BUILD. And kube::golang::server_image_targets - case $1 in - "amd64") - local targets=( - cloud-controller-manager,busybox - kube-apiserver,busybox - kube-controller-manager,busybox - kube-scheduler,busybox - kube-proxy,k8s.gcr.io/debian-iptables-amd64:${debian_iptables_version} - );; - "arm") - local targets=( - cloud-controller-manager,arm32v7/busybox - kube-apiserver,arm32v7/busybox - kube-controller-manager,arm32v7/busybox - kube-scheduler,arm32v7/busybox - kube-proxy,k8s.gcr.io/debian-iptables-arm:${debian_iptables_version} - );; - "arm64") - local targets=( - cloud-controller-manager,arm64v8/busybox - kube-apiserver,arm64v8/busybox - kube-controller-manager,arm64v8/busybox - kube-scheduler,arm64v8/busybox - kube-proxy,k8s.gcr.io/debian-iptables-arm64:${debian_iptables_version} - );; - "ppc64le") - local targets=( - cloud-controller-manager,ppc64le/busybox - kube-apiserver,ppc64le/busybox - kube-controller-manager,ppc64le/busybox - kube-scheduler,ppc64le/busybox - kube-proxy,k8s.gcr.io/debian-iptables-ppc64le:${debian_iptables_version} - );; - "s390x") - local targets=( - cloud-controller-manager,s390x/busybox - kube-apiserver,s390x/busybox - kube-controller-manager,s390x/busybox - kube-scheduler,s390x/busybox - kube-proxy,k8s.gcr.io/debian-iptables-s390x:${debian_iptables_version} - );; - esac + local targets=( + cloud-controller-manager,"k8s.gcr.io/debian-base-${arch}:${debian_base_version}" + kube-apiserver,"k8s.gcr.io/debian-base-${arch}:${debian_base_version}" + kube-controller-manager,"k8s.gcr.io/debian-base-${arch}:${debian_base_version}" + kube-scheduler,"k8s.gcr.io/debian-base-${arch}:${debian_base_version}" + kube-proxy,"k8s.gcr.io/debian-iptables-${arch}:${debian_iptables_version}" + ) echo "${targets[@]}" } diff --git a/build/debian-base/Makefile b/build/debian-base/Makefile index e472e95b24f1a..47569c7586231 100755 --- a/build/debian-base/Makefile +++ b/build/debian-base/Makefile @@ -65,7 +65,7 @@ all-push: all-push-images push-manifest push-manifest: docker manifest create --amend $(IMAGE):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(IMAGE)\-&:$(TAG)~g") @for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${IMAGE}:${TAG} ${IMAGE}-$${arch}:${TAG}; done - docker manifest push ${IMAGE}:${TAG} + docker manifest push --purge ${IMAGE}:${TAG} build: clean cp ./* $(TEMP_DIR) diff --git a/build/debian-hyperkube-base/Makefile b/build/debian-hyperkube-base/Makefile index f402fe04a9021..9a74426def737 100644 --- a/build/debian-hyperkube-base/Makefile +++ b/build/debian-hyperkube-base/Makefile @@ -52,7 +52,7 @@ all-push: all-push-images push-manifest push-manifest: docker manifest create --amend $(IMAGE):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(IMAGE)\-&:$(TAG)~g") @for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${IMAGE}:${TAG} ${IMAGE}-$${arch}:${TAG}; done - docker manifest push ${IMAGE}:${TAG} + docker manifest push --purge ${IMAGE}:${TAG} cni-tars/$(CNI_TARBALL): mkdir -p cni-tars/ diff --git a/build/debian-iptables/Makefile b/build/debian-iptables/Makefile index 0d90adfcbb637..bef45123dfb0a 100644 --- a/build/debian-iptables/Makefile +++ b/build/debian-iptables/Makefile @@ -55,6 +55,6 @@ all-push: all-push-images push-manifest push-manifest: docker manifest create --amend $(IMAGE):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(IMAGE)\-&:$(TAG)~g") @for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${IMAGE}:${TAG} ${IMAGE}-$${arch}:${TAG}; done - docker manifest push ${IMAGE}:${TAG} + docker manifest push --purge ${IMAGE}:${TAG} all: all-push diff --git a/build/debs/50-kubeadm.conf b/build/debs/50-kubeadm.conf new file mode 100644 index 0000000000000..a5d977316dd42 --- /dev/null +++ b/build/debs/50-kubeadm.conf @@ -0,0 +1,2 @@ +# The file is provided as part of the kubeadm package +net.ipv4.ip_forward = 1 diff --git a/build/debs/BUILD b/build/debs/BUILD index b89dbe1b303a4..4237e92739d3f 100644 --- a/build/debs/BUILD +++ b/build/debs/BUILD @@ -78,6 +78,16 @@ deb_data( "mode": "644", "dir": "/etc/systemd/system/kubelet.service.d", }, + { + "files": ["kubeadm.conf"], + "mode": "644", + "dir": "/usr/lib/modules-load.d", + }, + { + "files": ["50-kubeadm.conf"], + "mode": "644", + "dir": "/etc/sysctl.d", + }, ], ) diff --git a/build/debs/kubeadm.conf b/build/debs/kubeadm.conf new file mode 100644 index 0000000000000..4b3e02da8cceb --- /dev/null +++ b/build/debs/kubeadm.conf @@ -0,0 +1,2 @@ +# Load br_netfilter module at boot +br_netfilter diff --git a/build/root/Makefile.generated_files b/build/root/Makefile.generated_files index 2dd26921df9b0..54f8d918de07c 100644 --- a/build/root/Makefile.generated_files +++ b/build/root/Makefile.generated_files @@ -405,7 +405,15 @@ OPENAPI_OUTPUT_PKG := pkg/generated/openapi BOILERPLATE_FILENAME := vendor/k8s.io/code-generator/hack/boilerplate.go.txt REPORT_FILENAME := $(OUT_DIR)/violations.report KNOWN_VIOLATION_FILENAME := api/api-rules/violation_exceptions.list -API_RULE_CHECK_FAILURE_MESSAGE := "Error: API rules check failed. Reported violations \"$(REPORT_FILENAME)\" differ from known violations \"$(KNOWN_VIOLATION_FILENAME)\". Please fix API source file if new violation is detected, or update known violations \"$(KNOWN_VIOLATION_FILENAME)\" if existing violation is being fixed. Please refer to api/api-rules/README.md and https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators/rules for more information about the API rules being enforced." +# When UPDATE_API_KNOWN_VIOLATIONS is set to be true, let the generator to write +# updated API violations to the known API violation exceptions list. +ifeq ($(UPDATE_API_KNOWN_VIOLATIONS),true) + REPORT_FILENAME:=$(KNOWN_VIOLATION_FILENAME) + # When UPDATE_API_KNOWN_VIOLATIONS is set to be true, touch the exceptions + # list so that the OPENAPI_OUTFILE target re-run instead of being cached. + $(shell touch $(KNOWN_VIOLATION_FILENAME)) +endif +API_RULE_CHECK_FAILURE_MESSAGE := "ERROR: \n\t API rule check failed. Reported violations differ from known violations. Please read api/api-rules/README.md to resolve the failure. \n" # The tool used to generate open apis. OPENAPI_GEN := $(BIN_DIR)/openapi-gen @@ -452,7 +460,7 @@ $(OPENAPI_OUTFILE): $(OPENAPI_GEN) $(KNOWN_VIOLATION_FILENAME) -r $(REPORT_FILENAME) \ "$$@"; \ diff $(REPORT_FILENAME) $(KNOWN_VIOLATION_FILENAME) || \ - (echo $(API_RULE_CHECK_FAILURE_MESSAGE); exit 1) + (echo -e $(API_RULE_CHECK_FAILURE_MESSAGE); exit 1) # How to build the generator tool. The deps for this are defined in diff --git a/build/root/WORKSPACE b/build/root/WORKSPACE index 43357c33a011a..cee89622008eb 100644 --- a/build/root/WORKSPACE +++ b/build/root/WORKSPACE @@ -1,17 +1,18 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file") load("//build:workspace_mirror.bzl", "mirror") load("//build:workspace.bzl", "CRI_TOOLS_VERSION") http_archive( name = "io_bazel_rules_go", - sha256 = "7519e9e1c716ae3c05bd2d984a42c3b02e690c5df728dc0a84b23f90c355c5a1", - urls = mirror("https://github.com/bazelbuild/rules_go/releases/download/0.15.4/rules_go-0.15.4.tar.gz"), + sha256 = "f87fa87475ea107b3c69196f39c82b7bbf58fe27c62a338684c20ca17d1d8613", + urls = mirror("https://github.com/bazelbuild/rules_go/releases/download/0.16.2/rules_go-0.16.2.tar.gz"), ) http_archive( name = "io_kubernetes_build", - sha256 = "66a44fd5f6357268340d66fbd8a502065445a7c022732fe5f6fd84d9a20f75a3", - strip_prefix = "repo-infra-e8f2f7c3decf03e1fde9f30d249e39b8328aa8b0", - urls = mirror("https://github.com/kubernetes/repo-infra/archive/e8f2f7c3decf03e1fde9f30d249e39b8328aa8b0.tar.gz"), + sha256 = "21160531ea8a9a4001610223ad815622bf60671d308988c7057168a495a7e2e8", + strip_prefix = "repo-infra-b4bc4f1552c7fc1d4654753ca9b0e5e13883429f", + urls = mirror("https://github.com/kubernetes/repo-infra/archive/b4bc4f1552c7fc1d4654753ca9b0e5e13883429f.tar.gz"), ) http_archive( @@ -23,9 +24,9 @@ http_archive( ETCD_VERSION = "3.2.24" -new_http_archive( +http_archive( name = "com_coreos_etcd", - build_file = "third_party/etcd.BUILD", + build_file = "@//third_party:etcd.BUILD", sha256 = "947849dbcfa13927c81236fb76a7c01d587bbab42ab1e807184cd91b026ebed7", strip_prefix = "etcd-v%s-linux-amd64" % ETCD_VERSION, urls = mirror("https://github.com/coreos/etcd/releases/download/v%s/etcd-v%s-linux-amd64.tar.gz" % (ETCD_VERSION, ETCD_VERSION)), @@ -40,7 +41,7 @@ http_archive( load("@bazel_skylib//:lib.bzl", "versions") -versions.check(minimum_bazel_version = "0.16.0") +versions.check(minimum_bazel_version = "0.17.2") load("@io_bazel_rules_go//go:def.bzl", "go_download_sdk", "go_register_toolchains", "go_rules_dependencies") load("@io_bazel_rules_docker//docker:docker.bzl", "docker_pull", "docker_repositories") @@ -48,37 +49,47 @@ load("@io_bazel_rules_docker//docker:docker.bzl", "docker_pull", "docker_reposit go_rules_dependencies() go_register_toolchains( - go_version = "1.11.1", + go_version = "1.11.2", ) docker_repositories() http_file( name = "kubernetes_cni", + downloaded_file_path = "kubernetes_cni.tgz", sha256 = "f04339a21b8edf76d415e7f17b620e63b8f37a76b2f706671587ab6464411f2d", urls = mirror("https://storage.googleapis.com/kubernetes-release/network-plugins/cni-plugins-amd64-v0.6.0.tgz"), ) http_file( name = "cri_tools", + downloaded_file_path = "cri_tools.tgz", sha256 = "e7d913bcce40bf54e37ab1d4b75013c823d0551e6bc088b217bc1893207b4844", urls = mirror("https://github.com/kubernetes-incubator/cri-tools/releases/download/v%s/crictl-v%s-linux-amd64.tar.gz" % (CRI_TOOLS_VERSION, CRI_TOOLS_VERSION)), ) +docker_pull( + name = "debian-base-amd64", + digest = "sha256:86176bc8ccdc4d8ea7fbf6ba4b57fcefc2cb61ff7413114630940474ff9bf751", + registry = "k8s.gcr.io", + repository = "debian-base-amd64", + tag = "0.4.0", # ignored, but kept here for documentation +) + docker_pull( name = "debian-iptables-amd64", - digest = "sha256:0987db7ce42949d20ed2647a65d4bee0b616b4d40c7ea54769cc24b7ad003677", + digest = "sha256:d4ff8136b9037694a3165a7fff6a91e7fc828741b8ea1eda226d4d9ea5d23abb", registry = "k8s.gcr.io", repository = "debian-iptables-amd64", - tag = "v10.2", # ignored, but kept here for documentation + tag = "v11.0", # ignored, but kept here for documentation ) docker_pull( name = "debian-hyperkube-base-amd64", - digest = "sha256:b180af61c8c40a3e011630be135c091e7af6b6c784bedce839d31b9fad63c435", + digest = "sha256:4a77bc882f7d629c088a11ff144a2e86660268fddf63b61f52b6a93d16ab83f0", registry = "k8s.gcr.io", repository = "debian-hyperkube-base-amd64", - tag = "0.11.0", # ignored, but kept here for documentation + tag = "0.12.0", # ignored, but kept here for documentation ) docker_pull( diff --git a/cluster/addons/addon-manager/kube-addons.sh b/cluster/addons/addon-manager/kube-addons.sh index a017d622e5e5e..9332663a314ef 100755 --- a/cluster/addons/addon-manager/kube-addons.sh +++ b/cluster/addons/addon-manager/kube-addons.sh @@ -208,7 +208,7 @@ function is_leader() { # The business logic for whether a given object should be created # was already enforced by salt, and /etc/kubernetes/addons is the -# managed result is of that. Start everything below that directory. +# managed result of that. Start everything below that directory. log INFO "== Kubernetes addon manager started at $(date -Is) with ADDON_CHECK_INTERVAL_SEC=${ADDON_CHECK_INTERVAL_SEC} ==" # Create the namespace that will be used to host the cluster-level add-ons. diff --git a/cluster/addons/fluentd-elasticsearch/es-image/elasticsearch_logging_discovery.go b/cluster/addons/fluentd-elasticsearch/es-image/elasticsearch_logging_discovery.go index cf283dbf9b056..75f728662d7a7 100644 --- a/cluster/addons/fluentd-elasticsearch/es-image/elasticsearch_logging_discovery.go +++ b/cluster/addons/fluentd-elasticsearch/es-image/elasticsearch_logging_discovery.go @@ -113,7 +113,7 @@ func main() { } addrs = flattenSubsets(endpoints.Subsets) glog.Infof("Found %s", addrs) - if len(addrs) > 0 && len(addrs) == count { + if len(addrs) > 0 && len(addrs) >= count { break } } diff --git a/cluster/addons/python-image/Dockerfile b/cluster/addons/python-image/Dockerfile deleted file mode 100644 index 5205aeb37d49b..0000000000000 --- a/cluster/addons/python-image/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2016 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. - -FROM python:2.7-slim - -RUN pip install pyyaml diff --git a/cluster/addons/python-image/Makefile b/cluster/addons/python-image/Makefile deleted file mode 100644 index a073ac49db710..0000000000000 --- a/cluster/addons/python-image/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2016 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. - -IMAGE=staging-k8s.gcr.io/python -VERSION=v1 - -.PHONY: build push - -build: - docker build --pull -t "$(IMAGE):$(VERSION)" . - -push: - docker push "$(IMAGE):$(VERSION)" - diff --git a/cluster/addons/python-image/README.md b/cluster/addons/python-image/README.md deleted file mode 100644 index 06c82b25c6ebf..0000000000000 --- a/cluster/addons/python-image/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Python image - -The python image here is used by OS distros that don't have python installed to -run python scripts to parse the yaml files in the addon updater script. - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/cluster/addons/python-image/README.md?pixel)]() diff --git a/cluster/addons/storage-crds/OWNERS b/cluster/addons/storage-crds/OWNERS new file mode 100644 index 0000000000000..852f35cac613b --- /dev/null +++ b/cluster/addons/storage-crds/OWNERS @@ -0,0 +1,6 @@ +approvers: +- saad-ali +- jsafrane +- msau42 +reviewers: +- davidz627 \ No newline at end of file diff --git a/cluster/addons/storage-crds/README.md b/cluster/addons/storage-crds/README.md new file mode 100644 index 0000000000000..0ac4681c13e27 --- /dev/null +++ b/cluster/addons/storage-crds/README.md @@ -0,0 +1,13 @@ +# Kubernetes CSI CRDs + +The Kubernetes Container Storage Interface implementation defines some API objects as CRDs that Kubernetes components +including the Attach/Detach controller depend on. + +If you are using CSI, it is recommended that you enable the relevant feature gates (e.g. `CSIDriverRegistry`, `CSINodeInfo`, etc.), and ensure the CRDs in this directory are installed. + +These objects and their CRDs are defined in `staging/src/k8s.io/csi-api/pkg/crd/manifests`, the source of truth. +They are copied from that CRD manifest directory to this addon directory. +A unit test in `staging/src/k8s.io/csi-api/pkg/crd` verifies that this (and any other) copies of the manifest outside of `staging/src/k8s.io/csi-api/pkg/crd/manifests` do not drift from that source of truth. +If you need to make changes please make changes in the `staging/src/k8s.io/csi-api/pkg/crd/manifests` directory and then update this copy. + +For more information, see: https://kubernetes-csi.github.io/docs/ diff --git a/staging/src/k8s.io/csi-api/pkg/crd/testdata/csidriver.yaml b/cluster/addons/storage-crds/csidriver.yaml similarity index 88% rename from staging/src/k8s.io/csi-api/pkg/crd/testdata/csidriver.yaml rename to cluster/addons/storage-crds/csidriver.yaml index d950cbf494aa3..54416b24f933d 100644 --- a/staging/src/k8s.io/csi-api/pkg/crd/testdata/csidriver.yaml +++ b/cluster/addons/storage-crds/csidriver.yaml @@ -1,8 +1,9 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - creationTimestamp: null name: csidrivers.csi.storage.k8s.io + labels: + addonmanager.kubernetes.io/mode: Reconcile spec: group: csi.storage.k8s.io names: @@ -25,9 +26,3 @@ spec: information (like podName, podUID, etc.) during mount operations. type: string version: v1alpha1 -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/staging/src/k8s.io/csi-api/pkg/crd/testdata/csinodeinfo.yaml b/cluster/addons/storage-crds/csinodeinfo.yaml similarity index 88% rename from staging/src/k8s.io/csi-api/pkg/crd/testdata/csinodeinfo.yaml rename to cluster/addons/storage-crds/csinodeinfo.yaml index 6ea408d5e77f6..a9556fc1e824c 100644 --- a/staging/src/k8s.io/csi-api/pkg/crd/testdata/csinodeinfo.yaml +++ b/cluster/addons/storage-crds/csinodeinfo.yaml @@ -1,8 +1,9 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - creationTimestamp: null name: csinodeinfos.csi.storage.k8s.io + labels: + addonmanager.kubernetes.io/mode: Reconcile spec: group: csi.storage.k8s.io names: @@ -29,9 +30,3 @@ spec: type: array type: array version: v1alpha1 -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/cluster/gce/config-default.sh b/cluster/gce/config-default.sh index 671c1a5db7b4d..20d4d722bc3f4 100755 --- a/cluster/gce/config-default.sh +++ b/cluster/gce/config-default.sh @@ -246,10 +246,6 @@ fi # Optional: customize runtime config RUNTIME_CONFIG="${KUBE_RUNTIME_CONFIG:-}" -if [[ "${KUBE_FEATURE_GATES:-}" == "AllAlpha=true" ]]; then - RUNTIME_CONFIG="${KUBE_RUNTIME_CONFIG:-api/all=true}" -fi - # Optional: set feature gates FEATURE_GATES="${KUBE_FEATURE_GATES:-ExperimentalCriticalPodAnnotation=true}" @@ -260,6 +256,18 @@ if [[ ! -z "${NODE_ACCELERATORS}" ]]; then fi fi +if [[ "${KUBE_FEATURE_GATES:-}" == "AllAlpha=true" ]]; then + RUNTIME_CONFIG="${KUBE_RUNTIME_CONFIG:-api/all=true}" + if ! [[ "${KUBE_FEATURE_GATES:-}" =~ "CSIDriverRegistry" ]]; then + # If not explicitly specified, default to true. + FEATURE_GATES="${FEATURE_GATES},CSIDriverRegistry=true" + fi + if ! [[ "${KUBE_FEATURE_GATES:-}" =~ "CSINodeInfo" ]]; then + # If not explicitly specified, default to true. + FEATURE_GATES="${FEATURE_GATES},CSINodeInfo=true" + fi +fi + # Optional: Install cluster DNS. # Set CLUSTER_DNS_CORE_DNS to 'false' to install kube-dns instead of CoreDNS. CLUSTER_DNS_CORE_DNS="${CLUSTER_DNS_CORE_DNS:-true}" diff --git a/cluster/gce/gci/configure-helper.sh b/cluster/gce/gci/configure-helper.sh index 0a4a410acb1b8..291a72aa6b32c 100644 --- a/cluster/gce/gci/configure-helper.sh +++ b/cluster/gce/gci/configure-helper.sh @@ -25,21 +25,6 @@ set -o errexit set -o nounset set -o pipefail -readonly UUID_MNT_PREFIX="/mnt/disks/by-uuid/google-local-ssds" -readonly UUID_BLOCK_PREFIX="/dev/disk/by-uuid/google-local-ssds" -readonly COREDNS_AUTOSCALER="Deployment/coredns" -readonly KUBEDNS_AUTOSCALER="Deployment/kube-dns" - -# Resource requests of master components. -KUBE_CONTROLLER_MANAGER_CPU_REQUEST="${KUBE_CONTROLLER_MANAGER_CPU_REQUEST:-200m}" -KUBE_SCHEDULER_CPU_REQUEST="${KUBE_SCHEDULER_CPU_REQUEST:-75m}" - -# Use --retry-connrefused opt only if it's supported by curl. -CURL_RETRY_CONNREFUSED="" -if curl --help | grep -q -- '--retry-connrefused'; then - CURL_RETRY_CONNREFUSED='--retry-connrefused' -fi - function setup-os-params { # Reset core_pattern. On GCI, the default core_pattern pipes the core dumps to # /sbin/crash_reporter which is more restrictive in saving crash dumps. So for @@ -843,6 +828,13 @@ rules: resources: - group: "" # core resources: ["namespaces", "namespaces/status", "namespaces/finalize"] + - level: None + users: ["cluster-autoscaler"] + verbs: ["get", "update"] + namespaces: ["kube-system"] + resources: + - group: "" # core + resources: ["configmaps", "endpoints"] # Don't log HPA fetching metrics. - level: None users: @@ -1273,10 +1265,12 @@ EOF # Create the log file and set its properties. # # $1 is the file to create. +# $2: the log owner uid to set for the log file. +# $3: the log owner gid to set for the log file. function prepare-log-file { touch $1 chmod 644 $1 - chown "${LOG_OWNER_USER:-root}":"${LOG_OWNER_GROUP:-root}" $1 + chown "${2:-${LOG_OWNER_USER:-root}}":"${3:-${LOG_OWNER_GROUP:-root}}" $1 } # Prepares parameters for kube-proxy manifest. @@ -2580,6 +2574,9 @@ EOF if [[ "${ENABLE_DEFAULT_STORAGE_CLASS:-}" == "true" ]]; then setup-addon-manifests "addons" "storage-class/gce" fi + if [[ "${FEATURE_GATES:-}" =~ "CSIDriverRegistry=true" || "${FEATURE_GATES:-}" =~ "CSINodeInfo=true" ]]; then + setup-addon-manifests "addons" "storage-crds" + fi if [[ "${ENABLE_IP_MASQ_AGENT:-}" == "true" ]]; then setup-addon-manifests "addons" "ip-masq-agent" fi @@ -2748,6 +2745,21 @@ EOF function main() { echo "Start to configure instance for kubernetes" + readonly UUID_MNT_PREFIX="/mnt/disks/by-uuid/google-local-ssds" + readonly UUID_BLOCK_PREFIX="/dev/disk/by-uuid/google-local-ssds" + readonly COREDNS_AUTOSCALER="Deployment/coredns" + readonly KUBEDNS_AUTOSCALER="Deployment/kube-dns" + + # Resource requests of master components. + KUBE_CONTROLLER_MANAGER_CPU_REQUEST="${KUBE_CONTROLLER_MANAGER_CPU_REQUEST:-200m}" + KUBE_SCHEDULER_CPU_REQUEST="${KUBE_SCHEDULER_CPU_REQUEST:-75m}" + + # Use --retry-connrefused opt only if it's supported by curl. + CURL_RETRY_CONNREFUSED="" + if curl --help | grep -q -- '--retry-connrefused'; then + CURL_RETRY_CONNREFUSED='--retry-connrefused' + fi + KUBE_HOME="/home/kubernetes" CONTAINERIZED_MOUNTER_HOME="${KUBE_HOME}/containerized_mounter" PV_RECYCLER_OVERRIDE_TEMPLATE="${KUBE_HOME}/kube-manifests/kubernetes/pv-recycler-template.yaml" @@ -2839,9 +2851,6 @@ function main() { echo "Done for the configuration for kubernetes" } -# use --source-only to test functions defined in this script. -if [[ "$#" -eq 1 && "${1}" == "--source-only" ]]; then - : -else - main "${@}" +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "${@}" fi diff --git a/cluster/gce/gci/configure_helper_test.go b/cluster/gce/gci/configure_helper_test.go index 1b1384403a2c4..9298f322baf85 100644 --- a/cluster/gce/gci/configure_helper_test.go +++ b/cluster/gce/gci/configure_helper_test.go @@ -125,7 +125,7 @@ func (c *ManifestTestCase) mustCreateEnv(envTemplate string, env interface{}) { func (c *ManifestTestCase) mustInvokeFunc(envTemplate string, env interface{}) { c.mustCreateEnv(envTemplate, env) - args := fmt.Sprintf("source %s ; source %s --source-only ; %s", c.envScriptPath, configureHelperScriptName, c.manifestFuncName) + args := fmt.Sprintf("source %s ; source %s; %s", c.envScriptPath, configureHelperScriptName, c.manifestFuncName) cmd := exec.Command("bash", "-c", args) bs, err := cmd.CombinedOutput() diff --git a/cluster/gce/manifests/kube-addon-manager.yaml b/cluster/gce/manifests/kube-addon-manager.yaml index d91570f0bfbae..9694f88a05a0d 100644 --- a/cluster/gce/manifests/kube-addon-manager.yaml +++ b/cluster/gce/manifests/kube-addon-manager.yaml @@ -14,7 +14,7 @@ spec: - name: kube-addon-manager # When updating version also bump it in: # - test/kubemark/resources/manifests/kube-addon-manager.yaml - image: k8s.gcr.io/kube-addon-manager:v8.8 + image: k8s.gcr.io/kube-addon-manager:v8.9 command: - /bin/bash - -c diff --git a/cluster/images/conformance/Makefile b/cluster/images/conformance/Makefile index d5f7582e81ac1..43f61ddf53df8 100644 --- a/cluster/images/conformance/Makefile +++ b/cluster/images/conformance/Makefile @@ -25,7 +25,7 @@ KUBECTL_BIN?=$(shell pwd)/../../../$(OUT_DIR)/dockerized/bin/linux/$(ARCH)/kubec E2E_TEST_BIN?=$(shell pwd)/../../../$(OUT_DIR)/dockerized/bin/linux/$(ARCH)/e2e.test CLUSTER_DIR?=$(shell pwd)/../../../cluster/ -BASEIMAGE=k8s.gcr.io/debian-hyperkube-base-$(ARCH):0.11.0 +BASEIMAGE=k8s.gcr.io/debian-hyperkube-base-$(ARCH):0.12.0 TEMP_DIR:=$(shell mktemp -d -t conformanceXXXXXX) all: build diff --git a/cluster/images/etcd/Makefile b/cluster/images/etcd/Makefile index 8a2f1ba873cbf..0aa28362918d6 100644 --- a/cluster/images/etcd/Makefile +++ b/cluster/images/etcd/Makefile @@ -142,7 +142,7 @@ all-push: all-push-images push-manifest push-manifest: docker manifest create --amend $(MANIFEST_IMAGE):$(IMAGE_TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(MANIFEST_IMAGE)\-&:$(IMAGE_TAG)~g") @for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${MANIFEST_IMAGE}:${IMAGE_TAG} ${MANIFEST_IMAGE}-$${arch}:${IMAGE_TAG}; done - docker manifest push ${MANIFEST_IMAGE}:${IMAGE_TAG} + docker manifest push --purge ${MANIFEST_IMAGE}:${IMAGE_TAG} unit-test: docker run --interactive -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \ diff --git a/cluster/images/hyperkube/Makefile b/cluster/images/hyperkube/Makefile index 16af35b9c1589..2bd17d3416c13 100644 --- a/cluster/images/hyperkube/Makefile +++ b/cluster/images/hyperkube/Makefile @@ -22,7 +22,7 @@ ARCH?=amd64 OUT_DIR?=_output HYPERKUBE_BIN?=$(shell pwd)/../../../$(OUT_DIR)/dockerized/bin/linux/$(ARCH)/hyperkube -BASEIMAGE=k8s.gcr.io/debian-hyperkube-base-$(ARCH):0.11.0 +BASEIMAGE=k8s.gcr.io/debian-hyperkube-base-$(ARCH):0.12.0 TEMP_DIR:=$(shell mktemp -d -t hyperkubeXXXXXX) all: build diff --git a/cmd/cloud-controller-manager/OWNERS b/cmd/cloud-controller-manager/OWNERS index d3f960b76de83..d7318e2841f71 100644 --- a/cmd/cloud-controller-manager/OWNERS +++ b/cmd/cloud-controller-manager/OWNERS @@ -3,12 +3,14 @@ approvers: - luxas - wlan0 - andrewsykim +- sttts reviewers: - thockin - luxas - wlan0 - andrewsykim - stewart-yu +- sttts labels: - sig/api-machinery - sig/cloud-provider diff --git a/cmd/cloud-controller-manager/app/options/options.go b/cmd/cloud-controller-manager/app/options/options.go index 5b184105bde81..e15a659f012fe 100644 --- a/cmd/cloud-controller-manager/app/options/options.go +++ b/cmd/cloud-controller-manager/app/options/options.go @@ -44,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/master/ports" + // add the kubernetes feature gates _ "k8s.io/kubernetes/pkg/features" ) @@ -102,7 +103,8 @@ func NewCloudControllerManagerOptions() (*CloudControllerManagerOptions, error) s.Authorization.RemoteKubeConfigFileOptional = true s.Authorization.AlwaysAllowPaths = []string{"/healthz"} - s.SecureServing.ServerCert.CertDirectory = "/var/run/kubernetes" + // Set the PairName but leave certificate directory blank to generate in-memory by default + s.SecureServing.ServerCert.CertDirectory = "" s.SecureServing.ServerCert.PairName = "cloud-controller-manager" s.SecureServing.BindPort = ports.CloudControllerManagerPort diff --git a/cmd/cloud-controller-manager/app/options/options_test.go b/cmd/cloud-controller-manager/app/options/options_test.go index 72bcb068a9cfb..b9825bb2354ed 100644 --- a/cmd/cloud-controller-manager/app/options/options_test.go +++ b/cmd/cloud-controller-manager/app/options/options_test.go @@ -78,7 +78,7 @@ func TestDefaultFlags(t *testing.T) { BindPort: 10258, BindAddress: net.ParseIP("0.0.0.0"), ServerCert: apiserveroptions.GeneratableKeyCert{ - CertDirectory: "/var/run/kubernetes", + CertDirectory: "", PairName: "cloud-controller-manager", }, HTTP2MaxStreamsPerConnection: 0, diff --git a/cmd/kube-apiserver/app/BUILD b/cmd/kube-apiserver/app/BUILD index ef7a18ffd943a..eb338464cbbca 100644 --- a/cmd/kube-apiserver/app/BUILD +++ b/cmd/kube-apiserver/app/BUILD @@ -1,9 +1,4 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) +load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", @@ -13,12 +8,11 @@ go_library( "server.go", ], importpath = "k8s.io/kubernetes/cmd/kube-apiserver/app", + visibility = ["//visibility:public"], deps = [ "//cmd/kube-apiserver/app/options:go_default_library", "//pkg/api/legacyscheme:go_default_library", "//pkg/capabilities:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", "//pkg/controller/serviceaccount:go_default_library", "//pkg/features:go_default_library", "//pkg/generated/openapi:go_default_library", @@ -32,7 +26,6 @@ go_library( "//pkg/master/controller/crdregistration:go_default_library", "//pkg/master/reconcilers:go_default_library", "//pkg/master/tunneler:go_default_library", - "//pkg/quota/v1/install:go_default_library", "//pkg/registry/cachesize:go_default_library", "//pkg/registry/rbac/rest:go_default_library", "//pkg/serviceaccount:go_default_library", @@ -53,7 +46,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library", @@ -67,11 +59,8 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/flag:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", - "//staging/src/k8s.io/client-go/discovery/cached:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", - "//staging/src/k8s.io/client-go/rest:go_default_library", - "//staging/src/k8s.io/client-go/restmapper:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", "//staging/src/k8s.io/cloud-provider:go_default_library", @@ -105,4 +94,5 @@ filegroup( "//cmd/kube-apiserver/app/testing:all-srcs", ], tags = ["automanaged"], + visibility = ["//visibility:public"], ) diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index 8eec41ba560f0..0d21910d6b00d 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -42,7 +42,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" utilwait "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/admission" - webhookinit "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authorization/authorizer" openapinamer "k8s.io/apiserver/pkg/endpoints/openapi" @@ -54,11 +53,8 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" apiserverflag "k8s.io/apiserver/pkg/util/flag" "k8s.io/apiserver/pkg/util/webhook" - cacheddiscovery "k8s.io/client-go/discovery/cached" clientgoinformers "k8s.io/client-go/informers" clientgoclientset "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "k8s.io/client-go/restmapper" certutil "k8s.io/client-go/util/cert" cloudprovider "k8s.io/cloud-provider" aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver" @@ -67,8 +63,6 @@ import ( "k8s.io/kubernetes/cmd/kube-apiserver/app/options" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/capabilities" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount" "k8s.io/kubernetes/pkg/features" generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi" @@ -81,7 +75,6 @@ import ( "k8s.io/kubernetes/pkg/master" "k8s.io/kubernetes/pkg/master/reconcilers" "k8s.io/kubernetes/pkg/master/tunneler" - quotainstall "k8s.io/kubernetes/pkg/quota/v1/install" "k8s.io/kubernetes/pkg/registry/cachesize" rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest" "k8s.io/kubernetes/pkg/serviceaccount" @@ -286,9 +279,8 @@ func CreateKubeAPIServerConfig( ) { var genericConfig *genericapiserver.Config var storageFactory *serverstorage.DefaultStorageFactory - var sharedInformers informers.SharedInformerFactory var versionedInformers clientgoinformers.SharedInformerFactory - genericConfig, sharedInformers, versionedInformers, insecureServingInfo, serviceResolver, pluginInitializers, admissionPostStartHook, storageFactory, lastErr = buildGenericConfig(s.ServerRunOptions, proxyTransport) + genericConfig, versionedInformers, insecureServingInfo, serviceResolver, pluginInitializers, admissionPostStartHook, storageFactory, lastErr = buildGenericConfig(s.ServerRunOptions, proxyTransport) if lastErr != nil { return } @@ -404,7 +396,6 @@ func CreateKubeAPIServerConfig( APIAudiences: apiAudiences, ServiceAccountMaxExpiration: maxExpiration, - InternalInformers: sharedInformers, VersionedInformers: versionedInformers, }, } @@ -423,7 +414,6 @@ func buildGenericConfig( proxyTransport *http.Transport, ) ( genericConfig *genericapiserver.Config, - sharedInformers informers.SharedInformerFactory, versionedInformers clientgoinformers.SharedInformerFactory, insecureServingInfo *genericapiserver.DeprecatedInsecureServingInfo, serviceResolver aggregatorapiserver.ServiceResolver, @@ -491,14 +481,7 @@ func buildGenericConfig( // set it in kube-apiserver. genericConfig.LoopbackClientConfig.ContentConfig.ContentType = "application/vnd.kubernetes.protobuf" - client, err := internalclientset.NewForConfig(genericConfig.LoopbackClientConfig) - if err != nil { - lastErr = fmt.Errorf("failed to create clientset: %v", err) - return - } - kubeClientConfig := genericConfig.LoopbackClientConfig - sharedInformers = informers.NewSharedInformerFactory(client, 10*time.Minute) clientgoExternalClient, err := clientgoclientset.NewForConfig(kubeClientConfig) if err != nil { lastErr = fmt.Errorf("failed to create real external clientset: %v", err) @@ -506,25 +489,7 @@ func buildGenericConfig( } versionedInformers = clientgoinformers.NewSharedInformerFactory(clientgoExternalClient, 10*time.Minute) - if s.EnableAggregatorRouting { - serviceResolver = aggregatorapiserver.NewEndpointServiceResolver( - versionedInformers.Core().V1().Services().Lister(), - versionedInformers.Core().V1().Endpoints().Lister(), - ) - } else { - serviceResolver = aggregatorapiserver.NewClusterIPServiceResolver( - versionedInformers.Core().V1().Services().Lister(), - ) - } - // resolve kubernetes.default.svc locally - localHost, err := url.Parse(genericConfig.LoopbackClientConfig.Host) - if err != nil { - lastErr = err - return - } - serviceResolver = aggregatorapiserver.NewLoopbackServiceResolver(serviceResolver, localHost) - - genericConfig.Authentication.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, clientgoExternalClient, sharedInformers) + genericConfig.Authentication.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, clientgoExternalClient, versionedInformers) if err != nil { lastErr = fmt.Errorf("invalid authentication config: %v", err) return @@ -539,36 +504,14 @@ func buildGenericConfig( genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName) } - webhookAuthResolverWrapper := func(delegate webhook.AuthenticationInfoResolver) webhook.AuthenticationInfoResolver { - return &webhook.AuthenticationInfoResolverDelegator{ - ClientConfigForFunc: func(server string) (*rest.Config, error) { - if server == "kubernetes.default.svc" { - return genericConfig.LoopbackClientConfig, nil - } - return delegate.ClientConfigFor(server) - }, - ClientConfigForServiceFunc: func(serviceName, serviceNamespace string) (*rest.Config, error) { - if serviceName == "kubernetes" && serviceNamespace == "default" { - return genericConfig.LoopbackClientConfig, nil - } - ret, err := delegate.ClientConfigForService(serviceName, serviceNamespace) - if err != nil { - return nil, err - } - if proxyTransport != nil && proxyTransport.DialContext != nil { - ret.Dial = proxyTransport.DialContext - } - return ret, err - }, - } + admissionConfig := &kubeapiserveradmission.Config{ + ExternalInformers: versionedInformers, + LoopbackClientConfig: genericConfig.LoopbackClientConfig, + CloudConfigFile: s.CloudProvider.CloudConfigFile, } - pluginInitializers, admissionPostStartHook, err = BuildAdmissionPluginInitializers( - s, - client, - sharedInformers, - serviceResolver, - webhookAuthResolverWrapper, - ) + serviceResolver = buildServiceResolver(s.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, versionedInformers) + + pluginInitializers, admissionPostStartHook, err = admissionConfig.New(proxyTransport, serviceResolver) if err != nil { lastErr = fmt.Errorf("failed to create admission plugin initializer: %v", err) return @@ -587,51 +530,14 @@ func buildGenericConfig( return } -// BuildAdmissionPluginInitializers constructs the admission plugin initializer -func BuildAdmissionPluginInitializers( - s *options.ServerRunOptions, - client internalclientset.Interface, - sharedInformers informers.SharedInformerFactory, - serviceResolver aggregatorapiserver.ServiceResolver, - webhookAuthWrapper webhook.AuthenticationInfoResolverWrapper, -) ([]admission.PluginInitializer, genericapiserver.PostStartHookFunc, error) { - var cloudConfig []byte - - if s.CloudProvider.CloudConfigFile != "" { - var err error - cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile) - if err != nil { - glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err) - } - } - - // We have a functional client so we can use that to build our discovery backed REST mapper - // Use a discovery client capable of being refreshed. - discoveryClient := cacheddiscovery.NewMemCacheClient(client.Discovery()) - discoveryRESTMapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient) - - admissionPostStartHook := func(context genericapiserver.PostStartHookContext) error { - discoveryRESTMapper.Reset() - go utilwait.Until(discoveryRESTMapper.Reset, 30*time.Second, context.StopCh) - return nil - } - - quotaConfiguration := quotainstall.NewQuotaConfigurationForAdmission() - - kubePluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, cloudConfig, discoveryRESTMapper, quotaConfiguration) - webhookPluginInitializer := webhookinit.NewPluginInitializer(webhookAuthWrapper, serviceResolver) - - return []admission.PluginInitializer{webhookPluginInitializer, kubePluginInitializer}, admissionPostStartHook, nil -} - // BuildAuthenticator constructs the authenticator -func BuildAuthenticator(s *options.ServerRunOptions, extclient clientgoclientset.Interface, sharedInformers informers.SharedInformerFactory) (authenticator.Request, *spec.SecurityDefinitions, error) { +func BuildAuthenticator(s *options.ServerRunOptions, extclient clientgoclientset.Interface, versionedInformer clientgoinformers.SharedInformerFactory) (authenticator.Request, *spec.SecurityDefinitions, error) { authenticatorConfig := s.Authentication.ToAuthenticationConfig() if s.Authentication.ServiceAccounts.Lookup { authenticatorConfig.ServiceAccountTokenGetter = serviceaccountcontroller.NewGetterFromClient(extclient) } authenticatorConfig.BootstrapTokenAuthenticator = bootstrap.NewTokenAuthenticator( - sharedInformers.Core().InternalVersion().Secrets().Lister().Secrets(v1.NamespaceSystem), + versionedInformer.Core().V1().Secrets().Lister().Secrets(v1.NamespaceSystem), ) return authenticatorConfig.New() @@ -730,6 +636,25 @@ func Complete(s *options.ServerRunOptions) (completedServerRunOptions, error) { return options, nil } +func buildServiceResolver(enabledAggregatorRouting bool, hostname string, informer clientgoinformers.SharedInformerFactory) webhook.ServiceResolver { + var serviceResolver webhook.ServiceResolver + if enabledAggregatorRouting { + serviceResolver = aggregatorapiserver.NewEndpointServiceResolver( + informer.Core().V1().Services().Lister(), + informer.Core().V1().Endpoints().Lister(), + ) + } else { + serviceResolver = aggregatorapiserver.NewClusterIPServiceResolver( + informer.Core().V1().Services().Lister(), + ) + } + // resolve kubernetes.default.svc locally + if localHost, err := url.Parse(hostname); err == nil { + serviceResolver = aggregatorapiserver.NewLoopbackServiceResolver(serviceResolver, localHost) + } + return serviceResolver +} + func readCAorNil(file string) ([]byte, error) { if len(file) == 0 { return nil, nil diff --git a/cmd/kube-controller-manager/OWNERS b/cmd/kube-controller-manager/OWNERS index dc963a9e2febf..e8e10481cd458 100644 --- a/cmd/kube-controller-manager/OWNERS +++ b/cmd/kube-controller-manager/OWNERS @@ -2,6 +2,7 @@ approvers: - deads2k - lavalamp - mikedanese +- sttts reviewers: - '249043822' - a-robinson diff --git a/cmd/kube-controller-manager/app/options/options.go b/cmd/kube-controller-manager/app/options/options.go index 22cf24a12e3f7..377a6ee3de971 100644 --- a/cmd/kube-controller-manager/app/options/options.go +++ b/cmd/kube-controller-manager/app/options/options.go @@ -190,7 +190,8 @@ func NewKubeControllerManagerOptions() (*KubeControllerManagerOptions, error) { s.Authorization.RemoteKubeConfigFileOptional = true s.Authorization.AlwaysAllowPaths = []string{"/healthz"} - s.SecureServing.ServerCert.CertDirectory = "/var/run/kubernetes" + // Set the PairName but leave certificate directory blank to generate in-memory by default + s.SecureServing.ServerCert.CertDirectory = "" s.SecureServing.ServerCert.PairName = "kube-controller-manager" s.SecureServing.BindPort = ports.KubeControllerManagerPort @@ -260,9 +261,6 @@ func (s *KubeControllerManagerOptions) Flags(allControllers []string, disabledBy fs := fss.FlagSet("misc") fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig).") fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.") - var dummy string - fs.MarkDeprecated("insecure-experimental-approve-all-kubelet-csrs-for-group", "This flag does nothing.") - fs.StringVar(&dummy, "insecure-experimental-approve-all-kubelet-csrs-for-group", "", "This flag does nothing.") utilfeature.DefaultFeatureGate.AddFlag(fss.FlagSet("generic")) return fss diff --git a/cmd/kubeadm/.import-restrictions b/cmd/kubeadm/.import-restrictions index 44489b889552e..0149df472621c 100644 --- a/cmd/kubeadm/.import-restrictions +++ b/cmd/kubeadm/.import-restrictions @@ -50,6 +50,7 @@ "k8s.io/kubernetes/pkg/apis/autoscaling", "k8s.io/kubernetes/pkg/apis/core", "k8s.io/kubernetes/pkg/api/service", + "k8s.io/kubernetes/pkg/apis/apps", "k8s.io/kubernetes/pkg/apis/extensions", "k8s.io/kubernetes/pkg/apis/networking", "k8s.io/kubernetes/pkg/apis/policy", diff --git a/cmd/kubeadm/app/apis/kubeadm/BUILD b/cmd/kubeadm/app/apis/kubeadm/BUILD index e043841b1bc72..70d51c2bfae21 100644 --- a/cmd/kubeadm/app/apis/kubeadm/BUILD +++ b/cmd/kubeadm/app/apis/kubeadm/BUILD @@ -26,6 +26,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -59,5 +60,6 @@ go_test( deps = [ "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/apis/kubeadm/bootstraptokenhelpers.go b/cmd/kubeadm/app/apis/kubeadm/bootstraptokenhelpers.go index 5881ea4d81716..cd2977ed64333 100644 --- a/cmd/kubeadm/app/apis/kubeadm/bootstraptokenhelpers.go +++ b/cmd/kubeadm/app/apis/kubeadm/bootstraptokenhelpers.go @@ -17,11 +17,12 @@ limitations under the License. package kubeadm import ( - "fmt" "sort" "strings" "time" + "github.com/pkg/errors" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" bootstrapapi "k8s.io/cluster-bootstrap/token/api" @@ -84,24 +85,24 @@ func BootstrapTokenFromSecret(secret *v1.Secret) (*BootstrapToken, error) { // Get the Token ID field from the Secret data tokenID := getSecretString(secret, bootstrapapi.BootstrapTokenIDKey) if len(tokenID) == 0 { - return nil, fmt.Errorf("Bootstrap Token Secret has no token-id data: %s", secret.Name) + return nil, errors.Errorf("bootstrap Token Secret has no token-id data: %s", secret.Name) } // Enforce the right naming convention if secret.Name != bootstraputil.BootstrapTokenSecretName(tokenID) { - return nil, fmt.Errorf("bootstrap token name is not of the form '%s(token-id)'. Actual: %q. Expected: %q", + return nil, errors.Errorf("bootstrap token name is not of the form '%s(token-id)'. Actual: %q. Expected: %q", bootstrapapi.BootstrapTokenSecretPrefix, secret.Name, bootstraputil.BootstrapTokenSecretName(tokenID)) } tokenSecret := getSecretString(secret, bootstrapapi.BootstrapTokenSecretKey) if len(tokenSecret) == 0 { - return nil, fmt.Errorf("Bootstrap Token Secret has no token-secret data: %s", secret.Name) + return nil, errors.Errorf("bootstrap Token Secret has no token-secret data: %s", secret.Name) } // Create the BootstrapTokenString object based on the ID and Secret bts, err := NewBootstrapTokenStringFromIDAndSecret(tokenID, tokenSecret) if err != nil { - return nil, fmt.Errorf("Bootstrap Token Secret is invalid and couldn't be parsed: %v", err) + return nil, errors.Wrap(err, "bootstrap Token Secret is invalid and couldn't be parsed") } // Get the description (if any) from the Secret @@ -114,7 +115,7 @@ func BootstrapTokenFromSecret(secret *v1.Secret) (*BootstrapToken, error) { if len(secretExpiration) > 0 { expTime, err := time.Parse(time.RFC3339, secretExpiration) if err != nil { - return nil, fmt.Errorf("can't parse expiration time of bootstrap token %q: %v", secret.Name, err) + return nil, errors.Wrapf(err, "can't parse expiration time of bootstrap token %q", secret.Name) } expires = &metav1.Time{Time: expTime} } diff --git a/cmd/kubeadm/app/apis/kubeadm/bootstraptokenstring.go b/cmd/kubeadm/app/apis/kubeadm/bootstraptokenstring.go index c92a78afc0790..2c1175b9d8b8a 100644 --- a/cmd/kubeadm/app/apis/kubeadm/bootstraptokenstring.go +++ b/cmd/kubeadm/app/apis/kubeadm/bootstraptokenstring.go @@ -24,6 +24,8 @@ import ( "fmt" "strings" + "github.com/pkg/errors" + bootstrapapi "k8s.io/cluster-bootstrap/token/api" bootstraputil "k8s.io/cluster-bootstrap/token/util" ) @@ -77,7 +79,7 @@ func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) { substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token) // TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works) if len(substrs) != 3 { - return nil, fmt.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern) + return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern) } return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil diff --git a/cmd/kubeadm/app/apis/kubeadm/bootstraptokenstring_test.go b/cmd/kubeadm/app/apis/kubeadm/bootstraptokenstring_test.go index 8a389f83ec163..f43f7892290f0 100644 --- a/cmd/kubeadm/app/apis/kubeadm/bootstraptokenstring_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/bootstraptokenstring_test.go @@ -18,9 +18,10 @@ package kubeadm import ( "encoding/json" - "fmt" "reflect" "testing" + + "github.com/pkg/errors" ) func TestMarshalJSON(t *testing.T) { @@ -99,13 +100,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error { // If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string if len(input) > 0 { if err := json.Unmarshal([]byte(input), newbts); err != nil { - return fmt.Errorf("expected no unmarshal error, got error: %v", err) + return errors.Wrap(err, "expected no unmarshal error, got error") } if b, err = json.Marshal(newbts); err != nil { - return fmt.Errorf("expected no marshal error, got error: %v", err) + return errors.Wrap(err, "expected no marshal error, got error") } if input != string(b) { - return fmt.Errorf( + return errors.Errorf( "expected token: %s\n\t actual: %s", input, string(b), @@ -113,13 +114,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error { } } else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object if b, err = json.Marshal(bts); err != nil { - return fmt.Errorf("expected no marshal error, got error: %v", err) + return errors.Wrap(err, "expected no marshal error, got error") } if err := json.Unmarshal(b, newbts); err != nil { - return fmt.Errorf("expected no unmarshal error, got error: %v", err) + return errors.Wrap(err, "expected no unmarshal error, got error") } if !reflect.DeepEqual(bts, newbts) { - return fmt.Errorf( + return errors.Errorf( "expected object: %v\n\t actual: %v", bts, newbts, diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go index a17688767833c..f9d1c9df3eac5 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go @@ -50,6 +50,11 @@ func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c fuzz.Continue) { // More specifically: // internal with manually applied defaults -> external object : loosing ClusterConfiguration) -> internal object with automatically applied defaults obj.ClusterConfiguration = kubeadm.ClusterConfiguration{ + APIServer: kubeadm.APIServer{ + TimeoutForControlPlane: &metav1.Duration{ + Duration: constants.DefaultControlPlaneTimeout, + }, + }, AuditPolicyConfiguration: kubeadm.AuditPolicyConfiguration{ LogDir: constants.StaticPodAuditPolicyLogDir, LogMaxAge: &v1beta1.DefaultAuditPolicyLogMaxAge, @@ -97,6 +102,9 @@ func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue obj.ClusterName = "bar" obj.ImageRepository = "baz" obj.KubernetesVersion = "qux" + obj.APIServer.TimeoutForControlPlane = &metav1.Duration{ + Duration: constants.DefaultControlPlaneTimeout, + } } func fuzzAuditPolicyConfiguration(obj *kubeadm.AuditPolicyConfiguration, c fuzz.Continue) { diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go index a1138558e4881..f05188fcdc763 100644 --- a/cmd/kubeadm/app/apis/kubeadm/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/types.go @@ -81,33 +81,15 @@ type ClusterConfiguration struct { // could be used for assigning a stable DNS to the control plane. ControlPlaneEndpoint string - // APIServerExtraArgs is a set of extra flags to pass to the API Server or override - // default ones in form of =. - // TODO: This is temporary and ideally we would like to switch all components to - // use ComponentConfig + ConfigMaps. - APIServerExtraArgs map[string]string - // ControllerManagerExtraArgs is a set of extra flags to pass to the Controller Manager - // or override default ones in form of = - // TODO: This is temporary and ideally we would like to switch all components to - // use ComponentConfig + ConfigMaps. - ControllerManagerExtraArgs map[string]string - // SchedulerExtraArgs is a set of extra flags to pass to the Scheduler or override - // default ones in form of = - // TODO: This is temporary and ideally we would like to switch all components to - // use ComponentConfig + ConfigMaps. - SchedulerExtraArgs map[string]string - - // APIServerExtraVolumes is an extra set of host volumes mounted to the API server. - APIServerExtraVolumes []HostPathMount - // ControllerManagerExtraVolumes is an extra set of host volumes mounted to the - // Controller Manager. - ControllerManagerExtraVolumes []HostPathMount - // SchedulerExtraVolumes is an extra set of host volumes mounted to the scheduler. - SchedulerExtraVolumes []HostPathMount - - // APIServerCertSANs sets extra Subject Alternative Names for the API Server - // signing cert. - APIServerCertSANs []string + // APIServer contains extra settings for the API server control plane component + APIServer APIServer + + // ControllerManager contains extra settings for the controller manager control plane component + ControllerManager ControlPlaneComponent + + // Scheduler contains extra settings for the scheduler control plane component + Scheduler ControlPlaneComponent + // CertificatesDir specifies where to store or look for all required certificates. CertificatesDir string @@ -133,6 +115,26 @@ type ClusterConfiguration struct { ClusterName string } +// ControlPlaneComponent holds settings common to control plane component of the cluster +type ControlPlaneComponent struct { + // ExtraArgs is an extra set of flags to pass to the control plane component. + ExtraArgs map[string]string + + // ExtraVolumes is an extra set of host volumes, mounted to the control plane component. + ExtraVolumes []HostPathMount +} + +// APIServer holds settings necessary for API server deployments in the cluster +type APIServer struct { + ControlPlaneComponent + + // CertSANs sets extra Subject Alternative Names for the API Server signing cert. + CertSANs []string + + // TimeoutForControlPlane controls the timeout that we use for API server to appear + TimeoutForControlPlane *metav1.Duration +} + // ComponentConfigs holds known internal ComponentConfig types for other components type ComponentConfigs struct { // Kubelet holds the ComponentConfiguration for the kubelet @@ -323,10 +325,8 @@ type BootstrapTokenDiscovery struct { // fetched from the master. Token string - // APIServerEndpoints is a set of IPs or domain names to API servers from which info - // will be fetched. Currently we only pay attention to one API server but - // hope to support >1 in the future. - APIServerEndpoints []string + // APIServerEndpoint is an IP or domain name to the API server from which info will be fetched. + APIServerEndpoint string // CACertHashes specifies a set of public key pins to verify // when token-based discovery is used. The root CA found during discovery @@ -372,8 +372,8 @@ type HostPathMount struct { HostPath string // MountPath is the path inside the pod where hostPath will be mounted. MountPath string - // Writable controls write access to the volume - Writable bool + // ReadOnly controls write access to the volume + ReadOnly bool // PathType is the type of the HostPath. PathType v1.HostPathType } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/BUILD b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/BUILD index 9d94d61c98b73..873fd4bbe03d5 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/BUILD +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/BUILD @@ -27,6 +27,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -48,4 +49,5 @@ go_test( name = "go_default_test", srcs = ["bootstraptokenstring_test.go"], embed = [":go_default_library"], + deps = ["//vendor/github.com/pkg/errors:go_default_library"], ) diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/bootstraptokenstring.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/bootstraptokenstring.go index f28f98dad249e..c394c111a6e0c 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/bootstraptokenstring.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/bootstraptokenstring.go @@ -20,6 +20,8 @@ import ( "fmt" "strings" + "github.com/pkg/errors" + bootstrapapi "k8s.io/cluster-bootstrap/token/api" bootstraputil "k8s.io/cluster-bootstrap/token/util" ) @@ -73,7 +75,7 @@ func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) { substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token) // TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works) if len(substrs) != 3 { - return nil, fmt.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern) + return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern) } return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/bootstraptokenstring_test.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/bootstraptokenstring_test.go index 9c4d4f47a9a5e..320d9d5660db2 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/bootstraptokenstring_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/bootstraptokenstring_test.go @@ -18,9 +18,10 @@ package v1alpha3 import ( "encoding/json" - "fmt" "reflect" "testing" + + "github.com/pkg/errors" ) func TestMarshalJSON(t *testing.T) { @@ -99,13 +100,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error { // If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string if len(input) > 0 { if err := json.Unmarshal([]byte(input), newbts); err != nil { - return fmt.Errorf("expected no unmarshal error, got error: %v", err) + return errors.Wrap(err, "expected no unmarshal error, got error") } if b, err = json.Marshal(newbts); err != nil { - return fmt.Errorf("expected no marshal error, got error: %v", err) + return errors.Wrap(err, "expected no marshal error, got error") } if input != string(b) { - return fmt.Errorf( + return errors.Errorf( "expected token: %s\n\t actual: %s", input, string(b), @@ -113,13 +114,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error { } } else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object if b, err = json.Marshal(bts); err != nil { - return fmt.Errorf("expected no marshal error, got error: %v", err) + return errors.Wrap(err, "expected no marshal error, got error") } if err := json.Unmarshal(b, newbts); err != nil { - return fmt.Errorf("expected no unmarshal error, got error: %v", err) + return errors.Wrap(err, "expected no unmarshal error, got error") } if !reflect.DeepEqual(bts, newbts) { - return fmt.Errorf( + return errors.Errorf( "expected object: %v\n\t actual: %v", bts, newbts, diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go index 813d1f65b6360..bb1ac51eba2a2 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go @@ -17,8 +17,10 @@ limitations under the License. package v1alpha3 import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" + "k8s.io/kubernetes/cmd/kubeadm/app/constants" ) func Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConfiguration, out *kubeadm.JoinConfiguration, s conversion.Scope) error { @@ -40,10 +42,12 @@ func Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinCon } } else { out.Discovery.BootstrapToken = &kubeadm.BootstrapTokenDiscovery{ - APIServerEndpoints: in.DiscoveryTokenAPIServers, CACertHashes: in.DiscoveryTokenCACertHashes, UnsafeSkipCAVerification: in.DiscoveryTokenUnsafeSkipCAVerification, } + if len(in.DiscoveryTokenAPIServers) != 0 { + out.Discovery.BootstrapToken.APIServerEndpoint = in.DiscoveryTokenAPIServers[0] + } if len(in.DiscoveryToken) != 0 { out.Discovery.BootstrapToken.Token = in.DiscoveryToken } else { @@ -64,7 +68,7 @@ func Convert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration(in *kubeadm if in.Discovery.BootstrapToken != nil { out.DiscoveryToken = in.Discovery.BootstrapToken.Token - out.DiscoveryTokenAPIServers = in.Discovery.BootstrapToken.APIServerEndpoints + out.DiscoveryTokenAPIServers = []string{in.Discovery.BootstrapToken.APIServerEndpoint} out.DiscoveryTokenCACertHashes = in.Discovery.BootstrapToken.CACertHashes out.DiscoveryTokenUnsafeSkipCAVerification = in.Discovery.BootstrapToken.UnsafeSkipCAVerification @@ -74,3 +78,100 @@ func Convert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration(in *kubeadm return nil } + +func Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *ClusterConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error { + if err := autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in, out, s); err != nil { + return err + } + + out.APIServer.ExtraArgs = in.APIServerExtraArgs + out.APIServer.CertSANs = in.APIServerCertSANs + out.APIServer.TimeoutForControlPlane = &metav1.Duration{ + Duration: constants.DefaultControlPlaneTimeout, + } + if err := convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&in.APIServerExtraVolumes, &out.APIServer.ExtraVolumes, s); err != nil { + return err + } + + out.ControllerManager.ExtraArgs = in.ControllerManagerExtraArgs + if err := convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&in.ControllerManagerExtraVolumes, &out.ControllerManager.ExtraVolumes, s); err != nil { + return err + } + + out.Scheduler.ExtraArgs = in.SchedulerExtraArgs + if err := convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&in.SchedulerExtraVolumes, &out.Scheduler.ExtraVolumes, s); err != nil { + return err + } + + return nil +} + +func Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *kubeadm.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error { + if err := autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in, out, s); err != nil { + return err + } + + out.APIServerExtraArgs = in.APIServer.ExtraArgs + out.APIServerCertSANs = in.APIServer.CertSANs + if err := convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(&in.APIServer.ExtraVolumes, &out.APIServerExtraVolumes, s); err != nil { + return err + } + + out.ControllerManagerExtraArgs = in.ControllerManager.ExtraArgs + if err := convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(&in.ControllerManager.ExtraVolumes, &out.ControllerManagerExtraVolumes, s); err != nil { + return err + } + + out.SchedulerExtraArgs = in.Scheduler.ExtraArgs + if err := convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(&in.Scheduler.ExtraVolumes, &out.SchedulerExtraVolumes, s); err != nil { + return err + } + + return nil +} + +func Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMount, out *kubeadm.HostPathMount, s conversion.Scope) error { + if err := autoConvert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in, out, s); err != nil { + return err + } + + out.ReadOnly = !in.Writable + return nil +} + +func Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error { + if err := autoConvert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in, out, s); err != nil { + return err + } + + out.Writable = !in.ReadOnly + return nil +} + +func convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in *[]HostPathMount, out *[]kubeadm.HostPathMount, s conversion.Scope) error { + if *in != nil { + *out = make([]kubeadm.HostPathMount, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + *out = nil + } + return nil +} + +func convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *[]kubeadm.HostPathMount, out *[]HostPathMount, s conversion.Scope) error { + if *in != nil { + *out = make([]HostPathMount, len(*in)) + for i := range *in { + if err := Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + *out = nil + } + return nil +} diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults_unix.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults_unix.go index 8a8962872fd53..7e60d20b080ff 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults_unix.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults_unix.go @@ -21,7 +21,7 @@ package v1alpha3 const ( // DefaultCACertPath defines default location of CA certificate on Linux DefaultCACertPath = "/etc/kubernetes/pki/ca.crt" - // DefaultSocketUrlScheme defines default socket url prefix + // DefaultUrlScheme defines default socket url prefix DefaultUrlScheme = "unix" // DefaultCRISocket defines the default cri socket DefaultCRISocket = "/var/run/dockershim.sock" diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults_windows.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults_windows.go index d5cc345403edb..fa68cf94c51b2 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults_windows.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults_windows.go @@ -21,7 +21,7 @@ package v1alpha3 const ( // DefaultCACertPath defines default location of CA certificate on Windows DefaultCACertPath = "C:/etc/kubernetes/pki/ca.crt" - // DefaultSocketUrlScheme defines default socket url prefix + // DefaultUrlScheme defines default socket url prefix DefaultUrlScheme = "tcp" // DefaultCRISocket defines the default cri socket DefaultCRISocket = "tcp://localhost:2375" diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go index b603541c31773..2aad6f6ac03e8 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go @@ -177,11 +177,31 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*kubeadm.ClusterConfiguration)(nil), (*ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(a.(*kubeadm.ClusterConfiguration), b.(*ClusterConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*kubeadm.HostPathMount)(nil), (*HostPathMount)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(a.(*kubeadm.HostPathMount), b.(*HostPathMount), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*kubeadm.JoinConfiguration)(nil), (*JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration(a.(*kubeadm.JoinConfiguration), b.(*JoinConfiguration), scope) }); err != nil { return err } + if err := s.AddConversionFunc((*ClusterConfiguration)(nil), (*kubeadm.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(a.(*ClusterConfiguration), b.(*kubeadm.ClusterConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*HostPathMount)(nil), (*kubeadm.HostPathMount)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(a.(*HostPathMount), b.(*kubeadm.HostPathMount), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*JoinConfiguration)(nil), (*kubeadm.JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(a.(*JoinConfiguration), b.(*kubeadm.JoinConfiguration), scope) }); err != nil { @@ -297,13 +317,13 @@ func autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(i } out.KubernetesVersion = in.KubernetesVersion out.ControlPlaneEndpoint = in.ControlPlaneEndpoint - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + // WARNING: in.APIServerExtraArgs requires manual conversion: does not exist in peer-type + // WARNING: in.ControllerManagerExtraArgs requires manual conversion: does not exist in peer-type + // WARNING: in.SchedulerExtraArgs requires manual conversion: does not exist in peer-type + // WARNING: in.APIServerExtraVolumes requires manual conversion: does not exist in peer-type + // WARNING: in.ControllerManagerExtraVolumes requires manual conversion: does not exist in peer-type + // WARNING: in.SchedulerExtraVolumes requires manual conversion: does not exist in peer-type + // WARNING: in.APIServerCertSANs requires manual conversion: does not exist in peer-type out.CertificatesDir = in.CertificatesDir out.ImageRepository = in.ImageRepository out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage @@ -315,11 +335,6 @@ func autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(i return nil } -// Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration is an autogenerated conversion function. -func Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *ClusterConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error { - return autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in, out, s) -} - func autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *kubeadm.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error { // INFO: in.ComponentConfigs opted out of conversion generation if err := Convert_kubeadm_Etcd_To_v1alpha3_Etcd(&in.Etcd, &out.Etcd, s); err != nil { @@ -330,13 +345,9 @@ func autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(i } out.KubernetesVersion = in.KubernetesVersion out.ControlPlaneEndpoint = in.ControlPlaneEndpoint - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + // WARNING: in.APIServer requires manual conversion: does not exist in peer-type + // WARNING: in.ControllerManager requires manual conversion: does not exist in peer-type + // WARNING: in.Scheduler requires manual conversion: does not exist in peer-type out.CertificatesDir = in.CertificatesDir out.ImageRepository = in.ImageRepository // INFO: in.CIImageRepository opted out of conversion generation @@ -349,11 +360,6 @@ func autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(i return nil } -// Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration is an autogenerated conversion function. -func Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *kubeadm.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error { - return autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in, out, s) -} - func autoConvert_v1alpha3_ClusterStatus_To_kubeadm_ClusterStatus(in *ClusterStatus, out *kubeadm.ClusterStatus, s conversion.Scope) error { out.APIEndpoints = *(*map[string]kubeadm.APIEndpoint)(unsafe.Pointer(&in.APIEndpoints)) return nil @@ -426,30 +432,20 @@ func autoConvert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMou out.Name = in.Name out.HostPath = in.HostPath out.MountPath = in.MountPath - out.Writable = in.Writable + // WARNING: in.Writable requires manual conversion: does not exist in peer-type out.PathType = corev1.HostPathType(in.PathType) return nil } -// Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount is an autogenerated conversion function. -func Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMount, out *kubeadm.HostPathMount, s conversion.Scope) error { - return autoConvert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in, out, s) -} - func autoConvert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error { out.Name = in.Name out.HostPath = in.HostPath out.MountPath = in.MountPath - out.Writable = in.Writable + // WARNING: in.ReadOnly requires manual conversion: does not exist in peer-type out.PathType = corev1.HostPathType(in.PathType) return nil } -// Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount is an autogenerated conversion function. -func Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error { - return autoConvert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in, out, s) -} - func autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { if err := Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil { return err diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/BUILD b/cmd/kubeadm/app/apis/kubeadm/v1beta1/BUILD index 3f356ac07fe3b..667f9e4abaefb 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/BUILD +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/BUILD @@ -26,6 +26,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -33,6 +34,7 @@ go_test( name = "go_default_test", srcs = ["bootstraptokenstring_test.go"], embed = [":go_default_library"], + deps = ["//vendor/github.com/pkg/errors:go_default_library"], ) filegroup( diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/bootstraptokenstring.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/bootstraptokenstring.go index d9d1ed27c5cd8..45817a8705f8a 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/bootstraptokenstring.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/bootstraptokenstring.go @@ -20,6 +20,8 @@ import ( "fmt" "strings" + "github.com/pkg/errors" + bootstrapapi "k8s.io/cluster-bootstrap/token/api" bootstraputil "k8s.io/cluster-bootstrap/token/util" ) @@ -73,7 +75,7 @@ func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) { substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token) // TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works) if len(substrs) != 3 { - return nil, fmt.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern) + return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern) } return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/bootstraptokenstring_test.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/bootstraptokenstring_test.go index a9460e19dd93e..ed19f900a8bf0 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/bootstraptokenstring_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/bootstraptokenstring_test.go @@ -18,9 +18,10 @@ package v1beta1 import ( "encoding/json" - "fmt" "reflect" "testing" + + "github.com/pkg/errors" ) func TestMarshalJSON(t *testing.T) { @@ -99,13 +100,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error { // If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string if len(input) > 0 { if err := json.Unmarshal([]byte(input), newbts); err != nil { - return fmt.Errorf("expected no unmarshal error, got error: %v", err) + return errors.Wrap(err, "expected no unmarshal error, got error") } if b, err = json.Marshal(newbts); err != nil { - return fmt.Errorf("expected no marshal error, got error: %v", err) + return errors.Wrap(err, "expected no marshal error, got error") } if input != string(b) { - return fmt.Errorf( + return errors.Errorf( "expected token: %s\n\t actual: %s", input, string(b), @@ -113,13 +114,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error { } } else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object if b, err = json.Marshal(bts); err != nil { - return fmt.Errorf("expected no marshal error, got error: %v", err) + return errors.Wrap(err, "expected no marshal error, got error") } if err := json.Unmarshal(b, newbts); err != nil { - return fmt.Errorf("expected no unmarshal error, got error: %v", err) + return errors.Wrap(err, "expected no unmarshal error, got error") } if !reflect.DeepEqual(bts, newbts) { - return fmt.Errorf( + return errors.Errorf( "expected object: %v\n\t actual: %v", bts, newbts, diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults.go index 68564fa772056..aa56a0cfebcb9 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults.go @@ -101,6 +101,16 @@ func SetDefaults_ClusterConfiguration(obj *ClusterConfiguration) { SetDefaults_Etcd(obj) SetDefaults_AuditPolicyConfiguration(obj) + SetDefaults_APIServer(&obj.APIServer) +} + +// SetDefaults_APIServer assigns default values for the API Server +func SetDefaults_APIServer(obj *APIServer) { + if obj.TimeoutForControlPlane == nil { + obj.TimeoutForControlPlane = &metav1.Duration{ + Duration: constants.DefaultControlPlaneTimeout, + } + } } // SetDefaults_Etcd assigns default values for the Proxy diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults_unix.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults_unix.go index 1c0161bffc68a..f4a50f9972366 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults_unix.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults_unix.go @@ -21,7 +21,7 @@ package v1beta1 const ( // DefaultCACertPath defines default location of CA certificate on Linux DefaultCACertPath = "/etc/kubernetes/pki/ca.crt" - // DefaultSocketUrlScheme defines default socket url prefix + // DefaultUrlScheme defines default socket url prefix DefaultUrlScheme = "unix" // DefaultCRISocket defines the default cri socket DefaultCRISocket = "/var/run/dockershim.sock" diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults_windows.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults_windows.go index 8261f2e89190b..13b1d88ffc1c8 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults_windows.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/defaults_windows.go @@ -21,7 +21,7 @@ package v1beta1 const ( // DefaultCACertPath defines default location of CA certificate on Windows DefaultCACertPath = "C:/etc/kubernetes/pki/ca.crt" - // DefaultSocketUrlScheme defines default socket url prefix + // DefaultUrlScheme defines default socket url prefix DefaultUrlScheme = "tcp" // DefaultCRISocket defines the default cri socket DefaultCRISocket = "tcp://localhost:2375" diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/doc.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/doc.go index 4c3179424d48e..e9c3843d93c9a 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/doc.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/doc.go @@ -200,44 +200,48 @@ limitations under the License. // dnsDomain: "cluster.local" // kubernetesVersion: "v1.12.0" // controlPlaneEndpoint: "10.100.0.1:6443" -// apiServerExtraArgs: -// authorization-mode: "Node,RBAC" -// controllerManagerExtraArgs: -// node-cidr-mask-size: 20 -// schedulerExtraArgs: -// address: "10.100.0.1" -// apiServerExtraVolumes: -// - name: "some-volume" -// hostPath: "/etc/some-path" -// mountPath: "/etc/some-pod-path" -// writable: true -// pathType: File -// controllerManagerExtraVolumes: -// - name: "some-volume" -// hostPath: "/etc/some-path" -// mountPath: "/etc/some-pod-path" -// writable: true -// pathType: File -// schedulerExtraVolumes: -// - name: "some-volume" -// hostPath: "/etc/some-path" -// mountPath: "/etc/some-pod-path" -// writable: true -// pathType: File -// apiServerCertSANs: -// - "10.100.1.1" -// - "ec2-10-100-0-1.compute-1.amazonaws.com" -// certificatesDir: "/etc/kubernetes/pki" -// imageRepository: "k8s.gcr.io" -// unifiedControlPlaneImage: "k8s.gcr.io/controlplane:v1.12.0" -// auditPolicy: -// # https://kubernetes.io/docs/tasks/debug-application-cluster/audit/#audit-policy -// path: "/var/log/audit/audit.json" -// logDir: "/var/log/audit" -// logMaxAge: 7 # in days -// featureGates: -// selfhosting: false -// clusterName: "example-cluster" +// apiServer: +// extraArgs: +// authorization-mode: "Node,RBAC" +// extraVolumes: +// - name: "some-volume" +// hostPath: "/etc/some-path" +// mountPath: "/etc/some-pod-path" +// readOnly: false +// pathType: File +// certSANs: +// - "10.100.1.1" +// - "ec2-10-100-0-1.compute-1.amazonaws.com" +// timeoutForControlPlane: 4m0s +// controllerManager: +// extraArgs: +// node-cidr-mask-size: 20 +// extraVolumes: +// - name: "some-volume" +// hostPath: "/etc/some-path" +// mountPath: "/etc/some-pod-path" +// readOnly: false +// pathType: File +// scheduler: +// extraArgs: +// address: "10.100.0.1" +// extraVolumes: +// - name: "some-volume" +// hostPath: "/etc/some-path" +// mountPath: "/etc/some-pod-path" +// readOnly: false +// pathType: File +// certificatesDir: "/etc/kubernetes/pki" +// imageRepository: "k8s.gcr.io" +// unifiedControlPlaneImage: "k8s.gcr.io/controlplane:v1.12.0" +// auditPolicy: +// # https://kubernetes.io/docs/tasks/debug-application-cluster/audit/#audit-policy +// path: "/var/log/audit/audit.json" +// logDir: "/var/log/audit" +// logMaxAge: 7 # in days +// featureGates: +// selfhosting: false +// clusterName: "example-cluster" // // Kubeadm join configuration types // diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/types.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/types.go index 4c25842f44a37..0dd69c61c7795 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/types.go @@ -77,32 +77,15 @@ type ClusterConfiguration struct { // could be used for assigning a stable DNS to the control plane. ControlPlaneEndpoint string `json:"controlPlaneEndpoint"` - // APIServerExtraArgs is a set of extra flags to pass to the API Server or override - // default ones in form of =. - // TODO: This is temporary and ideally we would like to switch all components to - // use ComponentConfig + ConfigMaps. - APIServerExtraArgs map[string]string `json:"apiServerExtraArgs,omitempty"` - // ControllerManagerExtraArgs is a set of extra flags to pass to the Controller Manager - // or override default ones in form of = - // TODO: This is temporary and ideally we would like to switch all components to - // use ComponentConfig + ConfigMaps. - ControllerManagerExtraArgs map[string]string `json:"controllerManagerExtraArgs,omitempty"` - // SchedulerExtraArgs is a set of extra flags to pass to the Scheduler or override - // default ones in form of = - // TODO: This is temporary and ideally we would like to switch all components to - // use ComponentConfig + ConfigMaps. - SchedulerExtraArgs map[string]string `json:"schedulerExtraArgs,omitempty"` - - // APIServerExtraVolumes is an extra set of host volumes mounted to the API server. - APIServerExtraVolumes []HostPathMount `json:"apiServerExtraVolumes,omitempty"` - // ControllerManagerExtraVolumes is an extra set of host volumes mounted to the - // Controller Manager. - ControllerManagerExtraVolumes []HostPathMount `json:"controllerManagerExtraVolumes,omitempty"` - // SchedulerExtraVolumes is an extra set of host volumes mounted to the scheduler. - SchedulerExtraVolumes []HostPathMount `json:"schedulerExtraVolumes,omitempty"` - - // APIServerCertSANs sets extra Subject Alternative Names for the API Server signing cert. - APIServerCertSANs []string `json:"apiServerCertSANs,omitempty"` + // APIServer contains extra settings for the API server control plane component + APIServer APIServer `json:"apiServer,omitempty"` + + // ControllerManager contains extra settings for the controller manager control plane component + ControllerManager ControlPlaneComponent `json:"controllerManager,omitempty"` + + // Scheduler contains extra settings for the scheduler control plane component + Scheduler ControlPlaneComponent `json:"scheduler,omitempty"` + // CertificatesDir specifies where to store or look for all required certificates. CertificatesDir string `json:"certificatesDir"` @@ -122,6 +105,26 @@ type ClusterConfiguration struct { ClusterName string `json:"clusterName,omitempty"` } +// ControlPlaneComponent holds settings common to control plane component of the cluster +type ControlPlaneComponent struct { + // ExtraArgs is an extra set of flags to pass to the control plane component. + ExtraArgs map[string]string `json:"extraArgs,omitempty"` + + // ExtraVolumes is an extra set of host volumes, mounted to the control plane component. + ExtraVolumes []HostPathMount `json:"extraVolumes,omitempty"` +} + +// APIServer holds settings necessary for API server deployments in the cluster +type APIServer struct { + ControlPlaneComponent `json:",inline"` + + // CertSANs sets extra Subject Alternative Names for the API Server signing cert. + CertSANs []string `json:"certSANs,omitempty"` + + // TimeoutForControlPlane controls the timeout that we use for API server to appear + TimeoutForControlPlane *metav1.Duration `json:"timeoutForControlPlane,omitempty"` +} + // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ClusterStatus contains the cluster status. The ClusterStatus will be stored in the kubeadm-config @@ -301,10 +304,8 @@ type BootstrapTokenDiscovery struct { // fetched from the master. Token string `json:"token"` - // APIServerEndpoints is a set of IPs or domain names to API servers from which info - // will be fetched. Currently we only pay attention to one API server but - // hope to support >1 in the future. - APIServerEndpoints []string `json:"apiServerEndpoints,omitempty"` + // APIServerEndpoint is an IP or domain name to the API server from which info will be fetched. + APIServerEndpoint string `json:"apiServerEndpoint,omitempty"` // CACertHashes specifies a set of public key pins to verify // when token-based discovery is used. The root CA found during discovery @@ -338,8 +339,8 @@ type HostPathMount struct { HostPath string `json:"hostPath"` // MountPath is the path inside the pod where hostPath will be mounted. MountPath string `json:"mountPath"` - // Writable controls write access to the volume - Writable bool `json:"writable,omitempty"` + // ReadOnly controls write access to the volume + ReadOnly bool `json:"readOnly,omitempty"` // PathType is the type of the HostPath. PathType v1.HostPathType `json:"pathType,omitempty"` } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.conversion.go index 71ebf82fb539b..7370186920d1f 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.conversion.go @@ -47,6 +47,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*APIServer)(nil), (*kubeadm.APIServer)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_APIServer_To_kubeadm_APIServer(a.(*APIServer), b.(*kubeadm.APIServer), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kubeadm.APIServer)(nil), (*APIServer)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kubeadm_APIServer_To_v1beta1_APIServer(a.(*kubeadm.APIServer), b.(*APIServer), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*AuditPolicyConfiguration)(nil), (*kubeadm.AuditPolicyConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(a.(*AuditPolicyConfiguration), b.(*kubeadm.AuditPolicyConfiguration), scope) }); err != nil { @@ -107,6 +117,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*ControlPlaneComponent)(nil), (*kubeadm.ControlPlaneComponent)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(a.(*ControlPlaneComponent), b.(*kubeadm.ControlPlaneComponent), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kubeadm.ControlPlaneComponent)(nil), (*ControlPlaneComponent)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kubeadm_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(a.(*kubeadm.ControlPlaneComponent), b.(*ControlPlaneComponent), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*Discovery)(nil), (*kubeadm.Discovery)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_Discovery_To_kubeadm_Discovery(a.(*Discovery), b.(*kubeadm.Discovery), scope) }); err != nil { @@ -232,6 +252,34 @@ func Convert_kubeadm_APIEndpoint_To_v1beta1_APIEndpoint(in *kubeadm.APIEndpoint, return autoConvert_kubeadm_APIEndpoint_To_v1beta1_APIEndpoint(in, out, s) } +func autoConvert_v1beta1_APIServer_To_kubeadm_APIServer(in *APIServer, out *kubeadm.APIServer, s conversion.Scope) error { + if err := Convert_v1beta1_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(&in.ControlPlaneComponent, &out.ControlPlaneComponent, s); err != nil { + return err + } + out.CertSANs = *(*[]string)(unsafe.Pointer(&in.CertSANs)) + out.TimeoutForControlPlane = (*v1.Duration)(unsafe.Pointer(in.TimeoutForControlPlane)) + return nil +} + +// Convert_v1beta1_APIServer_To_kubeadm_APIServer is an autogenerated conversion function. +func Convert_v1beta1_APIServer_To_kubeadm_APIServer(in *APIServer, out *kubeadm.APIServer, s conversion.Scope) error { + return autoConvert_v1beta1_APIServer_To_kubeadm_APIServer(in, out, s) +} + +func autoConvert_kubeadm_APIServer_To_v1beta1_APIServer(in *kubeadm.APIServer, out *APIServer, s conversion.Scope) error { + if err := Convert_kubeadm_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(&in.ControlPlaneComponent, &out.ControlPlaneComponent, s); err != nil { + return err + } + out.CertSANs = *(*[]string)(unsafe.Pointer(&in.CertSANs)) + out.TimeoutForControlPlane = (*v1.Duration)(unsafe.Pointer(in.TimeoutForControlPlane)) + return nil +} + +// Convert_kubeadm_APIServer_To_v1beta1_APIServer is an autogenerated conversion function. +func Convert_kubeadm_APIServer_To_v1beta1_APIServer(in *kubeadm.APIServer, out *APIServer, s conversion.Scope) error { + return autoConvert_kubeadm_APIServer_To_v1beta1_APIServer(in, out, s) +} + func autoConvert_v1beta1_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(in *AuditPolicyConfiguration, out *kubeadm.AuditPolicyConfiguration, s conversion.Scope) error { out.Path = in.Path out.LogDir = in.LogDir @@ -288,7 +336,7 @@ func Convert_kubeadm_BootstrapToken_To_v1beta1_BootstrapToken(in *kubeadm.Bootst func autoConvert_v1beta1_BootstrapTokenDiscovery_To_kubeadm_BootstrapTokenDiscovery(in *BootstrapTokenDiscovery, out *kubeadm.BootstrapTokenDiscovery, s conversion.Scope) error { out.Token = in.Token - out.APIServerEndpoints = *(*[]string)(unsafe.Pointer(&in.APIServerEndpoints)) + out.APIServerEndpoint = in.APIServerEndpoint out.CACertHashes = *(*[]string)(unsafe.Pointer(&in.CACertHashes)) out.UnsafeSkipCAVerification = in.UnsafeSkipCAVerification return nil @@ -301,7 +349,7 @@ func Convert_v1beta1_BootstrapTokenDiscovery_To_kubeadm_BootstrapTokenDiscovery( func autoConvert_kubeadm_BootstrapTokenDiscovery_To_v1beta1_BootstrapTokenDiscovery(in *kubeadm.BootstrapTokenDiscovery, out *BootstrapTokenDiscovery, s conversion.Scope) error { out.Token = in.Token - out.APIServerEndpoints = *(*[]string)(unsafe.Pointer(&in.APIServerEndpoints)) + out.APIServerEndpoint = in.APIServerEndpoint out.CACertHashes = *(*[]string)(unsafe.Pointer(&in.CACertHashes)) out.UnsafeSkipCAVerification = in.UnsafeSkipCAVerification return nil @@ -343,13 +391,15 @@ func autoConvert_v1beta1_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in } out.KubernetesVersion = in.KubernetesVersion out.ControlPlaneEndpoint = in.ControlPlaneEndpoint - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + if err := Convert_v1beta1_APIServer_To_kubeadm_APIServer(&in.APIServer, &out.APIServer, s); err != nil { + return err + } + if err := Convert_v1beta1_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(&in.ControllerManager, &out.ControllerManager, s); err != nil { + return err + } + if err := Convert_v1beta1_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(&in.Scheduler, &out.Scheduler, s); err != nil { + return err + } out.CertificatesDir = in.CertificatesDir out.ImageRepository = in.ImageRepository out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage @@ -376,13 +426,15 @@ func autoConvert_kubeadm_ClusterConfiguration_To_v1beta1_ClusterConfiguration(in } out.KubernetesVersion = in.KubernetesVersion out.ControlPlaneEndpoint = in.ControlPlaneEndpoint - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + if err := Convert_kubeadm_APIServer_To_v1beta1_APIServer(&in.APIServer, &out.APIServer, s); err != nil { + return err + } + if err := Convert_kubeadm_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(&in.ControllerManager, &out.ControllerManager, s); err != nil { + return err + } + if err := Convert_kubeadm_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(&in.Scheduler, &out.Scheduler, s); err != nil { + return err + } out.CertificatesDir = in.CertificatesDir out.ImageRepository = in.ImageRepository // INFO: in.CIImageRepository opted out of conversion generation @@ -420,6 +472,28 @@ func Convert_kubeadm_ClusterStatus_To_v1beta1_ClusterStatus(in *kubeadm.ClusterS return autoConvert_kubeadm_ClusterStatus_To_v1beta1_ClusterStatus(in, out, s) } +func autoConvert_v1beta1_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in *ControlPlaneComponent, out *kubeadm.ControlPlaneComponent, s conversion.Scope) error { + out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) + out.ExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ExtraVolumes)) + return nil +} + +// Convert_v1beta1_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent is an autogenerated conversion function. +func Convert_v1beta1_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in *ControlPlaneComponent, out *kubeadm.ControlPlaneComponent, s conversion.Scope) error { + return autoConvert_v1beta1_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in, out, s) +} + +func autoConvert_kubeadm_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(in *kubeadm.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error { + out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) + out.ExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ExtraVolumes)) + return nil +} + +// Convert_kubeadm_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent is an autogenerated conversion function. +func Convert_kubeadm_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(in *kubeadm.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error { + return autoConvert_kubeadm_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(in, out, s) +} + func autoConvert_v1beta1_Discovery_To_kubeadm_Discovery(in *Discovery, out *kubeadm.Discovery, s conversion.Scope) error { out.BootstrapToken = (*kubeadm.BootstrapTokenDiscovery)(unsafe.Pointer(in.BootstrapToken)) out.File = (*kubeadm.FileDiscovery)(unsafe.Pointer(in.File)) @@ -518,7 +592,7 @@ func autoConvert_v1beta1_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMoun out.Name = in.Name out.HostPath = in.HostPath out.MountPath = in.MountPath - out.Writable = in.Writable + out.ReadOnly = in.ReadOnly out.PathType = corev1.HostPathType(in.PathType) return nil } @@ -532,7 +606,7 @@ func autoConvert_kubeadm_HostPathMount_To_v1beta1_HostPathMount(in *kubeadm.Host out.Name = in.Name out.HostPath = in.HostPath out.MountPath = in.MountPath - out.Writable = in.Writable + out.ReadOnly = in.ReadOnly out.PathType = corev1.HostPathType(in.PathType) return nil } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.deepcopy.go index d1075107875a9..72e7e81a440ed 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.deepcopy.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.deepcopy.go @@ -42,6 +42,33 @@ func (in *APIEndpoint) DeepCopy() *APIEndpoint { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServer) DeepCopyInto(out *APIServer) { + *out = *in + in.ControlPlaneComponent.DeepCopyInto(&out.ControlPlaneComponent) + if in.CertSANs != nil { + in, out := &in.CertSANs, &out.CertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.TimeoutForControlPlane != nil { + in, out := &in.TimeoutForControlPlane, &out.TimeoutForControlPlane + *out = new(v1.Duration) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServer. +func (in *APIServer) DeepCopy() *APIServer { + if in == nil { + return nil + } + out := new(APIServer) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuditPolicyConfiguration) DeepCopyInto(out *AuditPolicyConfiguration) { *out = *in @@ -106,11 +133,6 @@ func (in *BootstrapToken) DeepCopy() *BootstrapToken { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BootstrapTokenDiscovery) DeepCopyInto(out *BootstrapTokenDiscovery) { *out = *in - if in.APIServerEndpoints != nil { - in, out := &in.APIServerEndpoints, &out.APIServerEndpoints - *out = make([]string, len(*in)) - copy(*out, *in) - } if in.CACertHashes != nil { in, out := &in.CACertHashes, &out.CACertHashes *out = make([]string, len(*in)) @@ -151,47 +173,9 @@ func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) { out.TypeMeta = in.TypeMeta in.Etcd.DeepCopyInto(&out.Etcd) out.Networking = in.Networking - if in.APIServerExtraArgs != nil { - in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.ControllerManagerExtraArgs != nil { - in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.SchedulerExtraArgs != nil { - in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.APIServerExtraVolumes != nil { - in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.ControllerManagerExtraVolumes != nil { - in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.SchedulerExtraVolumes != nil { - in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.APIServerCertSANs != nil { - in, out := &in.APIServerCertSANs, &out.APIServerCertSANs - *out = make([]string, len(*in)) - copy(*out, *in) - } + in.APIServer.DeepCopyInto(&out.APIServer) + in.ControllerManager.DeepCopyInto(&out.ControllerManager) + in.Scheduler.DeepCopyInto(&out.Scheduler) in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration) if in.FeatureGates != nil { in, out := &in.FeatureGates, &out.FeatureGates @@ -253,6 +237,34 @@ func (in *ClusterStatus) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneComponent) DeepCopyInto(out *ControlPlaneComponent) { + *out = *in + if in.ExtraArgs != nil { + in, out := &in.ExtraArgs, &out.ExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ExtraVolumes != nil { + in, out := &in.ExtraVolumes, &out.ExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneComponent. +func (in *ControlPlaneComponent) DeepCopy() *ControlPlaneComponent { + if in == nil { + return nil + } + out := new(ControlPlaneComponent) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Discovery) DeepCopyInto(out *Discovery) { *out = *in diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.defaults.go index a27612cce03c3..799ffbb7e0958 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.defaults.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta1/zz_generated.defaults.go @@ -37,6 +37,7 @@ func RegisterDefaults(scheme *runtime.Scheme) error { func SetObjectDefaults_ClusterConfiguration(in *ClusterConfiguration) { SetDefaults_ClusterConfiguration(in) + SetDefaults_APIServer(&in.APIServer) } func SetObjectDefaults_ClusterStatus(in *ClusterStatus) { diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/BUILD b/cmd/kubeadm/app/apis/kubeadm/validation/BUILD index 517036bdb89c7..600a2ce38dbac 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/BUILD +++ b/cmd/kubeadm/app/apis/kubeadm/validation/BUILD @@ -19,6 +19,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", ], ) diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go index e6cedff96c033..30bdc7761271d 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go +++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go @@ -25,6 +25,7 @@ import ( "strconv" "strings" + "github.com/pkg/errors" "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/util/sets" @@ -56,7 +57,7 @@ func ValidateInitConfiguration(c *kubeadm.InitConfiguration) field.ErrorList { func ValidateClusterConfiguration(c *kubeadm.ClusterConfiguration) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...) - allErrs = append(allErrs, ValidateCertSANs(c.APIServerCertSANs, field.NewPath("apiServerCertSANs"))...) + allErrs = append(allErrs, ValidateAPIServer(&c.APIServer, field.NewPath("apiServer"))...) allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificatesDir"))...) allErrs = append(allErrs, ValidateFeatureGates(c.FeatureGates, field.NewPath("featureGates"))...) allErrs = append(allErrs, ValidateHostPort(c.ControlPlaneEndpoint, field.NewPath("controlPlaneEndpoint"))...) @@ -65,6 +66,13 @@ func ValidateClusterConfiguration(c *kubeadm.ClusterConfiguration) field.ErrorLi return allErrs } +// ValidateAPIServer validates a APIServer object and collects all encountered errors +func ValidateAPIServer(a *kubeadm.APIServer, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, ValidateCertSANs(a.CertSANs, fldPath.Child("certSANs"))...) + return allErrs +} + // ValidateJoinConfiguration validates node configuration and collects all encountered errors func ValidateJoinConfiguration(c *kubeadm.JoinConfiguration) field.ErrorList { allErrs := field.ErrorList{} @@ -122,13 +130,8 @@ func ValidateDiscovery(d *kubeadm.Discovery, fldPath *field.Path) field.ErrorLis func ValidateDiscoveryBootstrapToken(b *kubeadm.BootstrapTokenDiscovery, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if len(b.APIServerEndpoints) < 1 { - allErrs = append(allErrs, field.Required(fldPath, "APIServerEndpoints not set")) - } - - // TODO remove once we support multiple api servers - if len(b.APIServerEndpoints) > 1 { - fmt.Println("[validation] WARNING: kubeadm doesn't fully support multiple API Servers yet") + if len(b.APIServerEndpoint) == 0 { + allErrs = append(allErrs, field.Required(fldPath, "APIServerEndpoint is not set")) } if len(b.CACertHashes) == 0 && !b.UnsafeSkipCAVerification { @@ -136,7 +139,7 @@ func ValidateDiscoveryBootstrapToken(b *kubeadm.BootstrapTokenDiscovery, fldPath } allErrs = append(allErrs, ValidateToken(b.Token, fldPath.Child("token"))...) - allErrs = append(allErrs, ValidateDiscoveryTokenAPIServer(b.APIServerEndpoints, fldPath.Child("apiServerEndpoints"))...) + allErrs = append(allErrs, ValidateDiscoveryTokenAPIServer(b.APIServerEndpoint, fldPath.Child("apiServerEndpoints"))...) return allErrs } @@ -151,13 +154,11 @@ func ValidateDiscoveryFile(f *kubeadm.FileDiscovery, fldPath *field.Path) field. } // ValidateDiscoveryTokenAPIServer validates discovery token for API server -func ValidateDiscoveryTokenAPIServer(apiServers []string, fldPath *field.Path) field.ErrorList { +func ValidateDiscoveryTokenAPIServer(apiServer string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - for _, m := range apiServers { - _, _, err := net.SplitHostPort(m) - if err != nil { - allErrs = append(allErrs, field.Invalid(fldPath, m, err.Error())) - } + _, _, err := net.SplitHostPort(apiServer) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath, apiServer, err.Error())) } return allErrs } @@ -398,7 +399,7 @@ func ValidateMixedArguments(flag *pflag.FlagSet) error { }) if len(mixedInvalidFlags) != 0 { - return fmt.Errorf("can not mix '--config' with arguments %v", mixedInvalidFlags) + return errors.Errorf("can not mix '--config' with arguments %v", mixedInvalidFlags) } return nil } diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go index f955f0514a9ca..14d98eb42abc7 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go @@ -692,7 +692,7 @@ func TestValidateDiscoveryBootstrapToken(t *testing.T) { expected bool }{ { - "invalid: .APIServerEndpoints not set", + "invalid: .APIServerEndpoint not set", &kubeadm.BootstrapTokenDiscovery{ Token: "abcdef.1234567890123456", }, @@ -702,25 +702,16 @@ func TestValidateDiscoveryBootstrapToken(t *testing.T) { "invalid: using token-based discovery without .BootstrapToken.CACertHashes and .BootstrapToken.UnsafeSkipCAVerification", &kubeadm.BootstrapTokenDiscovery{ Token: "abcdef.1234567890123456", - APIServerEndpoints: []string{"192.168.122.100:6443"}, + APIServerEndpoint: "192.168.122.100:6443", UnsafeSkipCAVerification: false, }, false, }, - { - "WARNING: kubeadm doesn't fully support multiple API Servers yet", - &kubeadm.BootstrapTokenDiscovery{ - Token: "abcdef.1234567890123456", - APIServerEndpoints: []string{"192.168.122.100:6443", "192.168.122.88:6443"}, - UnsafeSkipCAVerification: true, - }, - true, - }, { "valid: using token-based discovery with .BootstrapToken.CACertHashes", &kubeadm.BootstrapTokenDiscovery{ Token: "abcdef.1234567890123456", - APIServerEndpoints: []string{"192.168.122.100:6443"}, + APIServerEndpoint: "192.168.122.100:6443", CACertHashes: []string{"sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc"}, UnsafeSkipCAVerification: false, }, @@ -730,7 +721,7 @@ func TestValidateDiscoveryBootstrapToken(t *testing.T) { "valid: using token-based discovery with .BootstrapToken.CACertHashe but skip ca verification", &kubeadm.BootstrapTokenDiscovery{ Token: "abcdef.1234567890123456", - APIServerEndpoints: []string{"192.168.122.100:6443"}, + APIServerEndpoint: "192.168.122.100:6443", CACertHashes: []string{"sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc"}, UnsafeSkipCAVerification: true, }, @@ -753,20 +744,20 @@ func TestValidateDiscoveryBootstrapToken(t *testing.T) { func TestValidateDiscoveryTokenAPIServer(t *testing.T) { var tests = []struct { - apiServerEndpoints []string - expected bool + apiServerEndpoint string + expected bool }{ { - []string{"192.168.122.100"}, + "192.168.122.100", false, }, { - []string{"192.168.122.100:6443"}, + "192.168.122.100:6443", true, }, } for _, rt := range tests { - actual := ValidateDiscoveryTokenAPIServer(rt.apiServerEndpoints, nil) + actual := ValidateDiscoveryTokenAPIServer(rt.apiServerEndpoint, nil) if (len(actual) == 0) != rt.expected { t.Errorf( "failed ValidateDiscoveryTokenAPIServer:\n\texpected: %t\n\t actual: %t", diff --git a/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go index 1de5d51da7289..89a0ed5709b18 100644 --- a/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go +++ b/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go @@ -44,6 +44,33 @@ func (in *APIEndpoint) DeepCopy() *APIEndpoint { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServer) DeepCopyInto(out *APIServer) { + *out = *in + in.ControlPlaneComponent.DeepCopyInto(&out.ControlPlaneComponent) + if in.CertSANs != nil { + in, out := &in.CertSANs, &out.CertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.TimeoutForControlPlane != nil { + in, out := &in.TimeoutForControlPlane, &out.TimeoutForControlPlane + *out = new(v1.Duration) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServer. +func (in *APIServer) DeepCopy() *APIServer { + if in == nil { + return nil + } + out := new(APIServer) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuditPolicyConfiguration) DeepCopyInto(out *AuditPolicyConfiguration) { *out = *in @@ -108,11 +135,6 @@ func (in *BootstrapToken) DeepCopy() *BootstrapToken { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BootstrapTokenDiscovery) DeepCopyInto(out *BootstrapTokenDiscovery) { *out = *in - if in.APIServerEndpoints != nil { - in, out := &in.APIServerEndpoints, &out.APIServerEndpoints - *out = make([]string, len(*in)) - copy(*out, *in) - } if in.CACertHashes != nil { in, out := &in.CACertHashes, &out.CACertHashes *out = make([]string, len(*in)) @@ -154,47 +176,9 @@ func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) { in.ComponentConfigs.DeepCopyInto(&out.ComponentConfigs) in.Etcd.DeepCopyInto(&out.Etcd) out.Networking = in.Networking - if in.APIServerExtraArgs != nil { - in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.ControllerManagerExtraArgs != nil { - in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.SchedulerExtraArgs != nil { - in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.APIServerExtraVolumes != nil { - in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.ControllerManagerExtraVolumes != nil { - in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.SchedulerExtraVolumes != nil { - in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.APIServerCertSANs != nil { - in, out := &in.APIServerCertSANs, &out.APIServerCertSANs - *out = make([]string, len(*in)) - copy(*out, *in) - } + in.APIServer.DeepCopyInto(&out.APIServer) + in.ControllerManager.DeepCopyInto(&out.ControllerManager) + in.Scheduler.DeepCopyInto(&out.Scheduler) in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration) if in.FeatureGates != nil { in, out := &in.FeatureGates, &out.FeatureGates @@ -282,6 +266,34 @@ func (in *ComponentConfigs) DeepCopy() *ComponentConfigs { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneComponent) DeepCopyInto(out *ControlPlaneComponent) { + *out = *in + if in.ExtraArgs != nil { + in, out := &in.ExtraArgs, &out.ExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ExtraVolumes != nil { + in, out := &in.ExtraVolumes, &out.ExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneComponent. +func (in *ControlPlaneComponent) DeepCopy() *ControlPlaneComponent { + if in == nil { + return nil + } + out := new(ControlPlaneComponent) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Discovery) DeepCopyInto(out *Discovery) { *out = *in diff --git a/cmd/kubeadm/app/cmd/BUILD b/cmd/kubeadm/app/cmd/BUILD index 6127f5fc159bc..7d881c39d42a3 100644 --- a/cmd/kubeadm/app/cmd/BUILD +++ b/cmd/kubeadm/app/cmd/BUILD @@ -25,6 +25,7 @@ go_library( "//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library", + "//cmd/kubeadm/app/cmd/alpha:go_default_library", "//cmd/kubeadm/app/cmd/options:go_default_library", "//cmd/kubeadm/app/cmd/phases:go_default_library", "//cmd/kubeadm/app/cmd/phases/workflow:go_default_library", @@ -51,11 +52,10 @@ go_library( "//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library", - "//cmd/kubeadm/app/util/audit:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", - "//cmd/kubeadm/app/util/dryrun:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library", "//cmd/kubeadm/app/util/runtime:go_default_library", + "//cmd/kubeadm/app/util/staticpod:go_default_library", "//pkg/util/initsystem:go_default_library", "//pkg/version:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", @@ -102,6 +102,7 @@ go_test( "//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", "//cmd/kubeadm/app/util/runtime:go_default_library", + "//cmd/kubeadm/test:go_default_library", "//staging/src/k8s.io/api/core/v1: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", @@ -109,8 +110,8 @@ go_test( "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", - "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//vendor/github.com/ghodss/yaml:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/renstrom/dedent:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", @@ -129,6 +130,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//cmd/kubeadm/app/cmd/alpha:all-srcs", "//cmd/kubeadm/app/cmd/options:all-srcs", "//cmd/kubeadm/app/cmd/phases:all-srcs", "//cmd/kubeadm/app/cmd/upgrade:all-srcs", diff --git a/cmd/kubeadm/app/cmd/phases/certs/BUILD b/cmd/kubeadm/app/cmd/alpha/BUILD similarity index 61% rename from cmd/kubeadm/app/cmd/phases/certs/BUILD rename to cmd/kubeadm/app/cmd/alpha/BUILD index 3f1ba58371e2d..49f1f7d7d48c1 100644 --- a/cmd/kubeadm/app/cmd/phases/certs/BUILD +++ b/cmd/kubeadm/app/cmd/alpha/BUILD @@ -2,36 +2,36 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", - srcs = ["renew.go"], - importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/certs", + srcs = [ + "alpha.go", + "certs.go", + "kubeconfig.go", + "kubelet.go", + "preflight.go", + ], + importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/alpha", visibility = ["//visibility:public"], deps = [ "//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", + "//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library", "//cmd/kubeadm/app/cmd/options:go_default_library", + "//cmd/kubeadm/app/cmd/phases:go_default_library", "//cmd/kubeadm/app/cmd/util:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/phases/certs:go_default_library", "//cmd/kubeadm/app/phases/certs/renewal:go_default_library", + "//cmd/kubeadm/app/phases/kubeconfig:go_default_library", + "//cmd/kubeadm/app/phases/kubelet:go_default_library", + "//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library", "//pkg/util/normalizer:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", - ], -) - -go_test( - name = "go_default_test", - srcs = ["renewal_test.go"], - embed = [":go_default_library"], - deps = [ - "//cmd/kubeadm/app/constants:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", - "//cmd/kubeadm/test:go_default_library", - "//cmd/kubeadm/test/certs:go_default_library", - "//cmd/kubeadm/test/cmd:go_default_library", - "//vendor/github.com/spf13/cobra:go_default_library", + "//vendor/k8s.io/utils/exec:go_default_library", ], ) @@ -48,3 +48,22 @@ filegroup( tags = ["automanaged"], visibility = ["//visibility:public"], ) + +go_test( + name = "go_default_test", + srcs = [ + "certs_test.go", + "kubeconfig_test.go", + ], + embed = [":go_default_library"], + deps = [ + "//cmd/kubeadm/app/constants:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", + "//cmd/kubeadm/test:go_default_library", + "//cmd/kubeadm/test/certs:go_default_library", + "//cmd/kubeadm/test/cmd:go_default_library", + "//cmd/kubeadm/test/kubeconfig:go_default_library", + "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", + "//vendor/github.com/spf13/cobra:go_default_library", + ], +) diff --git a/cmd/kubeadm/app/cmd/alpha/alpha.go b/cmd/kubeadm/app/cmd/alpha/alpha.go new file mode 100644 index 0000000000000..b3ca7c2816979 --- /dev/null +++ b/cmd/kubeadm/app/cmd/alpha/alpha.go @@ -0,0 +1,60 @@ +/* +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 alpha + +import ( + "io" + + "github.com/spf13/cobra" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases" + cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" +) + +// NewCmdAlpha returns "kubeadm alpha" command. +func NewCmdAlpha(out io.Writer) *cobra.Command { + cmd := &cobra.Command{ + Use: "alpha", + Short: "Kubeadm experimental sub-commands", + } + + cmd.AddCommand(newCmdCertsUtility()) + cmd.AddCommand(newCmdKubeletUtility()) + cmd.AddCommand(newCmdKubeConfigUtility(out)) + cmd.AddCommand(newCmdPreFlightUtility()) + + // TODO: This command should be removed as soon as the kubeadm init phase refactoring is completed. + // current phases implemented as cobra.Commands should become workflow.Phases, while other utilities + // hosted under kubeadm alpha phases command should found a new home under kubeadm alpha (without phases) + cmd.AddCommand(newCmdPhase(out)) + + return cmd +} + +func newCmdPhase(out io.Writer) *cobra.Command { + cmd := &cobra.Command{ + Use: "phase", + Short: "Invoke subsets of kubeadm functions separately for a manual install", + Long: cmdutil.MacroCommandLongDescription, + } + + cmd.AddCommand(phases.NewCmdAddon()) + cmd.AddCommand(phases.NewCmdBootstrapToken()) + cmd.AddCommand(phases.NewCmdMarkMaster()) + cmd.AddCommand(phases.NewCmdSelfhosting()) + + return cmd +} diff --git a/cmd/kubeadm/app/cmd/phases/certs/renew.go b/cmd/kubeadm/app/cmd/alpha/certs.go similarity index 69% rename from cmd/kubeadm/app/cmd/phases/certs/renew.go rename to cmd/kubeadm/app/cmd/alpha/certs.go index 16c43781c3fb1..320a21e99338b 100644 --- a/cmd/kubeadm/app/cmd/phases/certs/renew.go +++ b/cmd/kubeadm/app/cmd/alpha/certs.go @@ -14,13 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package renew +package alpha import ( "fmt" "github.com/spf13/cobra" - kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" @@ -46,8 +45,20 @@ var ( `) ) -// NewCmdCertsRenewal creates a new `cert renew` command. -func NewCmdCertsRenewal() *cobra.Command { +// newCmdCertsUtility returns main command for certs phase +func newCmdCertsUtility() *cobra.Command { + cmd := &cobra.Command{ + Use: "certs", + Aliases: []string{"certificates"}, + Short: "Commands related to handling kubernetes certificates", + } + + cmd.AddCommand(newCmdCertsRenewal()) + return cmd +} + +// newCmdCertsRenewal creates a new `cert renew` command. +func newCmdCertsRenewal() *cobra.Command { cmd := &cobra.Command{ Use: "renew", Short: "Renews certificates for a Kubernetes cluster", @@ -78,14 +89,20 @@ func getRenewSubCommands() []*cobra.Command { kubeadmutil.CheckErr(err) cmdList := []*cobra.Command{} - allCmds := []func() error{} + funcList := []func(){} for caCert, certs := range certTree { // Don't offer to renew CAs; would cause serious consequences for _, cert := range certs { - cmd := makeCommandForRenew(cert, caCert, cfg) + // get the cobra.Command skeleton for this command + cmd := generateRenewalCommand(cert, cfg) + // get the implementation of renewing this certificate + renewalFunc := generateRenewalFunction(cert, caCert, cfg) + // install the implementation into the command + cmd.Run = func(*cobra.Command, []string) { renewalFunc() } cmdList = append(cmdList, cmd) - allCmds = append(allCmds, cmd.Execute) + // Collect renewal functions for `renew all` + funcList = append(funcList, renewalFunc) } } @@ -94,9 +111,8 @@ func getRenewSubCommands() []*cobra.Command { Short: "renew all available certificates", Long: allLongDesc, Run: func(*cobra.Command, []string) { - for _, cmd := range allCmds { - err := cmd() - kubeadmutil.CheckErr(err) + for _, f := range funcList { + f() } }, } @@ -113,28 +129,26 @@ func addFlags(cmd *cobra.Command, cfg *renewConfig) { cmd.Flags().BoolVar(&cfg.useAPI, "use-api", cfg.useAPI, "Use the Kubernetes certificate API to renew certificates") } -// generateCertCommand takes mostly strings instead of structs to avoid using structs in a for loop -func generateCertCommand(name, longName, baseName, caCertBaseName string, cfg *renewConfig) *cobra.Command { - return &cobra.Command{ - Use: name, - Short: fmt.Sprintf("Generates the %s", longName), - Long: fmt.Sprintf(genericLongDesc, longName, baseName), - Run: func(cmd *cobra.Command, args []string) { - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfg.cfgPath, &cfg.cfg) - kubeadmutil.CheckErr(err) - renewer, err := getRenewer(cfg, caCertBaseName) - kubeadmutil.CheckErr(err) - - err = renewal.RenewExistingCert(internalcfg.CertificatesDir, baseName, renewer) - kubeadmutil.CheckErr(err) - }, +func generateRenewalFunction(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert, cfg *renewConfig) func() { + return func() { + internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfg.cfgPath, &cfg.cfg) + kubeadmutil.CheckErr(err) + renewer, err := getRenewer(cfg, caCert.BaseName) + kubeadmutil.CheckErr(err) + + err = renewal.RenewExistingCert(internalcfg.CertificatesDir, cert.BaseName, renewer) + kubeadmutil.CheckErr(err) } } -func makeCommandForRenew(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert, cfg *renewConfig) *cobra.Command { - certCmd := generateCertCommand(cert.Name, cert.LongName, cert.BaseName, caCert.BaseName, cfg) - addFlags(certCmd, cfg) - return certCmd +func generateRenewalCommand(cert *certsphase.KubeadmCert, cfg *renewConfig) *cobra.Command { + cmd := &cobra.Command{ + Use: cert.Name, + Short: fmt.Sprintf("Generates the %s", cert.LongName), + Long: fmt.Sprintf(genericLongDesc, cert.LongName, cert.BaseName), + } + addFlags(cmd, cfg) + return cmd } func getRenewer(cfg *renewConfig, caCertBaseName string) (renewal.Interface, error) { diff --git a/cmd/kubeadm/app/cmd/phases/certs/renewal_test.go b/cmd/kubeadm/app/cmd/alpha/certs_test.go similarity index 98% rename from cmd/kubeadm/app/cmd/phases/certs/renewal_test.go rename to cmd/kubeadm/app/cmd/alpha/certs_test.go index 81bc781b3490c..be73d693de383 100644 --- a/cmd/kubeadm/app/cmd/phases/certs/renewal_test.go +++ b/cmd/kubeadm/app/cmd/alpha/certs_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package renew +package alpha import ( "crypto/rand" @@ -29,9 +29,8 @@ import ( "time" "github.com/spf13/cobra" - kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" testutil "k8s.io/kubernetes/cmd/kubeadm/test" certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs" cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd" @@ -58,7 +57,7 @@ func TestCommandsGenerated(t *testing.T) { "renew etcd-healthcheck-client", } - renewCmd := NewCmdCertsRenewal() + renewCmd := newCmdCertsRenewal() fakeRoot := &cobra.Command{} fakeRoot.AddCommand(renewCmd) diff --git a/cmd/kubeadm/app/cmd/alpha/kubeconfig.go b/cmd/kubeadm/app/cmd/alpha/kubeconfig.go new file mode 100644 index 0000000000000..6b1178ee628e5 --- /dev/null +++ b/cmd/kubeadm/app/cmd/alpha/kubeconfig.go @@ -0,0 +1,106 @@ +/* +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 alpha + +import ( + "io" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" + kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" + cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" + kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" + kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" + configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" + "k8s.io/kubernetes/pkg/util/normalizer" +) + +var ( + kubeconfigLongDesc = normalizer.LongDesc(` + Kubeconfig file utilities. + ` + cmdutil.AlphaDisclaimer) + + userKubeconfigLongDesc = normalizer.LongDesc(` + Outputs a kubeconfig file for an additional user. + ` + cmdutil.AlphaDisclaimer) + + userKubeconfigExample = normalizer.Examples(` + # Outputs a kubeconfig file for an additional user named foo + kubeadm alpha kubeconfig user --client-name=foo + `) +) + +// newCmdKubeConfigUtility returns main command for kubeconfig phase +func newCmdKubeConfigUtility(out io.Writer) *cobra.Command { + cmd := &cobra.Command{ + Use: "kubeconfig", + Short: "Kubeconfig file utilities", + Long: kubeconfigLongDesc, + } + + cmd.AddCommand(newCmdUserKubeConfig(out)) + return cmd +} + +// newCmdUserKubeConfig returns sub commands for kubeconfig phase +func newCmdUserKubeConfig(out io.Writer) *cobra.Command { + + cfg := &kubeadmapiv1beta1.InitConfiguration{} + + // Default values for the cobra help text + kubeadmscheme.Scheme.Default(cfg) + + var token, clientName string + var organizations []string + + // Creates the UX Command + cmd := &cobra.Command{ + Use: "user", + Short: "Outputs a kubeconfig file for an additional user", + Long: userKubeconfigLongDesc, + Example: userKubeconfigExample, + Run: func(cmd *cobra.Command, args []string) { + if clientName == "" { + kubeadmutil.CheckErr(errors.New("missing required argument --client-name")) + } + + // This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags + internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig("", cfg) + kubeadmutil.CheckErr(err) + + // if the kubeconfig file for an additional user has to use a token, use it + if token != "" { + kubeadmutil.CheckErr(kubeconfigphase.WriteKubeConfigWithToken(out, internalcfg, clientName, token)) + return + } + + // Otherwise, write a kubeconfig file with a generate client cert + kubeadmutil.CheckErr(kubeconfigphase.WriteKubeConfigWithClientCert(out, internalcfg, clientName, organizations)) + }, + } + + // Add flags to the command + cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where certificates are stored") + cmd.Flags().StringVar(&cfg.APIEndpoint.AdvertiseAddress, "apiserver-advertise-address", cfg.APIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on") + cmd.Flags().Int32Var(&cfg.APIEndpoint.BindPort, "apiserver-bind-port", cfg.APIEndpoint.BindPort, "The port the API server is accessible on") + cmd.Flags().StringVar(&token, "token", token, "The token that should be used as the authentication mechanism for this kubeconfig, instead of client certificates") + cmd.Flags().StringVar(&clientName, "client-name", clientName, "The name of user. It will be used as the CN if client certificates are created") + cmd.Flags().StringSliceVar(&organizations, "org", organizations, "The orgnizations of the client certificate. It will be used as the O if client certificates are created") + + return cmd +} diff --git a/cmd/kubeadm/app/cmd/alpha/kubeconfig_test.go b/cmd/kubeadm/app/cmd/alpha/kubeconfig_test.go new file mode 100644 index 0000000000000..834edce40859a --- /dev/null +++ b/cmd/kubeadm/app/cmd/alpha/kubeconfig_test.go @@ -0,0 +1,104 @@ +/* +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 alpha + +import ( + "bytes" + "fmt" + "os" + "testing" + + "k8s.io/client-go/tools/clientcmd" + kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" + testutil "k8s.io/kubernetes/cmd/kubeadm/test" + kubeconfigtestutil "k8s.io/kubernetes/cmd/kubeadm/test/kubeconfig" +) + +func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) { + + // Temporary folders for the test case + tmpdir := testutil.SetupTempDir(t) + defer os.RemoveAll(tmpdir) + + // Adds a pki folder with a ca cert to the temp folder + pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir) + + // Retrieves ca cert for assertions + caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkidir, kubeadmconstants.CACertAndKeyBaseName) + if err != nil { + t.Fatalf("couldn't retrieve ca cert: %v", err) + } + + commonFlags := []string{ + "--apiserver-advertise-address=1.2.3.4", + "--apiserver-bind-port=1234", + "--client-name=myUser", + fmt.Sprintf("--cert-dir=%s", pkidir), + } + + var tests = []struct { + command string + withClientCert bool + withToken bool + additionalFlags []string + }{ + { // Test user subCommand withClientCert + command: "user", + withClientCert: true, + }, + { // Test user subCommand withToken + withToken: true, + command: "user", + additionalFlags: []string{"--token=123456"}, + }, + } + + for _, test := range tests { + buf := new(bytes.Buffer) + + // Get subcommands working in the temporary directory + cmd := newCmdUserKubeConfig(buf) + + // Execute the subcommand + allFlags := append(commonFlags, test.additionalFlags...) + cmd.SetArgs(allFlags) + if err := cmd.Execute(); err != nil { + t.Fatal("Could not execute subcommand") + } + + // reads kubeconfig written to stdout + config, err := clientcmd.Load(buf.Bytes()) + if err != nil { + t.Errorf("couldn't read kubeconfig file from buffer: %v", err) + continue + } + + // checks that CLI flags are properly propagated + kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert) + + if test.withClientCert { + // checks that kubeconfig files have expected client cert + kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, "myUser") + } + + if test.withToken { + // checks that kubeconfig files have expected token + kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithToken(t, config, "myUser", "123456") + } + } +} diff --git a/cmd/kubeadm/app/cmd/alpha/kubelet.go b/cmd/kubeadm/app/cmd/alpha/kubelet.go new file mode 100644 index 0000000000000..8ab3575ad9924 --- /dev/null +++ b/cmd/kubeadm/app/cmd/alpha/kubelet.go @@ -0,0 +1,162 @@ +/* +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 alpha + +import ( + "github.com/pkg/errors" + "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/util/version" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" + "k8s.io/kubernetes/cmd/kubeadm/app/constants" + kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" + "k8s.io/kubernetes/cmd/kubeadm/app/preflight" + kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" + kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" + "k8s.io/kubernetes/pkg/util/normalizer" + utilsexec "k8s.io/utils/exec" +) + +var ( + kubeletConfigDownloadLongDesc = normalizer.LongDesc(` + Downloads the kubelet configuration from a ConfigMap of the form "kubelet-config-1.X" in the cluster, + where X is the minor version of the kubelet. Either kubeadm autodetects the kubelet version by exec-ing + "kubelet --version" or respects the --kubelet-version parameter. + ` + cmdutil.AlphaDisclaimer) + + kubeletConfigDownloadExample = normalizer.Examples(` + # Downloads the kubelet configuration from the ConfigMap in the cluster. Autodetects the kubelet version. + kubeadm alpha phase kubelet config download + + # Downloads the kubelet configuration from the ConfigMap in the cluster. Uses a specific desired kubelet version. + kubeadm alpha phase kubelet config download --kubelet-version v1.12.0 + `) + + kubeletConfigEnableDynamicLongDesc = normalizer.LongDesc(` + Enables or updates dynamic kubelet configuration for a Node, against the kubelet-config-1.X ConfigMap in the cluster, + where X is the minor version of the desired kubelet version. + + WARNING: This feature is still experimental, and disabled by default. Enable only if you know what you are doing, as it + may have surprising side-effects at this stage. + + ` + cmdutil.AlphaDisclaimer) + + kubeletConfigEnableDynamicExample = normalizer.Examples(` + # Enables dynamic kubelet configuration for a Node. + kubeadm alpha phase kubelet enable-dynamic-config --node-name node-1 --kubelet-version v1.12.0 + + WARNING: This feature is still experimental, and disabled by default. Enable only if you know what you are doing, as it + may have surprising side-effects at this stage. + `) +) + +// newCmdKubeletUtility returns command for `kubeadm phase kubelet` +func newCmdKubeletUtility() *cobra.Command { + cmd := &cobra.Command{ + Use: "kubelet", + Short: "Commands related to handling the kubelet", + Long: cmdutil.MacroCommandLongDescription, + } + + cmd.AddCommand(newCmdKubeletConfig()) + return cmd +} + +// newCmdKubeletConfig returns command for `kubeadm phase kubelet config` +func newCmdKubeletConfig() *cobra.Command { + cmd := &cobra.Command{ + Use: "config", + Short: "Utilities for kubelet configuration", + Long: cmdutil.MacroCommandLongDescription, + } + + cmd.AddCommand(newCmdKubeletConfigDownload()) + cmd.AddCommand(newCmdKubeletConfigEnableDynamic()) + return cmd +} + +// newCmdKubeletConfigDownload calls cobra.Command for downloading the kubelet configuration from the kubelet-config-1.X ConfigMap in the cluster +func newCmdKubeletConfigDownload() *cobra.Command { + var kubeletVersionStr string + // TODO: Be smarter about this and be able to load multiple kubeconfig files in different orders of precedence + kubeConfigFile := constants.GetKubeletKubeConfigPath() + + cmd := &cobra.Command{ + Use: "download", + Short: "Downloads the kubelet configuration from the cluster ConfigMap kubelet-config-1.X, where X is the minor version of the kubelet.", + Long: kubeletConfigDownloadLongDesc, + Example: kubeletConfigDownloadExample, + Run: func(cmd *cobra.Command, args []string) { + kubeletVersion, err := getKubeletVersion(kubeletVersionStr) + kubeadmutil.CheckErr(err) + + client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) + kubeadmutil.CheckErr(err) + + err = kubeletphase.DownloadConfig(client, kubeletVersion, constants.KubeletRunDirectory) + kubeadmutil.CheckErr(err) + }, + } + + options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile) + cmd.Flags().StringVar(&kubeletVersionStr, "kubelet-version", kubeletVersionStr, "The desired version for the kubelet. Defaults to being autodetected from 'kubelet --version'.") + return cmd +} + +func getKubeletVersion(kubeletVersionStr string) (*version.Version, error) { + if len(kubeletVersionStr) > 0 { + return version.ParseSemantic(kubeletVersionStr) + } + return preflight.GetKubeletVersion(utilsexec.New()) +} + +// newCmdKubeletConfigEnableDynamic calls cobra.Command for enabling dynamic kubelet configuration on node +// This feature is still in alpha and an experimental state +func newCmdKubeletConfigEnableDynamic() *cobra.Command { + var nodeName, kubeletVersionStr string + kubeConfigFile := constants.GetAdminKubeConfigPath() + + cmd := &cobra.Command{ + Use: "enable-dynamic", + Short: "EXPERIMENTAL: Enables or updates dynamic kubelet configuration for a Node", + Long: kubeletConfigEnableDynamicLongDesc, + Example: kubeletConfigEnableDynamicExample, + Run: func(cmd *cobra.Command, args []string) { + if len(nodeName) == 0 { + kubeadmutil.CheckErr(errors.New("The --node-name argument is required")) + } + if len(kubeletVersionStr) == 0 { + kubeadmutil.CheckErr(errors.New("The --kubelet-version argument is required")) + } + + kubeletVersion, err := version.ParseSemantic(kubeletVersionStr) + kubeadmutil.CheckErr(err) + + kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) + client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) + kubeadmutil.CheckErr(err) + + err = kubeletphase.EnableDynamicConfigForNode(client, nodeName, kubeletVersion) + kubeadmutil.CheckErr(err) + }, + } + + options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile) + cmd.Flags().StringVar(&nodeName, "node-name", nodeName, "Name of the node that should enable the dynamic kubelet configuration") + cmd.Flags().StringVar(&kubeletVersionStr, "kubelet-version", kubeletVersionStr, "The desired version for the kubelet") + return cmd +} diff --git a/cmd/kubeadm/app/cmd/alpha/preflight.go b/cmd/kubeadm/app/cmd/alpha/preflight.go new file mode 100644 index 0000000000000..40ff684c4bf56 --- /dev/null +++ b/cmd/kubeadm/app/cmd/alpha/preflight.go @@ -0,0 +1,100 @@ +/* +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 alpha + +import ( + "fmt" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" + kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" + "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" + "k8s.io/kubernetes/cmd/kubeadm/app/preflight" + kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" + configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" + "k8s.io/kubernetes/pkg/util/normalizer" + utilsexec "k8s.io/utils/exec" +) + +var ( + nodePreflightLongDesc = normalizer.LongDesc(` + Run node pre-flight checks, functionally equivalent to what implemented by kubeadm join. + ` + cmdutil.AlphaDisclaimer) + + nodePreflightExample = normalizer.Examples(` + # Run node pre-flight checks. + kubeadm alpha preflight node + `) + + errorMissingConfigFlag = errors.New("the --config flag is mandatory") +) + +// newCmdPreFlightUtility calls cobra.Command for preflight checks +func newCmdPreFlightUtility() *cobra.Command { + cmd := &cobra.Command{ + Use: "preflight", + Short: "Commands related to pre-flight checks", + Long: cmdutil.MacroCommandLongDescription, + } + + cmd.AddCommand(newCmdPreFlightNode()) + + return cmd +} + +// newCmdPreFlightNode calls cobra.Command for node preflight checks +func newCmdPreFlightNode() *cobra.Command { + var cfgPath string + var ignorePreflightErrors []string + + cmd := &cobra.Command{ + Use: "node", + Short: "Run node pre-flight checks", + Long: nodePreflightLongDesc, + Example: nodePreflightExample, + Run: func(cmd *cobra.Command, args []string) { + if len(cfgPath) == 0 { + kubeadmutil.CheckErr(errorMissingConfigFlag) + } + ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(ignorePreflightErrors) + kubeadmutil.CheckErr(err) + + cfg := &kubeadmapiv1beta1.JoinConfiguration{} + kubeadmscheme.Scheme.Default(cfg) + + internalcfg, err := configutil.JoinConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) + kubeadmutil.CheckErr(err) + err = configutil.VerifyAPIServerBindAddress(internalcfg.APIEndpoint.AdvertiseAddress) + kubeadmutil.CheckErr(err) + + fmt.Println("[preflight] running pre-flight checks") + + err = preflight.RunJoinNodeChecks(utilsexec.New(), internalcfg, ignorePreflightErrorsSet) + kubeadmutil.CheckErr(err) + + fmt.Println("[preflight] pre-flight checks passed") + }, + } + + options.AddConfigFlag(cmd.PersistentFlags(), &cfgPath) + options.AddIgnorePreflightErrorsFlag(cmd.PersistentFlags(), &ignorePreflightErrors) + + return cmd +} diff --git a/cmd/kubeadm/app/cmd/cmd.go b/cmd/kubeadm/app/cmd/cmd.go index 14259211eadd1..74656288eeb4b 100644 --- a/cmd/kubeadm/app/cmd/cmd.go +++ b/cmd/kubeadm/app/cmd/cmd.go @@ -22,8 +22,7 @@ import ( "github.com/renstrom/dedent" "github.com/spf13/cobra" "github.com/spf13/pflag" - - "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/alpha" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" // Register the kubeadm configuration types because CLI flag generation @@ -90,14 +89,7 @@ func NewKubeadmCommand(in io.Reader, out, err io.Writer) *cobra.Command { cmds.AddCommand(NewCmdVersion(out)) cmds.AddCommand(NewCmdToken(out, err)) cmds.AddCommand(upgrade.NewCmdUpgrade(out)) - - // Wrap not yet fully supported commands in an alpha subcommand - experimentalCmd := &cobra.Command{ - Use: "alpha", - Short: "Experimental sub-commands not yet fully functional.", - } - experimentalCmd.AddCommand(phases.NewCmdPhase(out)) - cmds.AddCommand(experimentalCmd) + cmds.AddCommand(alpha.NewCmdAlpha(out)) AddKubeadmOtherFlags(cmds.PersistentFlags(), &rootfsPath) diff --git a/cmd/kubeadm/app/cmd/completion.go b/cmd/kubeadm/app/cmd/completion.go index a19a0a2676d7b..12da3e2fe0958 100644 --- a/cmd/kubeadm/app/cmd/completion.go +++ b/cmd/kubeadm/app/cmd/completion.go @@ -18,10 +18,10 @@ package cmd import ( "bytes" - "fmt" "io" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/renstrom/dedent" "github.com/spf13/cobra" @@ -118,14 +118,14 @@ func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command { // RunCompletion checks given arguments and executes command func RunCompletion(out io.Writer, boilerPlate string, cmd *cobra.Command, args []string) error { if len(args) == 0 { - return fmt.Errorf("shell not specified") + return errors.New("shell not specified") } if len(args) > 1 { - return fmt.Errorf("too many arguments. expected only the shell type") + return errors.New("too many arguments. expected only the shell type") } run, found := completionShells[args[0]] if !found { - return fmt.Errorf("unsupported shell type %q", args[0]) + return errors.Errorf("unsupported shell type %q", args[0]) } if len(boilerPlate) == 0 { diff --git a/cmd/kubeadm/app/cmd/config.go b/cmd/kubeadm/app/cmd/config.go index c8cb8a8047350..ef8ff29f7b400 100644 --- a/cmd/kubeadm/app/cmd/config.go +++ b/cmd/kubeadm/app/cmd/config.go @@ -24,6 +24,7 @@ import ( "strings" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/renstrom/dedent" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -187,7 +188,7 @@ func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command { func getDefaultComponentConfigAPIObjectBytes(apiObject string) ([]byte, error) { registration, ok := componentconfigs.Known[componentconfigs.RegistrationKind(apiObject)] if !ok { - return []byte{}, fmt.Errorf("--component-configs needs to contain some of %v", getSupportedComponentConfigAPIObjects()) + return []byte{}, errors.Errorf("--component-configs needs to contain some of %v", getSupportedComponentConfigAPIObjects()) } return getDefaultComponentConfigBytes(registration) } @@ -207,7 +208,7 @@ func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) { // Is this a component config? registration, ok := componentconfigs.Known[componentconfigs.RegistrationKind(apiObject)] if !ok { - return []byte{}, fmt.Errorf("--api-object needs to be one of %v", getAllAPIObjectNames()) + return []byte{}, errors.Errorf("--api-object needs to be one of %v", getAllAPIObjectNames()) } return getDefaultComponentConfigBytes(registration) } @@ -276,7 +277,7 @@ func getDefaultNodeConfigBytes() ([]byte, error) { Discovery: kubeadmapiv1beta1.Discovery{ BootstrapToken: &kubeadmapiv1beta1.BootstrapTokenDiscovery{ Token: placeholderToken.Token.String(), - APIServerEndpoints: []string{"kube-apiserver:6443"}, + APIServerEndpoint: "kube-apiserver:6443", UnsafeSkipCAVerification: true, // TODO: UnsafeSkipCAVerification: true needs to be set for validation to pass, but shouldn't be recommended as the default }, }, @@ -296,7 +297,7 @@ func getDefaultComponentConfigBytes(registration componentconfigs.Registration) realobj, ok := registration.GetFromInternalConfig(&defaultedInitConfig.ClusterConfiguration) if !ok { - return []byte{}, fmt.Errorf("GetFromInternalConfig failed") + return []byte{}, errors.New("GetFromInternalConfig failed") } return registration.Marshal(realobj) @@ -325,7 +326,7 @@ func NewCmdConfigMigrate(out io.Writer) *cobra.Command { `), kubeadmapiv1alpha3.SchemeGroupVersion.String(), kubeadmapiv1beta1.SchemeGroupVersion.String(), kubeadmapiv1beta1.SchemeGroupVersion.String()), Run: func(cmd *cobra.Command, args []string) { if len(oldCfgPath) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("The --old-config flag is mandatory")) + kubeadmutil.CheckErr(errors.New("The --old-config flag is mandatory")) } internalcfg, err := configutil.AnyConfigFileAndDefaultsToInternal(oldCfgPath) @@ -338,7 +339,7 @@ func NewCmdConfigMigrate(out io.Writer) *cobra.Command { fmt.Fprint(out, string(outputBytes)) } else { if err := ioutil.WriteFile(newCfgPath, outputBytes, 0644); err != nil { - kubeadmutil.CheckErr(fmt.Errorf("failed to write the new configuration to the file %q: %v", newCfgPath, err)) + kubeadmutil.CheckErr(errors.Wrapf(err, "failed to write the new configuration to the file %q", newCfgPath)) } } }, @@ -382,7 +383,7 @@ func NewCmdConfigView(out io.Writer, kubeConfigFile *string) *cobra.Command { } } -// NewCmdConfigUploadFromFile verifies given kubernetes config file and returns cobra.Command for +// NewCmdConfigUploadFromFile verifies given Kubernetes config file and returns cobra.Command for // "kubeadm config upload from-file" command func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Command { var cfgPath string @@ -398,7 +399,7 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co `), metav1.NamespaceSystem, constants.KubeadmConfigConfigMap), Run: func(cmd *cobra.Command, args []string) { if len(cfgPath) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("The --config flag is mandatory")) + kubeadmutil.CheckErr(errors.New("The --config flag is mandatory")) } glog.V(1).Infoln("[config] retrieving ClientSet from file") @@ -544,7 +545,7 @@ func NewImagesPull(runtime utilruntime.ContainerRuntime, images []string) *Image func (ip *ImagesPull) PullAll() error { for _, image := range ip.images { if err := ip.runtime.PullImage(image); err != nil { - return fmt.Errorf("failed to pull image %q: %v", image, err) + return errors.Wrapf(err, "failed to pull image %q", image) } fmt.Printf("[config/images] Pulled %s\n", image) } @@ -558,7 +559,7 @@ func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Comman var cfgPath, featureGatesString string var err error - // This just sets the kubernetes version for unit testing so kubeadm won't try to + // This just sets the Kubernetes version for unit testing so kubeadm won't try to // lookup the latest release from the internet. if mockK8sVersion != nil { externalcfg.KubernetesVersion = *mockK8sVersion @@ -583,7 +584,7 @@ func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Comman func NewImagesList(cfgPath string, cfg *kubeadmapiv1beta1.InitConfiguration) (*ImagesList, error) { initcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) if err != nil { - return nil, fmt.Errorf("could not convert cfg to an internal cfg: %v", err) + return nil, errors.Wrap(err, "could not convert cfg to an internal cfg") } return &ImagesList{ diff --git a/cmd/kubeadm/app/cmd/config_test.go b/cmd/kubeadm/app/cmd/config_test.go index 7af79bc3bef0d..697f1291d69b2 100644 --- a/cmd/kubeadm/app/cmd/config_test.go +++ b/cmd/kubeadm/app/cmd/config_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd_test +package cmd import ( "bytes" @@ -31,7 +31,6 @@ import ( "github.com/spf13/cobra" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" - "k8s.io/kubernetes/cmd/kubeadm/app/cmd" "k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs" "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/features" @@ -52,7 +51,7 @@ const ( func TestNewCmdConfigImagesList(t *testing.T) { var output bytes.Buffer mockK8sVersion := dummyKubernetesVersion - images := cmd.NewCmdConfigImagesList(&output, &mockK8sVersion) + images := NewCmdConfigImagesList(&output, &mockK8sVersion) images.Run(nil, nil) actual := strings.Split(output.String(), "\n") if len(actual) != defaultNumberOfImages { @@ -109,7 +108,7 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) { t.Fatalf("Failed writing a config file: %v", err) } - i, err := cmd.NewImagesList(configFilePath, &kubeadmapiv1beta1.InitConfiguration{ + i, err := NewImagesList(configFilePath, &kubeadmapiv1beta1.InitConfiguration{ ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{ KubernetesVersion: dummyKubernetesVersion, }, @@ -180,7 +179,7 @@ func TestConfigImagesListRunWithoutPath(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - i, err := cmd.NewImagesList("", &tc.cfg) + i, err := NewImagesList("", &tc.cfg) if err != nil { t.Fatalf("did not expect an error while creating the Images command: %v", err) } @@ -226,7 +225,7 @@ func TestImagesPull(t *testing.T) { } images := []string{"a", "b", "c", "d", "a"} - ip := cmd.NewImagesPull(containerRuntime, images) + ip := NewImagesPull(containerRuntime, images) err = ip.PullAll() if err != nil { @@ -249,7 +248,7 @@ func TestMigrate(t *testing.T) { defer cleanup() var output bytes.Buffer - command := cmd.NewCmdConfigMigrate(&output) + command := NewCmdConfigMigrate(&output) if err := command.Flags().Set("old-config", configFile); err != nil { t.Fatalf("failed to set old-config flag") } @@ -293,7 +292,7 @@ func TestNewCmdConfigPrintActionDefaults(t *testing.T) { constants.ClusterConfigurationKind, constants.InitConfigurationKind, }, - cmdProc: cmd.NewCmdConfigPrintInitDefaults, + cmdProc: NewCmdConfigPrintInitDefaults, }, { name: "InitConfiguration: KubeProxyConfiguration", @@ -303,7 +302,7 @@ func TestNewCmdConfigPrintActionDefaults(t *testing.T) { string(componentconfigs.KubeProxyConfigurationKind), }, componentConfigs: "KubeProxyConfiguration", - cmdProc: cmd.NewCmdConfigPrintInitDefaults, + cmdProc: NewCmdConfigPrintInitDefaults, }, { name: "InitConfiguration: KubeProxyConfiguration and KubeletConfiguration", @@ -314,14 +313,14 @@ func TestNewCmdConfigPrintActionDefaults(t *testing.T) { string(componentconfigs.KubeletConfigurationKind), }, componentConfigs: "KubeProxyConfiguration,KubeletConfiguration", - cmdProc: cmd.NewCmdConfigPrintInitDefaults, + cmdProc: NewCmdConfigPrintInitDefaults, }, { name: "JoinConfiguration: No component configs", expectedKinds: []string{ constants.JoinConfigurationKind, }, - cmdProc: cmd.NewCmdConfigPrintJoinDefaults, + cmdProc: NewCmdConfigPrintJoinDefaults, }, { name: "JoinConfiguration: KubeProxyConfiguration", @@ -330,7 +329,7 @@ func TestNewCmdConfigPrintActionDefaults(t *testing.T) { string(componentconfigs.KubeProxyConfigurationKind), }, componentConfigs: "KubeProxyConfiguration", - cmdProc: cmd.NewCmdConfigPrintJoinDefaults, + cmdProc: NewCmdConfigPrintJoinDefaults, }, { name: "JoinConfiguration: KubeProxyConfiguration and KubeletConfiguration", @@ -340,7 +339,7 @@ func TestNewCmdConfigPrintActionDefaults(t *testing.T) { string(componentconfigs.KubeletConfigurationKind), }, componentConfigs: "KubeProxyConfiguration,KubeletConfiguration", - cmdProc: cmd.NewCmdConfigPrintJoinDefaults, + cmdProc: NewCmdConfigPrintJoinDefaults, }, } diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index 286a64533ce32..ce9151c151781 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors. +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. @@ -24,9 +24,9 @@ import ( "path/filepath" "strings" "text/template" - "time" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/renstrom/dedent" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -47,20 +47,14 @@ import ( clusterinfophase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo" nodebootstraptokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" - controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" - etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster" - patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode" selfhostingphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/selfhosting" - uploadconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig" "k8s.io/kubernetes/cmd/kubeadm/app/preflight" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" - auditutil "k8s.io/kubernetes/cmd/kubeadm/app/util/audit" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" - dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" utilsexec "k8s.io/utils/exec" ) @@ -114,6 +108,8 @@ type initOptions struct { cfgPath string skipTokenPrint bool dryRun bool + kubeconfigDir string + kubeconfigPath string featureGatesString string ignorePreflightErrors []string bto *options.BootstrapTokenOptions @@ -126,15 +122,20 @@ type initData struct { cfg *kubeadmapi.InitConfiguration skipTokenPrint bool dryRun bool + kubeconfigDir string + kubeconfigPath string ignorePreflightErrors sets.String certificatesDir string dryRunDir string + externalCA bool client clientset.Interface + waiter apiclient.Waiter + outputWriter io.Writer } // NewCmdInit returns "kubeadm init" command. func NewCmdInit(out io.Writer) *cobra.Command { - options := newInitOptions() + initOptions := newInitOptions() initRunner := workflow.NewRunner() cmd := &cobra.Command{ @@ -145,7 +146,7 @@ func NewCmdInit(out io.Writer) *cobra.Command { kubeadmutil.CheckErr(err) data := c.(initData) - fmt.Printf("[init] using Kubernetes version: %s\n", data.cfg.KubernetesVersion) + fmt.Printf("[init] Using Kubernetes version: %s\n", data.cfg.KubernetesVersion) err = initRunner.Run() kubeadmutil.CheckErr(err) @@ -157,20 +158,36 @@ func NewCmdInit(out io.Writer) *cobra.Command { }, } - // adds command flags - AddInitConfigFlags(cmd.PersistentFlags(), options.externalcfg, &options.featureGatesString) - AddInitOtherFlags(cmd.PersistentFlags(), &options.cfgPath, &options.skipTokenPrint, &options.dryRun, &options.ignorePreflightErrors) - options.bto.AddTokenFlag(cmd.PersistentFlags()) - options.bto.AddTTLFlag(cmd.PersistentFlags()) + // adds flags to the init command + // init command local flags could be eventually inherited by the sub-commands automatically generated for phases + AddInitConfigFlags(cmd.Flags(), initOptions.externalcfg, &initOptions.featureGatesString) + AddInitOtherFlags(cmd.Flags(), &initOptions.cfgPath, &initOptions.skipTokenPrint, &initOptions.dryRun, &initOptions.ignorePreflightErrors) + initOptions.bto.AddTokenFlag(cmd.Flags()) + initOptions.bto.AddTTLFlag(cmd.Flags()) + + // defines additional flag that are not used by the init command but that could be eventually used + // by the sub-commands automatically generated for phases + initRunner.SetPhaseSubcommandsAdditionalFlags(func(flags *flag.FlagSet) { + options.AddKubeConfigFlag(flags, &initOptions.kubeconfigPath) + options.AddKubeConfigDirFlag(flags, &initOptions.kubeconfigDir) + options.AddControlPlanExtraArgsFlags(flags, &initOptions.externalcfg.APIServer.ExtraArgs, &initOptions.externalcfg.ControllerManager.ExtraArgs, &initOptions.externalcfg.Scheduler.ExtraArgs) + }) // initialize the workflow runner with the list of phases initRunner.AppendPhase(phases.NewPreflightMasterPhase()) + initRunner.AppendPhase(phases.NewKubeletStartPhase()) + initRunner.AppendPhase(phases.NewCertsPhase()) + initRunner.AppendPhase(phases.NewKubeConfigPhase()) + initRunner.AppendPhase(phases.NewControlPlanePhase()) + initRunner.AppendPhase(phases.NewEtcdPhase()) + initRunner.AppendPhase(phases.NewWaitControlPlanePhase()) + initRunner.AppendPhase(phases.NewUploadConfigPhase()) // TODO: add other phases to the runner. // sets the data builder function, that will be used by the runner // both when running the entire workflow or single phases initRunner.SetDataInitializer(func() (workflow.RunData, error) { - return newInitData(cmd, options) + return newInitData(cmd, initOptions, out) }) // binds the Runner to kubeadm init command by altering @@ -183,67 +200,67 @@ func NewCmdInit(out io.Writer) *cobra.Command { // AddInitConfigFlags adds init flags bound to the config to the specified flagset func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta1.InitConfiguration, featureGatesString *string) { flagSet.StringVar( - &cfg.APIEndpoint.AdvertiseAddress, "apiserver-advertise-address", cfg.APIEndpoint.AdvertiseAddress, + &cfg.APIEndpoint.AdvertiseAddress, options.APIServerAdvertiseAddress, cfg.APIEndpoint.AdvertiseAddress, "The IP address the API Server will advertise it's listening on. Specify '0.0.0.0' to use the address of the default network interface.", ) flagSet.Int32Var( - &cfg.APIEndpoint.BindPort, "apiserver-bind-port", cfg.APIEndpoint.BindPort, + &cfg.APIEndpoint.BindPort, options.APIServerBindPort, cfg.APIEndpoint.BindPort, "Port for the API Server to bind to.", ) flagSet.StringVar( - &cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, + &cfg.Networking.ServiceSubnet, options.NetworkingServiceSubnet, cfg.Networking.ServiceSubnet, "Use alternative range of IP address for service VIPs.", ) flagSet.StringVar( - &cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet, + &cfg.Networking.PodSubnet, options.NetworkingPodSubnet, cfg.Networking.PodSubnet, "Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node.", ) flagSet.StringVar( - &cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, + &cfg.Networking.DNSDomain, options.NetworkingDNSDomain, cfg.Networking.DNSDomain, `Use alternative domain for services, e.g. "myorg.internal".`, ) flagSet.StringVar( - &cfg.KubernetesVersion, "kubernetes-version", cfg.KubernetesVersion, + &cfg.KubernetesVersion, options.KubernetesVersion, cfg.KubernetesVersion, `Choose a specific Kubernetes version for the control plane.`, ) flagSet.StringVar( - &cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, + &cfg.CertificatesDir, options.CertificatesDir, cfg.CertificatesDir, `The path where to save and store the certificates.`, ) flagSet.StringSliceVar( - &cfg.APIServerCertSANs, "apiserver-cert-extra-sans", cfg.APIServerCertSANs, + &cfg.APIServer.CertSANs, options.APIServerCertSANs, cfg.APIServer.CertSANs, `Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names.`, ) flagSet.StringVar( - &cfg.NodeRegistration.Name, "node-name", cfg.NodeRegistration.Name, + &cfg.NodeRegistration.Name, options.NodeName, cfg.NodeRegistration.Name, `Specify the node name.`, ) flagSet.StringVar( - &cfg.NodeRegistration.CRISocket, "cri-socket", cfg.NodeRegistration.CRISocket, + &cfg.NodeRegistration.CRISocket, options.NodeCRISocket, cfg.NodeRegistration.CRISocket, `Specify the CRI socket to connect to.`, ) - flagSet.StringVar(featureGatesString, "feature-gates", *featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+ + flagSet.StringVar(featureGatesString, options.FeatureGatesString, *featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+ "Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n")) } // AddInitOtherFlags adds init flags that are not bound to a configuration file to the given flagset func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipTokenPrint, dryRun *bool, ignorePreflightErrors *[]string) { flagSet.StringVar( - cfgPath, "config", *cfgPath, + cfgPath, options.CfgPath, *cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental.", ) flagSet.StringSliceVar( - ignorePreflightErrors, "ignore-preflight-errors", *ignorePreflightErrors, + ignorePreflightErrors, options.IgnorePreflightErrors, *ignorePreflightErrors, "A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.", ) // Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go flagSet.BoolVar( - skipTokenPrint, "skip-token-print", *skipTokenPrint, + skipTokenPrint, options.SkipTokenPrint, *skipTokenPrint, "Skip printing of the default bootstrap token generated by 'kubeadm init'.", ) // Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go flagSet.BoolVar( - dryRun, "dry-run", *dryRun, + dryRun, options.DryRun, *dryRun, "Don't apply any changes; just output what would be done.", ) } @@ -259,15 +276,17 @@ func newInitOptions() *initOptions { bto.Description = "The default bootstrap token generated by 'kubeadm init'." return &initOptions{ - externalcfg: externalcfg, - bto: bto, + externalcfg: externalcfg, + bto: bto, + kubeconfigDir: kubeadmconstants.KubernetesDir, + kubeconfigPath: kubeadmconstants.GetAdminKubeConfigPath(), } } // newInitData returns a new initData struct to be used for the execution of the kubeadm init workflow. // This func takes care of validating initOptions passed to the command, and then it converts // options into the internal InitConfiguration type that is used as input all the phases in the kubeadm init workflow -func newInitData(cmd *cobra.Command, options *initOptions) (initData, error) { +func newInitData(cmd *cobra.Command, options *initOptions, out io.Writer) (initData, error) { // Re-apply defaults to the public kubeadm API (this will set only values not exposed/not set as a flags) kubeadmscheme.Scheme.Default(options.externalcfg) @@ -306,7 +325,19 @@ func newInitData(cmd *cobra.Command, options *initOptions) (initData, error) { dryRunDir := "" if options.dryRun { if dryRunDir, err = ioutil.TempDir("", "kubeadm-init-dryrun"); err != nil { - return initData{}, fmt.Errorf("couldn't create a temporary directory: %v", err) + return initData{}, errors.Wrap(err, "couldn't create a temporary directory") + } + } + + // Checks if an external CA is provided by the user. + externalCA, _ := certsphase.UsingExternalCA(cfg) + if externalCA { + kubeconfigDir := kubeadmconstants.KubernetesDir + if options.dryRun { + kubeconfigDir = dryRunDir + } + if err := kubeconfigphase.ValidateKubeconfigsForExternalCA(kubeconfigDir, cfg); err != nil { + return initData{}, err } } @@ -316,7 +347,11 @@ func newInitData(cmd *cobra.Command, options *initOptions) (initData, error) { skipTokenPrint: options.skipTokenPrint, dryRun: options.dryRun, dryRunDir: dryRunDir, + kubeconfigDir: options.kubeconfigDir, + kubeconfigPath: options.kubeconfigPath, ignorePreflightErrors: ignorePreflightErrorsSet, + externalCA: externalCA, + outputWriter: out, }, nil } @@ -353,15 +388,20 @@ func (d initData) CertificateDir() string { return d.certificatesDir } -// KubeConfigDir returns the path of the kubernetes configuration folder or the temporary folder path in case of DryRun. +// KubeConfigDir returns the path of the Kubernetes configuration folder or the temporary folder path in case of DryRun. func (d initData) KubeConfigDir() string { if d.dryRun { return d.dryRunDir } - return kubeadmconstants.KubernetesDir + return d.kubeconfigDir } -// KubeConfigDir returns the path where manifest should be stored or the temporary folder path in case of DryRun. +// KubeConfigPath returns the path to the kubeconfig file to use for connecting to Kubernetes +func (d initData) KubeConfigPath() string { + return d.kubeconfigPath +} + +// ManifestDir returns the path where manifest should be stored or the temporary folder path in case of DryRun. func (d initData) ManifestDir() string { if d.dryRun { return d.dryRunDir @@ -377,6 +417,16 @@ func (d initData) KubeletDir() string { return kubeadmconstants.KubeletRunDirectory } +// ExternalCA returns true if an external CA is provided by the user. +func (d initData) ExternalCA() bool { + return d.externalCA +} + +// OutputWriter returns the io.Writer used to write output to by this command. +func (d initData) OutputWriter() io.Writer { + return d.outputWriter +} + // Client returns a Kubernetes client to be used by kubeadm. // This function is implemented as a singleton, thus avoiding to recreate the client when it is used by different phases. // Important. This function must be called after the admin.conf kubeconfig file is created. @@ -389,7 +439,7 @@ func (d initData) Client() (clientset.Interface, error) { } else { // If we're acting for real, we should create a connection to the API server and wait for it to come up var err error - d.client, err = kubeconfigutil.ClientSetFromFile(kubeadmconstants.GetAdminKubeConfigPath()) + d.client, err = kubeconfigutil.ClientSetFromFile(d.KubeConfigPath()) if err != nil { return nil, err } @@ -412,35 +462,9 @@ func runInit(i *initData, out io.Writer) error { // Get directories to write files to; can be faked if we're dry-running glog.V(1).Infof("[init] Getting certificates directory from configuration") - realCertsDir := i.cfg.CertificatesDir - certsDirToWriteTo, kubeConfigDir, manifestDir, kubeletDir, err := getDirectoriesToUse(i.dryRun, i.cfg.CertificatesDir) + certsDirToWriteTo, kubeConfigDir, manifestDir, _, err := getDirectoriesToUse(i.dryRun, i.dryRunDir, i.cfg.CertificatesDir) if err != nil { - return fmt.Errorf("error getting directories to use: %v", err) - } - - // First off, configure the kubelet. In this short timeframe, kubeadm is trying to stop/restart the kubelet - // Try to stop the kubelet service so no race conditions occur when configuring it - if !i.dryRun { - glog.V(1).Infof("Stopping the kubelet") - kubeletphase.TryStopKubelet() - } - - // Write env file with flags for the kubelet to use. We do not need to write the --register-with-taints for the master, - // as we handle that ourselves in the markmaster phase - // TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase? - if err := kubeletphase.WriteKubeletDynamicEnvFile(&i.cfg.NodeRegistration, i.cfg.FeatureGates, false, kubeletDir); err != nil { - return fmt.Errorf("error writing a dynamic environment file for the kubelet: %v", err) - } - - // Write the kubelet configuration file to disk. - if err := kubeletphase.WriteConfigToDisk(i.cfg.ComponentConfigs.Kubelet, kubeletDir); err != nil { - return fmt.Errorf("error writing kubelet configuration to disk: %v", err) - } - - if !i.dryRun { - // Try to start the kubelet service in case it's inactive - glog.V(1).Infof("Starting the kubelet") - kubeletphase.TryStartKubelet() + return errors.Wrap(err, "error getting directories to use") } // certsDirToWriteTo is gonna equal cfg.CertificatesDir in the normal case, but gonna be a temp directory if dryrunning @@ -448,110 +472,24 @@ func runInit(i *initData, out io.Writer) error { adminKubeConfigPath := filepath.Join(kubeConfigDir, kubeadmconstants.AdminKubeConfigFileName) - if res, _ := certsphase.UsingExternalCA(i.cfg); !res { - - // PHASE 1: Generate certificates - glog.V(1).Infof("[init] creating PKI Assets") - if err := certsphase.CreatePKIAssets(i.cfg); err != nil { - return err - } - - // PHASE 2: Generate kubeconfig files for the admin and the kubelet - glog.V(2).Infof("[init] generating kubeconfig files") - if err := kubeconfigphase.CreateInitKubeConfigFiles(kubeConfigDir, i.cfg); err != nil { - return err - } - - } else { - fmt.Println("[externalca] the file 'ca.key' was not found, yet all other certificates are present. Using external CA mode - certificates or kubeconfig will not be generated") - } - - if features.Enabled(i.cfg.FeatureGates, features.Auditing) { - // Setup the AuditPolicy (either it was passed in and exists or it wasn't passed in and generate a default policy) - if i.cfg.AuditPolicyConfiguration.Path != "" { - // TODO(chuckha) ensure passed in audit policy is valid so users don't have to find the error in the api server log. - if _, err := os.Stat(i.cfg.AuditPolicyConfiguration.Path); err != nil { - return fmt.Errorf("error getting file info for audit policy file %q [%v]", i.cfg.AuditPolicyConfiguration.Path, err) - } - } else { - i.cfg.AuditPolicyConfiguration.Path = filepath.Join(kubeConfigDir, kubeadmconstants.AuditPolicyDir, kubeadmconstants.AuditPolicyFile) - if err := auditutil.CreateDefaultAuditLogPolicy(i.cfg.AuditPolicyConfiguration.Path); err != nil { - return fmt.Errorf("error creating default audit policy %q [%v]", i.cfg.AuditPolicyConfiguration.Path, err) - } - } - } - - // Temporarily set cfg.CertificatesDir to the "real value" when writing controlplane manifests - // This is needed for writing the right kind of manifests - i.cfg.CertificatesDir = realCertsDir - - // PHASE 3: Bootstrap the control plane - glog.V(1).Infof("[init] bootstraping the control plane") - glog.V(1).Infof("[init] creating static pod manifest") - if err := controlplanephase.CreateInitStaticPodManifestFiles(manifestDir, i.cfg); err != nil { - return fmt.Errorf("error creating init static pod manifest files: %v", err) - } - // Add etcd static pod spec only if external etcd is not configured - if i.cfg.Etcd.External == nil { - glog.V(1).Infof("[init] no external etcd found. Creating manifest for local etcd static pod") - if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(manifestDir, i.cfg); err != nil { - return fmt.Errorf("error creating local etcd static pod manifest file: %v", err) - } - } - - // Revert the earlier CertificatesDir assignment to the directory that can be written to - i.cfg.CertificatesDir = certsDirToWriteTo - - // If we're dry-running, print the generated manifests - if err := printFilesIfDryRunning(i.dryRun, manifestDir); err != nil { - return fmt.Errorf("error printing files on dryrun: %v", err) - } - - // Create a kubernetes client and wait for the API server to be healthy (if not dryrunning) - glog.V(1).Infof("creating Kubernetes client") - client, err := createClient(i.cfg, i.dryRun) + // TODO: client and waiter are temporary until the rest of the phases that use them + // are removed from this function. + client, err := i.Client() if err != nil { - return fmt.Errorf("error creating client: %v", err) + return errors.Wrap(err, "failed to create client") } - // waiter holds the apiclient.Waiter implementation of choice, responsible for querying the API server in various ways and waiting for conditions to be fulfilled - glog.V(1).Infof("[init] waiting for the API server to be healthy") - waiter := getWaiter(i, client) - - fmt.Printf("[init] waiting for the kubelet to boot up the control plane as Static Pods from directory %q \n", kubeadmconstants.GetStaticPodDirectory()) - - if err := waitForKubeletAndFunc(waiter, waiter.WaitForAPI); err != nil { - ctx := map[string]string{ - "Error": fmt.Sprintf("%v", err), - } - - kubeletFailTempl.Execute(out, ctx) - - return fmt.Errorf("couldn't initialize a Kubernetes cluster") - } - - // Upload currently used configuration to the cluster - // Note: This is done right in the beginning of cluster initialization; as we might want to make other phases - // depend on centralized information from this source in the future - glog.V(1).Infof("[init] uploading currently used configuration to the cluster") - if err := uploadconfigphase.UploadConfiguration(i.cfg, client); err != nil { - return fmt.Errorf("error uploading configuration: %v", err) - } - - glog.V(1).Infof("[init] creating kubelet configuration configmap") - if err := kubeletphase.CreateConfigMap(i.cfg, client); err != nil { - return fmt.Errorf("error creating kubelet configuration ConfigMap: %v", err) + // TODO: NewControlPlaneWaiter should be converted to private after the self-hosting phase is removed. + timeout := i.cfg.ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration + waiter, err := phases.NewControlPlaneWaiter(i.dryRun, timeout, client, i.outputWriter) + if err != nil { + return errors.Wrap(err, "failed to create waiter") } // PHASE 4: Mark the master with the right label/taint glog.V(1).Infof("[init] marking the master with right label") if err := markmasterphase.MarkMaster(client, i.cfg.NodeRegistration.Name, i.cfg.NodeRegistration.Taints); err != nil { - return fmt.Errorf("error marking master: %v", err) - } - - glog.V(1).Infof("[init] preserving the crisocket information for the master") - if err := patchnodephase.AnnotateCRISocket(client, i.cfg.NodeRegistration.Name, i.cfg.NodeRegistration.CRISocket); err != nil { - return fmt.Errorf("error uploading crisocket: %v", err) + return errors.Wrap(err, "error marking master") } // This feature is disabled by default @@ -563,7 +501,7 @@ func runInit(i *initData, out io.Writer) error { // Enable dynamic kubelet configuration for the node. if err := kubeletphase.EnableDynamicConfigForNode(client, i.cfg.NodeRegistration.Name, kubeletVersion); err != nil { - return fmt.Errorf("error enabling dynamic kubelet configuration: %v", err) + return errors.Wrap(err, "error enabling dynamic kubelet configuration") } } @@ -583,17 +521,17 @@ func runInit(i *initData, out io.Writer) error { // Create the default node bootstrap token glog.V(1).Infof("[init] creating RBAC rules to generate default bootstrap token") if err := nodebootstraptokenphase.UpdateOrCreateTokens(client, false, i.cfg.BootstrapTokens); err != nil { - return fmt.Errorf("error updating or creating token: %v", err) + return errors.Wrap(err, "error updating or creating token") } // Create RBAC rules that makes the bootstrap tokens able to post CSRs glog.V(1).Infof("[init] creating RBAC rules to allow bootstrap tokens to post CSR") if err := nodebootstraptokenphase.AllowBootstrapTokensToPostCSRs(client); err != nil { - return fmt.Errorf("error allowing bootstrap tokens to post CSRs: %v", err) + return errors.Wrap(err, "error allowing bootstrap tokens to post CSRs") } // Create RBAC rules that makes the bootstrap tokens able to get their CSRs approved automatically glog.V(1).Infof("[init] creating RBAC rules to automatic approval of CSRs automatically") if err := nodebootstraptokenphase.AutoApproveNodeBootstrapTokens(client); err != nil { - return fmt.Errorf("error auto-approving node bootstrap tokens: %v", err) + return errors.Wrap(err, "error auto-approving node bootstrap tokens") } // Create/update RBAC rules that makes the nodes to rotate certificates and get their CSRs approved automatically @@ -605,21 +543,21 @@ func runInit(i *initData, out io.Writer) error { // Create the cluster-info ConfigMap with the associated RBAC rules glog.V(1).Infof("[init] creating bootstrap configmap") if err := clusterinfophase.CreateBootstrapConfigMapIfNotExists(client, adminKubeConfigPath); err != nil { - return fmt.Errorf("error creating bootstrap configmap: %v", err) + return errors.Wrap(err, "error creating bootstrap configmap") } glog.V(1).Infof("[init] creating ClusterInfo RBAC rules") if err := clusterinfophase.CreateClusterInfoRBACRules(client); err != nil { - return fmt.Errorf("error creating clusterinfo RBAC rules: %v", err) + return errors.Wrap(err, "error creating clusterinfo RBAC rules") } glog.V(1).Infof("[init] ensuring DNS addon") if err := dnsaddonphase.EnsureDNSAddon(i.cfg, client); err != nil { - return fmt.Errorf("error ensuring dns addon: %v", err) + return errors.Wrap(err, "error ensuring dns addon") } glog.V(1).Infof("[init] ensuring proxy addon") if err := proxyaddonphase.EnsureProxyAddon(i.cfg, client); err != nil { - return fmt.Errorf("error ensuring proxy addon: %v", err) + return errors.Wrap(err, "error ensuring proxy addon") } // PHASE 7: Make the control plane self-hosted if feature gate is enabled @@ -629,7 +567,7 @@ func runInit(i *initData, out io.Writer) error { // plane components and remove the static manifests: fmt.Println("[self-hosted] creating self-hosted control plane") if err := selfhostingphase.CreateSelfHostedControlPlane(manifestDir, kubeConfigDir, i.cfg, client, waiter, i.dryRun); err != nil { - return fmt.Errorf("error creating self hosted control plane: %v", err) + return errors.Wrap(err, "error creating self hosted control plane") } } @@ -642,7 +580,7 @@ func runInit(i *initData, out io.Writer) error { // Prints the join command, multiple times in case the user has multiple tokens for _, token := range tokens { if err := printJoinCommand(out, adminKubeConfigPath, token, i.skipTokenPrint); err != nil { - return fmt.Errorf("failed to print join command: %v", err) + return errors.Wrap(err, "failed to print join command") } } return nil @@ -662,93 +600,13 @@ func printJoinCommand(out io.Writer, adminKubeConfigPath, token string, skipToke return initDoneTempl.Execute(out, ctx) } -// createClient creates a clientset.Interface object -func createClient(cfg *kubeadmapi.InitConfiguration, dryRun bool) (clientset.Interface, error) { - if dryRun { - // If we're dry-running; we should create a faked client that answers some GETs in order to be able to do the full init flow and just logs the rest of requests - dryRunGetter := apiclient.NewInitDryRunGetter(cfg.NodeRegistration.Name, cfg.Networking.ServiceSubnet) - return apiclient.NewDryRunClient(dryRunGetter, os.Stdout), nil - } - - // If we're acting for real, we should create a connection to the API server and wait for it to come up - return kubeconfigutil.ClientSetFromFile(kubeadmconstants.GetAdminKubeConfigPath()) -} - // getDirectoriesToUse returns the (in order) certificates, kubeconfig and Static Pod manifest directories, followed by a possible error // This behaves differently when dry-running vs the normal flow -func getDirectoriesToUse(dryRun bool, defaultPkiDir string) (string, string, string, string, error) { +func getDirectoriesToUse(dryRun bool, dryRunDir string, defaultPkiDir string) (string, string, string, string, error) { if dryRun { - dryRunDir, err := ioutil.TempDir("", "kubeadm-init-dryrun") - if err != nil { - return "", "", "", "", fmt.Errorf("couldn't create a temporary directory: %v", err) - } // Use the same temp dir for all return dryRunDir, dryRunDir, dryRunDir, dryRunDir, nil } return defaultPkiDir, kubeadmconstants.KubernetesDir, kubeadmconstants.GetStaticPodDirectory(), kubeadmconstants.KubeletRunDirectory, nil } - -// printFilesIfDryRunning prints the Static Pod manifests to stdout and informs about the temporary directory to go and lookup -func printFilesIfDryRunning(dryRun bool, manifestDir string) error { - if !dryRun { - return nil - } - - fmt.Printf("[dryrun] wrote certificates, kubeconfig files and control plane manifests to the %q directory\n", manifestDir) - fmt.Println("[dryrun] the certificates or kubeconfig files would not be printed due to their sensitive nature") - fmt.Printf("[dryrun] please examine the %q directory for details about what would be written\n", manifestDir) - - // Print the contents of the upgraded manifests and pretend like they were in /etc/kubernetes/manifests - files := []dryrunutil.FileToPrint{} - // Print static pod manifests - for _, component := range kubeadmconstants.MasterComponents { - realPath := kubeadmconstants.GetStaticPodFilepath(component, manifestDir) - outputPath := kubeadmconstants.GetStaticPodFilepath(component, kubeadmconstants.GetStaticPodDirectory()) - files = append(files, dryrunutil.NewFileToPrint(realPath, outputPath)) - } - // Print kubelet config manifests - kubeletConfigFiles := []string{kubeadmconstants.KubeletConfigurationFileName, kubeadmconstants.KubeletEnvFileName} - for _, filename := range kubeletConfigFiles { - realPath := filepath.Join(manifestDir, filename) - outputPath := filepath.Join(kubeadmconstants.KubeletRunDirectory, filename) - files = append(files, dryrunutil.NewFileToPrint(realPath, outputPath)) - } - - return dryrunutil.PrintDryRunFiles(files, os.Stdout) -} - -// getWaiter gets the right waiter implementation for the right occasion -func getWaiter(ctx *initData, client clientset.Interface) apiclient.Waiter { - if ctx.dryRun { - return dryrunutil.NewWaiter() - } - - // We know that the images should be cached locally already as we have pulled them using - // crictl in the preflight checks. Hence we can have a pretty short timeout for the kubelet - // to start creating Static Pods. - timeout := 4 * time.Minute - return apiclient.NewKubeWaiter(client, timeout, os.Stdout) -} - -// waitForKubeletAndFunc waits primarily for the function f to execute, even though it might take some time. If that takes a long time, and the kubelet -// /healthz continuously are unhealthy, kubeadm will error out after a period of exponential backoff -func waitForKubeletAndFunc(waiter apiclient.Waiter, f func() error) error { - errorChan := make(chan error) - - go func(errC chan error, waiter apiclient.Waiter) { - // This goroutine can only make kubeadm init fail. If this check succeeds, it won't do anything special - if err := waiter.WaitForHealthyKubelet(40*time.Second, fmt.Sprintf("http://localhost:%d/healthz", kubeadmconstants.KubeletHealthzPort)); err != nil { - errC <- err - } - }(errorChan, waiter) - - go func(errC chan error, waiter apiclient.Waiter) { - // This main goroutine sends whatever the f function returns (error or not) to the channel - // This in order to continue on success (nil error), or just fail if the function returns an error - errC <- f() - }(errorChan, waiter) - - // This call is blocking until one of the goroutines sends to errorChan - return <-errorChan -} diff --git a/cmd/kubeadm/app/cmd/join.go b/cmd/kubeadm/app/cmd/join.go index 817ebc585138f..143d7dc7c75d5 100644 --- a/cmd/kubeadm/app/cmd/join.go +++ b/cmd/kubeadm/app/cmd/join.go @@ -30,7 +30,6 @@ import ( "github.com/renstrom/dedent" "github.com/spf13/cobra" flag "github.com/spf13/pflag" - "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" @@ -44,6 +43,7 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/features" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" + etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster" @@ -74,7 +74,6 @@ var ( Please ensure that: * The cluster has a stable controlPlaneEndpoint address. - * The cluster uses an external etcd. * The certificates that must be shared among control plane instances are provided. `))) @@ -85,7 +84,8 @@ var ( * Certificate signing request was sent to apiserver and approval was received. * The Kubelet was informed of the new secure connection details. * Master label and taint were applied to the new node. - * The kubernetes control plane instances scaled up. + * The Kubernetes control plane instances scaled up. + {{.etcdMessage}} To start administering your cluster from this node, you need to run the following as a regular user: @@ -177,10 +177,15 @@ func NewCmdJoin(out io.Writer) *cobra.Command { cfg.Discovery.File = fd } else { cfg.Discovery.BootstrapToken = btd - cfg.Discovery.BootstrapToken.APIServerEndpoints = args if len(cfg.Discovery.BootstrapToken.Token) == 0 { cfg.Discovery.BootstrapToken.Token = token } + if len(args) > 0 { + if len(cfgPath) == 0 && len(args) > 1 { + glog.Warningf("[join] WARNING: More than one API server endpoint supplied on command line %v. Using the first one.", args) + } + cfg.Discovery.BootstrapToken.APIServerEndpoint = args[0] + } } if len(cfg.Discovery.TLSBootstrapToken) == 0 { @@ -284,6 +289,8 @@ func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, ignorePreflightEr // Join defines struct used by kubeadm join command type Join struct { cfg *kubeadmapi.JoinConfiguration + initCfg *kubeadmapi.InitConfiguration + tlsBootstrapCfg *clientcmdapi.Config ignorePreflightErrors sets.String } @@ -298,52 +305,44 @@ func NewJoin(cfgPath string, defaultcfg *kubeadmapiv1beta1.JoinConfiguration, ig glog.V(1).Infoln("[join] found advertiseAddress empty; using default interface's IP address as advertiseAddress") } - internalcfg, err := configutil.JoinConfigFileAndDefaultsToInternalConfig(cfgPath, defaultcfg) + internalCfg, err := configutil.JoinConfigFileAndDefaultsToInternalConfig(cfgPath, defaultcfg) if err != nil { return nil, err } - if err := configutil.VerifyAPIServerBindAddress(internalcfg.APIEndpoint.AdvertiseAddress); err != nil { + if err := configutil.VerifyAPIServerBindAddress(internalCfg.APIEndpoint.AdvertiseAddress); err != nil { return nil, err } - fmt.Println("[preflight] running pre-flight checks") + fmt.Println("[preflight] Running pre-flight checks") - // Then continue with the others... - glog.V(1).Infoln("[preflight] running various checks on all nodes") - if err := preflight.RunJoinNodeChecks(utilsexec.New(), internalcfg, ignorePreflightErrors); err != nil { + // Start with general checks + glog.V(1).Infoln("[preflight] Running general checks") + if err := preflight.RunJoinNodeChecks(utilsexec.New(), internalCfg, ignorePreflightErrors); err != nil { return nil, err } - return &Join{cfg: internalcfg, ignorePreflightErrors: ignorePreflightErrors}, nil -} - -// Run executes worker node provisioning and tries to join an existing cluster. -func (j *Join) Run(out io.Writer) error { - // Perform the Discovery, which turns a Bootstrap Token and optionally (and preferably) a CA cert hash into a KubeConfig - // file that may be used for the TLS Bootstrapping process the kubelet performs using the Certificates API. - glog.V(1).Infoln("[join] discovering cluster-info") - tlsBootstrapCfg, err := discovery.For(j.cfg) + // Fetch the init configuration based on the join configuration + glog.V(1).Infoln("[preflight] Fetching init configuration") + initCfg, tlsBootstrapCfg, err := fetchInitConfigurationFromJoinConfiguration(internalCfg) if err != nil { - return err + return nil, err } - // If the node should host a new control plane instance - var initConfiguration *kubeadmapi.InitConfiguration - if j.cfg.ControlPlane == true { - // Retrives the kubeadm configuration used during kubeadm init - glog.V(1).Infoln("[join] retrieving KubeConfig objects") - initConfiguration, err = j.FetchInitConfiguration(tlsBootstrapCfg) - if err != nil { - return err - } + // Continue with more specific checks based on the init configuration + glog.V(1).Infoln("[preflight] Running configuration dependant checks") + if err := preflight.RunOptionalJoinNodeChecks(utilsexec.New(), initCfg, ignorePreflightErrors); err != nil { + return nil, err + } - // injects into the kubeadm configuration the information about the joining node - initConfiguration.NodeRegistration = j.cfg.NodeRegistration - initConfiguration.APIEndpoint = j.cfg.APIEndpoint + return &Join{cfg: internalCfg, initCfg: initCfg, tlsBootstrapCfg: tlsBootstrapCfg, ignorePreflightErrors: ignorePreflightErrors}, nil +} +// Run executes worker node provisioning and tries to join an existing cluster. +func (j *Join) Run(out io.Writer) error { + if j.cfg.ControlPlane == true { // Checks if the cluster configuration supports // joining a new control plane instance and if all the necessary certificates are provided - if err = j.CheckIfReadyForAdditionalControlPlane(initConfiguration); err != nil { + if err := j.CheckIfReadyForAdditionalControlPlane(j.initCfg); err != nil { // outputs the not ready for hosting a new control plane instance message ctx := map[string]string{ "Error": err.Error(), @@ -355,12 +354,12 @@ func (j *Join) Run(out io.Writer) error { } // run kubeadm init preflight checks for checking all the prequisites - fmt.Printf("[join] running pre-flight checks before initializing the new control plane instance\n") - preflight.RunInitMasterChecks(utilsexec.New(), initConfiguration, j.ignorePreflightErrors) + fmt.Printf("[join] Running pre-flight checks before initializing the new control plane instance\n") + preflight.RunInitMasterChecks(utilsexec.New(), j.initCfg, j.ignorePreflightErrors) // Prepares the node for hosting a new control plane instance by writing necessary - // KubeConfig files, and static pod manifests - if err = j.PrepareForHostingControlPlane(initConfiguration); err != nil { + // kubeconfig files, and static pod manifests + if err := j.PrepareForHostingControlPlane(j.initCfg); err != nil { return err } } @@ -371,20 +370,27 @@ func (j *Join) Run(out io.Writer) error { // if the node is hosting a new control plane instance, since it uses static pods for the control plane, // as soon as the kubelet starts it will take charge of creating control plane // components on the node. - if err = j.BootstrapKubelet(tlsBootstrapCfg); err != nil { + if err := j.BootstrapKubelet(j.tlsBootstrapCfg); err != nil { return err } // if the node is hosting a new control plane instance if j.cfg.ControlPlane == true { // Completes the control plane setup - if err := j.PostInstallControlPlane(initConfiguration); err != nil { + if err := j.PostInstallControlPlane(j.initCfg); err != nil { return err } // outputs the join control plane done template and exits + etcdMessage := "" + // in case of local etcd + if j.initCfg.Etcd.External == nil { + etcdMessage = "* A new etcd member was added to the local/stacked etcd cluster." + } + ctx := map[string]string{ "KubeConfigPath": kubeadmconstants.GetAdminKubeConfigPath(), + "etcdMessage": etcdMessage, } joinControPlaneDoneTemp.Execute(out, ctx) return nil @@ -396,44 +402,22 @@ func (j *Join) Run(out io.Writer) error { return nil } -// FetchInitConfiguration reads the cluster configuration from the kubeadm-admin configMap, -func (j *Join) FetchInitConfiguration(tlsBootstrapCfg *clientcmdapi.Config) (*kubeadmapi.InitConfiguration, error) { - // creates a client to access the cluster using the bootstrap token identity - tlsClient, err := kubeconfigutil.ToClientSet(tlsBootstrapCfg) - if err != nil { - return nil, errors.Wrap(err, "Unable to access the cluster") - } - - // Fetches the init configuration - initConfiguration, err := configutil.FetchConfigFromFileOrCluster(tlsClient, os.Stdout, "join", "", true) - if err != nil { - return nil, errors.Wrap(err, "Unable to fetch the kubeadm-config ConfigMap") - } - - return initConfiguration, nil -} - // CheckIfReadyForAdditionalControlPlane ensures that the cluster is in a state that supports // joining an additional control plane instance and if the node is ready to join func (j *Join) CheckIfReadyForAdditionalControlPlane(initConfiguration *kubeadmapi.InitConfiguration) error { // blocks if the cluster was created without a stable control plane endpoint if initConfiguration.ControlPlaneEndpoint == "" { - return fmt.Errorf("unable to add a new control plane instance a cluster that doesn't have a stable controlPlaneEndpoint address") - } - - // blocks if the cluster was created without an external etcd cluster - if initConfiguration.Etcd.External == nil { - return fmt.Errorf("unable to add a new control plane instance on a cluster that doesn't use an external etcd") + return errors.New("unable to add a new control plane instance a cluster that doesn't have a stable controlPlaneEndpoint address") } // blocks if control plane is self-hosted if features.Enabled(initConfiguration.FeatureGates, features.SelfHosting) { - return fmt.Errorf("self-hosted clusters are deprecated and won't be supported by `kubeadm join --experimental-control-plane`") + return errors.New("self-hosted clusters are deprecated and won't be supported by `kubeadm join --experimental-control-plane`") } // blocks if the certificates for the control plane are stored in secrets (instead of the local pki folder) if features.Enabled(initConfiguration.FeatureGates, features.StoreCertsInSecrets) { - return fmt.Errorf("certificates stored in secrets, as well as self-hosted clusters are deprecated and won't be supported by `kubeadm join --experimental-control-plane`") + return errors.New("certificates stored in secrets, as well as self-hosted clusters are deprecated and won't be supported by `kubeadm join --experimental-control-plane`") } // checks if the certificates that must be equal across contolplane instances are provided @@ -465,6 +449,23 @@ func (j *Join) PrepareForHostingControlPlane(initConfiguration *kubeadmapi.InitC return errors.Wrap(err, "error creating static pod manifest files for the control plane components") } + // in case of local etcd + if initConfiguration.Etcd.External == nil { + // Checks that the etcd cluster is healthy + // NB. this check cannot be implemented before because it requires the admin.conf and all the certificates + // for connecting to etcd already in place + kubeConfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName) + + client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) + if err != nil { + return errors.Wrap(err, "couldn't create Kubernetes client") + } + + if err := etcdphase.CheckLocalEtcdClusterStatus(client, initConfiguration); err != nil { + return err + } + } + return nil } @@ -495,7 +496,7 @@ func (j *Join) BootstrapKubelet(tlsBootstrapCfg *clientcmdapi.Config) error { bootstrapClient, err := kubeconfigutil.ClientSetFromFile(bootstrapKubeConfigFile) if err != nil { - return fmt.Errorf("couldn't create client from kubeconfig file %q", bootstrapKubeConfigFile) + return errors.Errorf("couldn't create client from kubeconfig file %q", bootstrapKubeConfigFile) } // Configure the kubelet. In this short timeframe, kubeadm is trying to stop/restart the kubelet @@ -521,10 +522,10 @@ func (j *Join) BootstrapKubelet(tlsBootstrapCfg *clientcmdapi.Config) error { kubeletphase.TryStartKubelet() // Now the kubelet will perform the TLS Bootstrap, transforming /etc/kubernetes/bootstrap-kubelet.conf to /etc/kubernetes/kubelet.conf - // Wait for the kubelet to create the /etc/kubernetes/kubelet.conf KubeConfig file. If this process + // Wait for the kubelet to create the /etc/kubernetes/kubelet.conf kubeconfig file. If this process // times out, display a somewhat user-friendly message. waiter := apiclient.NewKubeWaiter(nil, kubeadmconstants.TLSBootstrapTimeout, os.Stdout) - if err := waitForKubeletAndFunc(waiter, waitForTLSBootstrappedClient); err != nil { + if err := waiter.WaitForKubeletAndFunc(waitForTLSBootstrappedClient); err != nil { fmt.Printf(kubeadmJoinFailMsg, err) return err } @@ -556,12 +557,29 @@ func (j *Join) PostInstallControlPlane(initConfiguration *kubeadmapi.InitConfigu client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) if err != nil { - return errors.Wrap(err, "couldn't create kubernetes client") + return errors.Wrap(err, "couldn't create Kubernetes client") + } + + // in case of local etcd + if initConfiguration.Etcd.External == nil { + // Adds a new etcd instance; in order to do this the new etcd instance should be "announced" to + // the existing etcd members before being created. + // This operation must be executed after kubelet is already started in order to minimize the time + // between the new etcd member is announced and the start of the static pod running the new etcd member, because during + // this time frame etcd gets temporary not available (only when moving from 1 to 2 members in the etcd cluster). + // From https://coreos.com/etcd/docs/latest/v2/runtime-configuration.html + // "If you add a new member to a 1-node cluster, the cluster cannot make progress before the new member starts + // because it needs two members as majority to agree on the consensus. You will only see this behavior between the time + // etcdctl member add informs the cluster about the new member and the new member successfully establishing a connection to the existing one." + glog.V(1).Info("[join] adding etcd") + if err := etcdphase.CreateStackedEtcdStaticPodManifestFile(client, kubeadmconstants.GetStaticPodDirectory(), initConfiguration); err != nil { + return errors.Wrap(err, "error creating local etcd static pod manifest file") + } } glog.V(1).Info("[join] uploading currently used configuration to the cluster") if err := uploadconfigphase.UploadConfiguration(initConfiguration, client); err != nil { - return fmt.Errorf("error uploading configuration: %v", err) + return errors.Wrap(err, "error uploading configuration") } glog.V(1).Info("[join] marking the master with right label") @@ -583,3 +601,44 @@ func waitForTLSBootstrappedClient() error { return (err == nil), nil }) } + +// fetchInitConfigurationFromJoinConfiguration retrieves the init configuration from a join configuration, performing the discovery +func fetchInitConfigurationFromJoinConfiguration(cfg *kubeadmapi.JoinConfiguration) (*kubeadmapi.InitConfiguration, *clientcmdapi.Config, error) { + // Perform the Discovery, which turns a Bootstrap Token and optionally (and preferably) a CA cert hash into a KubeConfig + // file that may be used for the TLS Bootstrapping process the kubelet performs using the Certificates API. + glog.V(1).Infoln("[join] Discovering cluster-info") + tlsBootstrapCfg, err := discovery.For(cfg) + if err != nil { + return nil, nil, err + } + + // Retrieves the kubeadm configuration + glog.V(1).Infoln("[join] Retrieving KubeConfig objects") + initConfiguration, err := fetchInitConfiguration(tlsBootstrapCfg) + if err != nil { + return nil, nil, err + } + + // injects into the kubeadm configuration the information about the joining node + initConfiguration.NodeRegistration = cfg.NodeRegistration + initConfiguration.APIEndpoint = cfg.APIEndpoint + + return initConfiguration, tlsBootstrapCfg, nil +} + +// fetchInitConfiguration reads the cluster configuration from the kubeadm-admin configMap +func fetchInitConfiguration(tlsBootstrapCfg *clientcmdapi.Config) (*kubeadmapi.InitConfiguration, error) { + // creates a client to access the cluster using the bootstrap token identity + tlsClient, err := kubeconfigutil.ToClientSet(tlsBootstrapCfg) + if err != nil { + return nil, errors.Wrap(err, "unable to access the cluster") + } + + // Fetches the init configuration + initConfiguration, err := configutil.FetchConfigFromFileOrCluster(tlsClient, os.Stdout, "join", "", true) + if err != nil { + return nil, errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap") + } + + return initConfiguration, nil +} diff --git a/cmd/kubeadm/app/cmd/options/BUILD b/cmd/kubeadm/app/cmd/options/BUILD index 0f69807e35deb..8f8248b32ccad 100644 --- a/cmd/kubeadm/app/cmd/options/BUILD +++ b/cmd/kubeadm/app/cmd/options/BUILD @@ -4,6 +4,8 @@ go_library( name = "go_default_library", srcs = [ "certs.go", + "constant.go", + "doc.go", "generic.go", "token.go", ], @@ -12,6 +14,7 @@ go_library( deps = [ "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/flag:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", ], diff --git a/cmd/kubeadm/app/cmd/options/certs.go b/cmd/kubeadm/app/cmd/options/certs.go index 54adbf7fb9fdb..b1dddc5db94a5 100644 --- a/cmd/kubeadm/app/cmd/options/certs.go +++ b/cmd/kubeadm/app/cmd/options/certs.go @@ -20,5 +20,5 @@ import "github.com/spf13/pflag" // AddCertificateDirFlag adds the --certs-dir flag to the given flagset func AddCertificateDirFlag(fs *pflag.FlagSet, certsDir *string) { - fs.StringVar(certsDir, "cert-dir", *certsDir, "The path where to save the certificates") + fs.StringVar(certsDir, CertificatesDir, *certsDir, "The path where to save the certificates") } diff --git a/cmd/kubeadm/app/cmd/options/constant.go b/cmd/kubeadm/app/cmd/options/constant.go new file mode 100644 index 0000000000000..5bff8860e974f --- /dev/null +++ b/cmd/kubeadm/app/cmd/options/constant.go @@ -0,0 +1,77 @@ +/* +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 options + +// APIServerAdvertiseAddress flag sets the IP address the API Server will advertise it's listening on. Specify '0.0.0.0' to use the address of the default network interface. +const APIServerAdvertiseAddress = "apiserver-advertise-address" + +// APIServerBindPort flag sets the port for the API Server to bind to. +const APIServerBindPort = "apiserver-bind-port" + +// APIServerCertSANs flag sets extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names. +const APIServerCertSANs = "apiserver-cert-extra-sans" + +// APIServerExtraArgs flag sets a extra flags to pass to the API Server or override default ones in form of =. +const APIServerExtraArgs = "apiserver-extra-args" + +// CertificatesDir flag sets the path where to save and read the certificates. +const CertificatesDir = "cert-dir" + +// CfgPath flag sets the path to kubeadm config file. WARNING: Usage of a configuration file is experimental. +const CfgPath = "config" + +// ControllerManagerExtraArgs flag sets extra flags to pass to the Controller Manager or override default ones in form of =. +const ControllerManagerExtraArgs = "controller-manager-extra-args" + +// DryRun flag instruct kubeadm to don't apply any changes; just output what would be done. +const DryRun = "dry-run" + +// FeatureGatesString flag sets key=value pairs that describe feature gates for various features. +const FeatureGatesString = "feature-gates" + +// IgnorePreflightErrors sets the path a list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks. +const IgnorePreflightErrors = "ignore-preflight-errors" + +// KubeconfigDir flag sets the path where to save the kubeconfig file. +const KubeconfigDir = "kubeconfig-dir" + +// KubeconfigPath flag sets the kubeconfig file to use when talking to the cluster. If the flag is not set, a set of standard locations are searched for an existing KubeConfig file. +const KubeconfigPath = "kubeconfig" + +// KubernetesVersion flag sets the Kubernetes version for the control plane. +const KubernetesVersion = "kubernetes-version" + +// NetworkingDNSDomain flag sets the domain for services, e.g. "myorg.internal". +const NetworkingDNSDomain = "service-dns-domain" + +// NetworkingServiceSubnet flag sets the range of IP address for service VIPs. +const NetworkingServiceSubnet = "service-cidr" + +// NetworkingPodSubnet flag sets the range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node. +const NetworkingPodSubnet = "pod-network-cidr" + +// NodeCRISocket flag sets the CRI socket to connect to. +const NodeCRISocket = "cri-socket" + +// NodeName flag sets the node name. +const NodeName = "node-name" + +// SchedulerExtraArgs flag sets extra flags to pass to the Scheduler or override default ones in form of =". +const SchedulerExtraArgs = "scheduler-extra-args" + +// SkipTokenPrint flag instruct kubeadm to skip printing of the default bootstrap token generated by 'kubeadm init'. +const SkipTokenPrint = "skip-token-print" diff --git a/cmd/kubeadm/app/cmd/options/doc.go b/cmd/kubeadm/app/cmd/options/doc.go new file mode 100644 index 0000000000000..8e04d08917e96 --- /dev/null +++ b/cmd/kubeadm/app/cmd/options/doc.go @@ -0,0 +1,29 @@ +/* +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 options provide a central point for defining flags for kubeadm cobra commands, +no matter if hard coded commands or autogenerated command for phases. + +New kubeadm flags should always be defined in this package as a constant before their usage, +in order to enforce naming consistency across different commands and to control flag proliferation. + +In addition to defining the flags, the package also contains set of utilities for flag management. + +For additional details about how flags are managed in phases, please refer to the +"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" package. +*/ +package options diff --git a/cmd/kubeadm/app/cmd/options/generic.go b/cmd/kubeadm/app/cmd/options/generic.go index d09edcb020fe6..58e748a44e342 100644 --- a/cmd/kubeadm/app/cmd/options/generic.go +++ b/cmd/kubeadm/app/cmd/options/generic.go @@ -16,22 +16,37 @@ limitations under the License. package options -import "github.com/spf13/pflag" +import ( + "github.com/spf13/pflag" + utilflag "k8s.io/apiserver/pkg/util/flag" +) // AddKubeConfigFlag adds the --kubeconfig flag to the given flagset func AddKubeConfigFlag(fs *pflag.FlagSet, kubeConfigFile *string) { - fs.StringVar(kubeConfigFile, "kubeconfig", *kubeConfigFile, "The KubeConfig file to use when talking to the cluster. If the flag is not set, a set of standard locations are searched for an existing KubeConfig file.") + fs.StringVar(kubeConfigFile, KubeconfigPath, *kubeConfigFile, "The kubeconfig file to use when talking to the cluster. If the flag is not set, a set of standard locations are searched for an existing KubeConfig file.") +} + +// AddKubeConfigDirFlag adds the --kubeconfig-dir flag to the given flagset +func AddKubeConfigDirFlag(fs *pflag.FlagSet, kubeConfigDir *string) { + fs.StringVar(kubeConfigDir, KubeconfigDir, *kubeConfigDir, "The path where to save the kubeconfig file.") } // AddConfigFlag adds the --config flag to the given flagset func AddConfigFlag(fs *pflag.FlagSet, cfgPath *string) { - fs.StringVar(cfgPath, "config", *cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)") + fs.StringVar(cfgPath, CfgPath, *cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental).") } // AddIgnorePreflightErrorsFlag adds the --ignore-preflight-errors flag to the given flagset func AddIgnorePreflightErrorsFlag(fs *pflag.FlagSet, ignorePreflightErrors *[]string) { fs.StringSliceVar( - ignorePreflightErrors, "ignore-preflight-errors", *ignorePreflightErrors, + ignorePreflightErrors, IgnorePreflightErrors, *ignorePreflightErrors, "A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.", ) } + +// AddControlPlanExtraArgsFlags adds the ExtraArgs flags for control plane components +func AddControlPlanExtraArgsFlags(fs *pflag.FlagSet, apiServerExtraArgs, controllerManagerExtraArgs, schedulerExtraArgs *map[string]string) { + fs.Var(utilflag.NewMapStringString(apiServerExtraArgs), APIServerExtraArgs, "A set of extra flags to pass to the API Server or override default ones in form of =") + fs.Var(utilflag.NewMapStringString(controllerManagerExtraArgs), ControllerManagerExtraArgs, "A set of extra flags to pass to the Controller Manager or override default ones in form of =") + fs.Var(utilflag.NewMapStringString(schedulerExtraArgs), SchedulerExtraArgs, "A set of extra flags to pass to the Scheduler or override default ones in form of =") +} diff --git a/cmd/kubeadm/app/cmd/phases/BUILD b/cmd/kubeadm/app/cmd/phases/BUILD index 24def1c28892b..d2199ceeaee13 100644 --- a/cmd/kubeadm/app/cmd/phases/BUILD +++ b/cmd/kubeadm/app/cmd/phases/BUILD @@ -11,11 +11,11 @@ go_library( "kubeconfig.go", "kubelet.go", "markmaster.go", - "phase.go", "preflight.go", "selfhosting.go", "uploadconfig.go", "util.go", + "waitcontrolplane.go", ], importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases", visibility = ["//visibility:public"], @@ -25,7 +25,6 @@ go_library( "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library", "//cmd/kubeadm/app/cmd/options:go_default_library", - "//cmd/kubeadm/app/cmd/phases/certs:go_default_library", "//cmd/kubeadm/app/cmd/phases/workflow:go_default_library", "//cmd/kubeadm/app/cmd/util:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", @@ -46,17 +45,19 @@ go_library( "//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library", + "//cmd/kubeadm/app/util/audit:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", + "//cmd/kubeadm/app/util/dryrun:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library", "//pkg/util/normalizer:go_default_library", "//pkg/version:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/util/flag:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", + "//vendor/github.com/renstrom/dedent:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", @@ -67,26 +68,13 @@ go_test( name = "go_default_test", srcs = [ "addons_test.go", - "certs_test.go", - "controlplane_test.go", - "etcd_test.go", - "kubeconfig_test.go", - "kubelet_test.go", "util_test.go", ], embed = [":go_default_library"], deps = [ - "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", - "//cmd/kubeadm/app/constants:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", - "//cmd/kubeadm/test:go_default_library", "//cmd/kubeadm/test/cmd:go_default_library", - "//cmd/kubeadm/test/kubeconfig:go_default_library", - "//pkg/util/node:go_default_library", "//pkg/version:go_default_library", - "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", - "//vendor/github.com/spf13/cobra:go_default_library", ], ) @@ -101,7 +89,6 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", - "//cmd/kubeadm/app/cmd/phases/certs:all-srcs", "//cmd/kubeadm/app/cmd/phases/workflow:all-srcs", ], tags = ["automanaged"], diff --git a/cmd/kubeadm/app/cmd/phases/bootstraptoken.go b/cmd/kubeadm/app/cmd/phases/bootstraptoken.go index ed0c7e185f63f..dd4617ec9cb7e 100644 --- a/cmd/kubeadm/app/cmd/phases/bootstraptoken.go +++ b/cmd/kubeadm/app/cmd/phases/bootstraptoken.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -324,7 +325,7 @@ func createBootstrapToken(kubeConfigFile string, client clientset.Interface, cfg if len(internalcfg.BootstrapTokens) > 0 { joinCommand, err := cmdutil.GetJoinCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), skipTokenPrint) if err != nil { - return fmt.Errorf("failed to get join command: %v", err) + return errors.Wrap(err, "failed to get join command") } fmt.Println(joinCommand) } diff --git a/cmd/kubeadm/app/cmd/phases/certs.go b/cmd/kubeadm/app/cmd/phases/certs.go index b210958bcd836..ef972c2102c34 100644 --- a/cmd/kubeadm/app/cmd/phases/certs.go +++ b/cmd/kubeadm/app/cmd/phases/certs.go @@ -20,39 +20,20 @@ import ( "fmt" "strings" - "github.com/spf13/cobra" - + "github.com/pkg/errors" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" - certscmdphase "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/certs" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" - configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - allCertsLongDesc = normalizer.LongDesc(` - Generates a self-signed CA to provision identities for each component in the cluster (including nodes) - and client certificates to be used by various components. - - If a given certificate and private key pair both exist, kubeadm skips the generation step and - existing files will be used. - ` + cmdutil.AlphaDisclaimer) - - allCertsExample = normalizer.Examples(` - # Creates all PKI assets necessary to establish the control plane, - # functionally equivalent to what generated by kubeadm init. - kubeadm alpha phase certs all - - # Creates all PKI assets using options read from a configuration file. - kubeadm alpha phase certs all --config masterconfiguration.yaml - `) - saKeyLongDesc = fmt.Sprintf(normalizer.LongDesc(` Generates the private key for signing service account tokens along with its public key, and saves them into %s and %s files. @@ -66,81 +47,59 @@ var ( ` + cmdutil.AlphaDisclaimer) ) -// NewCmdCerts returns main command for certs phase -func NewCmdCerts() *cobra.Command { - cmd := &cobra.Command{ - Use: "certs", - Aliases: []string{"certificates"}, - Short: "Generates certificates for a Kubernetes cluster", - Long: cmdutil.MacroCommandLongDescription, - } - - cmd.AddCommand(getCertsSubCommands("")...) - return cmd +// certsData defines the behavior that a runtime data struct passed to the certs phase should +// have. Please note that we are using an interface in order to make this phase reusable in different workflows +// (and thus with different runtime data struct, all of them requested to be compliant to this interface) +type certsData interface { + Cfg() *kubeadmapi.InitConfiguration + ExternalCA() bool + CertificateDir() string + CertificateWriteDir() string } -// getCertsSubCommands returns sub commands for certs phase -func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command { - - cfg := &kubeadmapiv1beta1.InitConfiguration{} +// NewCertsPhase returns the phase for the certs +func NewCertsPhase() workflow.Phase { + return workflow.Phase{ + Name: "certs", + Short: "Certificate generation", + Phases: newCertSubPhases(), + Run: runCerts, + CmdFlags: getCertPhaseFlags("all"), + } +} - // Default values for the cobra help text - kubeadmscheme.Scheme.Default(cfg) +// newCertSubPhases returns sub phases for certs phase +func newCertSubPhases() []workflow.Phase { + subPhases := []workflow.Phase{} - var cfgPath string + certTree, _ := certsphase.GetDefaultCertList().AsMap().CertTree() - // Special case commands - // All runs CreatePKIAssets, which isn't a particular certificate - allCmd := &cobra.Command{ - Use: "all", - Short: "Generates all PKI assets necessary to establish the control plane", - Long: allCertsLongDesc, - Example: allCertsExample, - Run: func(cmd *cobra.Command, args []string) { - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) - kubeadmutil.CheckErr(err) + for ca, certList := range certTree { + caPhase := newCertSubPhase(ca, runCAPhase(ca)) + subPhases = append(subPhases, caPhase) - err = certsphase.CreatePKIAssets(internalcfg) - kubeadmutil.CheckErr(err) - }, + for _, cert := range certList { + certPhase := newCertSubPhase(cert, runCertPhase(cert, ca)) + subPhases = append(subPhases, certPhase) + } } - addFlags(allCmd, &cfgPath, cfg, true) // SA creates the private/public key pair, which doesn't use x509 at all - saCmd := &cobra.Command{ - Use: "sa", + saPhase := workflow.Phase{ + Name: "sa", Short: "Generates a private key for signing service account tokens along with its public key", Long: saKeyLongDesc, - Run: func(cmd *cobra.Command, args []string) { - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) - kubeadmutil.CheckErr(err) - - err = certsphase.CreateServiceAccountKeyAndPublicKeyFiles(internalcfg) - kubeadmutil.CheckErr(err) - }, + Run: runCertsSa, } - addFlags(saCmd, &cfgPath, cfg, false) - - // "renew" command - renewCmd := certscmdphase.NewCmdCertsRenewal() - subCmds := []*cobra.Command{allCmd, saCmd, renewCmd} + subPhases = append(subPhases, saPhase) - certTree, err := certsphase.GetDefaultCertList().AsMap().CertTree() - kubeadmutil.CheckErr(err) - - for ca, certList := range certTree { - // Don't use pointers from for loops, they will be rewrittenb - caCmds := makeCommandsForCA(ca, certList, &cfgPath, cfg) - subCmds = append(subCmds, caCmds...) - } - - return subCmds + return subPhases } -func makeCmd(certSpec *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv1beta1.InitConfiguration) *cobra.Command { - cmd := &cobra.Command{ - Use: certSpec.Name, +func newCertSubPhase(certSpec *certsphase.KubeadmCert, run func(c workflow.RunData) error) workflow.Phase { + phase := workflow.Phase{ + Name: certSpec.Name, Short: fmt.Sprintf("Generates the %s", certSpec.LongName), Long: fmt.Sprintf( genericLongDesc, @@ -148,10 +107,26 @@ func makeCmd(certSpec *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv certSpec.BaseName, getSANDescription(certSpec), ), + Run: run, + CmdFlags: getCertPhaseFlags(certSpec.Name), } - addFlags(cmd, cfgPath, cfg, certSpec.Name == "apiserver") - // Add flags to the command - return cmd + return phase +} + +func getCertPhaseFlags(name string) []string { + flags := []string{ + options.CertificatesDir, + options.CfgPath, + } + if name == "all" || name == "apiserver" { + flags = append(flags, + options.APIServerAdvertiseAddress, + options.APIServerCertSANs, + options.NetworkingDNSDomain, + options.NetworkingServiceSubnet, + ) + } + return flags } func getSANDescription(certSpec *certsphase.KubeadmCert) string { @@ -188,51 +163,91 @@ func getSANDescription(certSpec *certsphase.KubeadmCert) string { return fmt.Sprintf("\n\nDefault SANs are %s", strings.Join(sans, ", ")) } -func addFlags(cmd *cobra.Command, cfgPath *string, cfg *kubeadmapiv1beta1.InitConfiguration, addAPIFlags bool) { - options.AddCertificateDirFlag(cmd.Flags(), &cfg.CertificatesDir) - options.AddConfigFlag(cmd.Flags(), cfgPath) - if addAPIFlags { - cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, "Alternative domain for services, to use for the API server serving cert") - cmd.Flags().StringVar(&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, "Alternative range of IP address for service VIPs, from which derives the internal API server VIP that will be added to the API Server serving cert") - cmd.Flags().StringSliceVar(&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", []string{}, "Optional extra altnames to use for the API server serving cert. Can be both IP addresses and DNS names") - cmd.Flags().StringVar(&cfg.APIEndpoint.AdvertiseAddress, "apiserver-advertise-address", cfg.APIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on, to use for the API server serving cert") +func runCertsSa(c workflow.RunData) error { + data, ok := c.(certsData) + if !ok { + return errors.New("certs phase invoked with an invalid data struct") } -} - -func makeCommandsForCA(ca *certsphase.KubeadmCert, certList []*certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv1beta1.InitConfiguration) []*cobra.Command { - subCmds := []*cobra.Command{} - - caCmd := makeCmd(ca, cfgPath, cfg) - caCmd.Run = func(cmd *cobra.Command, args []string) { - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg) - kubeadmutil.CheckErr(err) - err = certsphase.CreateCACertAndKeyFiles(ca, internalcfg) - kubeadmutil.CheckErr(err) + // if external CA mode, skip service account key generation + if data.ExternalCA() { + fmt.Printf("[certs] External CA mode: Using existing sa keys\n") + return nil } - subCmds = append(subCmds, caCmd) + // if dryrunning, write certificates to a temporary folder (and defer restore to the path originally specified by the user) + cfg := data.Cfg() + cfg.CertificatesDir = data.CertificateWriteDir() + defer func() { cfg.CertificatesDir = data.CertificateDir() }() - for _, cert := range certList { - certCmd := makeCommandForCert(cert, ca, cfgPath, cfg) - subCmds = append(subCmds, certCmd) + // create the new service account key (or use existing) + return certsphase.CreateServiceAccountKeyAndPublicKeyFiles(cfg) +} + +func runCerts(c workflow.RunData) error { + data, ok := c.(certsData) + if !ok { + return errors.New("certs phase invoked with an invalid data struct") } - return subCmds + fmt.Printf("[certs] Using certificateDir folder %q\n", data.CertificateWriteDir()) + return nil } -func makeCommandForCert(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv1beta1.InitConfiguration) *cobra.Command { - certCmd := makeCmd(cert, cfgPath, cfg) +func runCAPhase(ca *certsphase.KubeadmCert) func(c workflow.RunData) error { + return func(c workflow.RunData) error { + data, ok := c.(certsData) + if !ok { + return errors.New("certs phase invoked with an invalid data struct") + } + + // if external CA mode, skips certificate authority generation + if data.ExternalCA() { + fmt.Printf("[certs] External CA mode: Using existing %s certificate authority\n", ca.BaseName) + return nil + } + + // if using external etcd, skips etcd certificate authority generation + if data.Cfg().Etcd.External != nil && ca.Name == "etcd-ca" { + fmt.Printf("[certs] External etcd mode: Skipping %s certificate authority generation\n", ca.BaseName) + return nil + } - certCmd.Run = func(cmd *cobra.Command, args []string) { - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg) - kubeadmutil.CheckErr(err) - err = configutil.VerifyAPIServerBindAddress(internalcfg.APIEndpoint.AdvertiseAddress) - kubeadmutil.CheckErr(err) + // if dryrunning, write certificates authority to a temporary folder (and defer restore to the path originally specified by the user) + cfg := data.Cfg() + cfg.CertificatesDir = data.CertificateWriteDir() + defer func() { cfg.CertificatesDir = data.CertificateDir() }() - err = certsphase.CreateCertAndKeyFilesWithCA(cert, caCert, internalcfg) - kubeadmutil.CheckErr(err) + // create the new certificate authority (or use existing) + return certsphase.CreateCACertAndKeyFiles(ca, cfg) } +} - return certCmd +func runCertPhase(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert) func(c workflow.RunData) error { + return func(c workflow.RunData) error { + data, ok := c.(certsData) + if !ok { + return errors.New("certs phase invoked with an invalid data struct") + } + + // if external CA mode, skip certificate generation + if data.ExternalCA() { + fmt.Printf("[certs] External CA mode: Using existing %s certificate\n", cert.BaseName) + return nil + } + + // if using external etcd, skips etcd certificates generation + if data.Cfg().Etcd.External != nil && cert.CAName == "etcd-ca" { + fmt.Printf("[certs] External etcd mode: Skipping %s certificate authority generation\n", cert.BaseName) + return nil + } + + // if dryrunning, write certificates to a temporary folder (and defer restore to the path originally specified by the user) + cfg := data.Cfg() + cfg.CertificatesDir = data.CertificateWriteDir() + defer func() { cfg.CertificatesDir = data.CertificateDir() }() + + // create the new certificate (or use existing) + return certsphase.CreateCertAndKeyFilesWithCA(cert, caCert, cfg) + } } diff --git a/cmd/kubeadm/app/cmd/phases/certs_test.go b/cmd/kubeadm/app/cmd/phases/certs_test.go deleted file mode 100644 index 09fe2572f9772..0000000000000 --- a/cmd/kubeadm/app/cmd/phases/certs_test.go +++ /dev/null @@ -1,287 +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 phases - -import ( - "fmt" - "os" - "strings" - "testing" - - kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" - "k8s.io/kubernetes/pkg/util/node" - - testutil "k8s.io/kubernetes/cmd/kubeadm/test" - cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd" -) - -// phaseTestK8sVersion is a fake kubernetes version to use when testing -const phaseTestK8sVersion = "v1.11.0" - -func TestCertsSubCommandsHasFlags(t *testing.T) { - - subCmds := getCertsSubCommands(phaseTestK8sVersion) - - commonFlags := []string{ - "cert-dir", - "config", - } - - var tests = []struct { - command string - additionalFlags []string - }{ - { - command: "all", - additionalFlags: []string{ - "apiserver-advertise-address", - "apiserver-cert-extra-sans", - "service-cidr", - "service-dns-domain", - }, - }, - { - command: "ca", - }, - { - command: "apiserver", - additionalFlags: []string{ - "apiserver-advertise-address", - "apiserver-cert-extra-sans", - "service-cidr", - "service-dns-domain", - }, - }, - { - command: "apiserver-kubelet-client", - }, - { - command: "etcd-ca", - }, - { - command: "etcd-server", - }, - { - command: "etcd-peer", - }, - { - command: "etcd-healthcheck-client", - }, - { - command: "apiserver-etcd-client", - }, - { - command: "sa", - }, - { - command: "front-proxy-ca", - }, - { - command: "front-proxy-client", - }, - } - - for _, test := range tests { - expectedFlags := append(commonFlags, test.additionalFlags...) - cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...) - } -} - -func TestSubCmdCertsCreateFilesWithFlags(t *testing.T) { - - subCmds := getCertsSubCommands(phaseTestK8sVersion) - - var tests = []struct { - subCmds []string - expectedFiles []string - }{ - { - subCmds: []string{"all"}, - expectedFiles: []string{ - kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, - kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, - kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName, - kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName, - kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, - kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName, - }, - }, - { - subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"}, - expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName}, - }, - { - subCmds: []string{"etcd-ca", "etcd-server", "etcd-peer", "etcd-healthcheck-client", "apiserver-etcd-client"}, - expectedFiles: []string{ - kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdCAKeyName, - kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName, - kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName, - kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName, - kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName, - }, - }, - { - subCmds: []string{"sa"}, - expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName}, - }, - { - subCmds: []string{"front-proxy-ca", "front-proxy-client"}, - expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName}, - }, - } - - for _, test := range tests { - t.Run(strings.Join(test.subCmds, ","), func(t *testing.T) { - // Create temp folder for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - // executes given sub commands - for _, subCmdName := range test.subCmds { - fmt.Printf("running command %q\n", subCmdName) - certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir) - cmdtestutil.RunSubCommand(t, subCmds, subCmdName, certDirFlag) - } - - // verify expected files are there - testutil.AssertFileExists(t, tmpdir, test.expectedFiles...) - }) - } -} - -func TestSubCmdCertsApiServerForwardsFlags(t *testing.T) { - - subCmds := getCertsSubCommands(phaseTestK8sVersion) - - // Create temp folder for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - // creates ca cert - certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir) - cmdtestutil.RunSubCommand(t, subCmds, "ca", certDirFlag) - - // creates apiserver cert - apiserverFlags := []string{ - fmt.Sprintf("--cert-dir=%s", tmpdir), - "--apiserver-cert-extra-sans=foo,boo", - "--service-cidr=10.0.0.0/24", - "--service-dns-domain=mycluster.local", - "--apiserver-advertise-address=1.2.3.4", - } - cmdtestutil.RunSubCommand(t, subCmds, "apiserver", apiserverFlags...) - - // asserts created cert has values from CLI flags - APIserverCert, err := pkiutil.TryLoadCertFromDisk(tmpdir, kubeadmconstants.APIServerCertAndKeyBaseName) - if err != nil { - t.Fatalf("Error loading API server certificate: %v", err) - } - - hostname, err := node.GetHostname("") - if err != nil { - t.Fatal(err) - } - - for i, name := range []string{hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.mycluster.local"} { - if APIserverCert.DNSNames[i] != name { - t.Errorf("APIserverCert.DNSNames[%d] is %s instead of %s", i, APIserverCert.DNSNames[i], name) - } - } - for i, ip := range []string{"10.0.0.1", "1.2.3.4"} { - if APIserverCert.IPAddresses[i].String() != ip { - t.Errorf("APIserverCert.IPAddresses[%d] is %s instead of %s", i, APIserverCert.IPAddresses[i], ip) - } - } -} - -func TestSubCmdCertsCreateFilesWithConfigFile(t *testing.T) { - - subCmds := getCertsSubCommands(phaseTestK8sVersion) - - var tests = []struct { - subCmds []string - expectedFiles []string - }{ - { - subCmds: []string{"all"}, - expectedFiles: []string{ - kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, - kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, - kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName, - kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName, - kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, - kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName, - }, - }, - { - subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"}, - expectedFiles: []string{ - kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, - kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, - kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName, - }, - }, - { - subCmds: []string{"etcd-ca", "etcd-server", "etcd-peer", "etcd-healthcheck-client", "apiserver-etcd-client"}, - expectedFiles: []string{ - kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdCAKeyName, - kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName, - kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName, - kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName, - kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName, - }, - }, - { - subCmds: []string{"front-proxy-ca", "front-proxy-client"}, - expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName}, - }, - { - subCmds: []string{"sa"}, - expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName}, - }, - } - - for _, test := range tests { - t.Run(strings.Join(test.subCmds, ","), func(t *testing.T) { - - // Create temp folder for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - cfg := &kubeadmapi.InitConfiguration{ - APIEndpoint: kubeadmapi.APIEndpoint{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, - ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - CertificatesDir: tmpdir, - }, - NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, - } - configPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg) - - // executes given sub commands - for _, subCmdName := range test.subCmds { - t.Logf("running subcommand %q", subCmdName) - configFlag := fmt.Sprintf("--config=%s", configPath) - cmdtestutil.RunSubCommand(t, subCmds, subCmdName, configFlag) - } - - // verify expected files are there - testutil.AssertFileExists(t, tmpdir, test.expectedFiles...) - }) - } -} diff --git a/cmd/kubeadm/app/cmd/phases/controlplane.go b/cmd/kubeadm/app/cmd/phases/controlplane.go index 8882311e9f2f4..81ea3c1c56115 100644 --- a/cmd/kubeadm/app/cmd/phases/controlplane.go +++ b/cmd/kubeadm/app/cmd/phases/controlplane.go @@ -1,5 +1,5 @@ /* -Copyright 2017 The Kubernetes Authors. +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. @@ -17,186 +17,154 @@ limitations under the License. package phases import ( + "errors" "fmt" - "strings" + "os" + "path/filepath" - "github.com/spf13/cobra" - - utilflag "k8s.io/apiserver/pkg/util/flag" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" - kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" - "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/features" - controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" - kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" - configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" + "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" + auditutil "k8s.io/kubernetes/cmd/kubeadm/app/util/audit" "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - allControlplaneLongDesc = normalizer.LongDesc(` - Generates all static Pod manifest files necessary to establish the control plane. - ` + cmdutil.AlphaDisclaimer) - - allControlplaneExample = normalizer.Examples(` + controlPlaneExample = normalizer.Examples(` # Generates all static Pod manifest files for control plane components, - # functionally equivalent to what generated by kubeadm init. - kubeadm alpha phase controlplane all + # functionally equivalent to what is generated by kubeadm init. + kubeadm init phase control-plane # Generates all static Pod manifest files using options read from a configuration file. - kubeadm alpha phase controlplane --config masterconfiguration.yaml + kubeadm init phase control-plane --config config.yaml `) - apiServerControlplaneLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the static Pod manifest file for the API server and saves it into %s file. - `+cmdutil.AlphaDisclaimer), kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.KubeAPIServer, kubeadmconstants.GetStaticPodDirectory())) - - controllerManagerControlplaneLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the static Pod manifest file for the controller-manager and saves it into %s file. - `+cmdutil.AlphaDisclaimer), kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.KubeControllerManager, kubeadmconstants.GetStaticPodDirectory())) - - schedulerControlplaneLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the static Pod manifest file for the scheduler and saves it into %s file. - `+cmdutil.AlphaDisclaimer), kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.KubeScheduler, kubeadmconstants.GetStaticPodDirectory())) -) - -// NewCmdControlplane returns main command for Controlplane phase -func NewCmdControlplane() *cobra.Command { - cmd := &cobra.Command{ - Use: "controlplane", - Short: "Generates all static Pod manifest files necessary to establish the control plane", - Long: cmdutil.MacroCommandLongDescription, - } - - manifestPath := kubeadmconstants.GetStaticPodDirectory() - cmd.AddCommand(getControlPlaneSubCommands(manifestPath, "")...) - return cmd -} - -// getControlPlaneSubCommands returns sub commands for Controlplane phase -func getControlPlaneSubCommands(outDir, defaultKubernetesVersion string) []*cobra.Command { - - cfg := &kubeadmapiv1beta1.InitConfiguration{} - - // This is used for unit testing only... - // If we wouldn't set this to something, the code would dynamically look up the version from the internet - // By setting this explicitly for tests workarounds that - if defaultKubernetesVersion != "" { - cfg.KubernetesVersion = defaultKubernetesVersion - } - - // Default values for the cobra help text - kubeadmscheme.Scheme.Default(cfg) - - var cfgPath, featureGatesString string - var subCmds []*cobra.Command - - subCmdProperties := []struct { - use string - short string - long string - examples string - cmdFunc func(outDir string, cfg *kubeadmapi.InitConfiguration) error + controlPlanePhaseProperties = map[string]struct { + name string + short string }{ - { - use: "all", - short: "Generates all static Pod manifest files necessary to establish the control plane", - long: allControlplaneLongDesc, - examples: allControlplaneExample, - cmdFunc: controlplanephase.CreateInitStaticPodManifestFiles, - }, - { - use: "apiserver", - short: "Generates the API server static Pod manifest", - long: apiServerControlplaneLongDesc, - cmdFunc: controlplanephase.CreateAPIServerStaticPodManifestFile, + kubeadmconstants.KubeAPIServer: { + name: "apiserver", + short: getPhaseDescription(kubeadmconstants.KubeAPIServer), }, - { - use: "controller-manager", - short: "Generates the controller-manager static Pod manifest", - long: controllerManagerControlplaneLongDesc, - cmdFunc: controlplanephase.CreateControllerManagerStaticPodManifestFile, + kubeadmconstants.KubeControllerManager: { + name: "controller-manager", + short: getPhaseDescription(kubeadmconstants.KubeControllerManager), }, - { - use: "scheduler", - short: "Generates the scheduler static Pod manifest", - long: schedulerControlplaneLongDesc, - cmdFunc: controlplanephase.CreateSchedulerStaticPodManifestFile, + kubeadmconstants.KubeScheduler: { + name: "scheduler", + short: getPhaseDescription(kubeadmconstants.KubeScheduler), }, } +) - for _, properties := range subCmdProperties { - // Creates the UX Command - cmd := &cobra.Command{ - Use: properties.use, - Short: properties.short, - Long: properties.long, - Example: properties.examples, - Run: runCmdControlPlane(properties.cmdFunc, &outDir, &cfgPath, &featureGatesString, cfg), - } +type controlPlaneData interface { + Cfg() *kubeadmapi.InitConfiguration + KubeConfigDir() string + ManifestDir() string +} - // Add flags to the command - cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`) - cmd.Flags().StringVar(&cfg.KubernetesVersion, "kubernetes-version", cfg.KubernetesVersion, `Choose a specific Kubernetes version for the control plane`) - - if properties.use == "all" || properties.use == "apiserver" { - cmd.Flags().StringVar(&cfg.APIEndpoint.AdvertiseAddress, "apiserver-advertise-address", cfg.APIEndpoint.AdvertiseAddress, "The IP address of the API server is accessible on") - cmd.Flags().Int32Var(&cfg.APIEndpoint.BindPort, "apiserver-bind-port", cfg.APIEndpoint.BindPort, "The port the API server is accessible on") - cmd.Flags().StringVar(&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, "The range of IP address used for service VIPs") - cmd.Flags().StringVar(&featureGatesString, "feature-gates", featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+ - "Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n")) - cmd.Flags().Var(utilflag.NewMapStringString(&cfg.APIServerExtraArgs), "apiserver-extra-args", "A set of extra flags to pass to the API Server or override default ones in form of =") - } +func getPhaseDescription(component string) string { + return fmt.Sprintf("Generates the %s static Pod manifest", component) +} - if properties.use == "all" || properties.use == "controller-manager" { - cmd.Flags().StringVar(&cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet, "The range of IP addresses used for the Pod network") - cmd.Flags().Var(utilflag.NewMapStringString(&cfg.ControllerManagerExtraArgs), "controller-manager-extra-args", "A set of extra flags to pass to the Controller Manager or override default ones in form of =") - } +// NewControlPlanePhase creates a kubeadm workflow phase that implements bootstrapping the control plane. +func NewControlPlanePhase() workflow.Phase { + phase := workflow.Phase{ + Name: "control-plane", + Short: "Generates all static Pod manifest files necessary to establish the control plane", + Example: controlPlaneExample, + Phases: []workflow.Phase{ + newControlPlaneSubPhase(kubeadmconstants.KubeAPIServer), + newControlPlaneSubPhase(kubeadmconstants.KubeControllerManager), + newControlPlaneSubPhase(kubeadmconstants.KubeScheduler), + }, + Run: runControlPlanePhase, + CmdFlags: getControlPlanePhaseFlags("all"), + } + return phase +} - if properties.use == "all" || properties.use == "scheduler" { - cmd.Flags().Var(utilflag.NewMapStringString(&cfg.SchedulerExtraArgs), "scheduler-extra-args", "A set of extra flags to pass to the Scheduler or override default ones in form of =") - } +func newControlPlaneSubPhase(component string) workflow.Phase { + phase := workflow.Phase{ + Name: controlPlanePhaseProperties[component].name, + Short: controlPlanePhaseProperties[component].short, + Run: runControlPlaneSubPhase(component), + CmdFlags: getControlPlanePhaseFlags(component), + } + return phase +} - cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental") +func getControlPlanePhaseFlags(name string) []string { + flags := []string{ + options.CfgPath, + options.CertificatesDir, + options.KubernetesVersion, + } + if name == "all" || name == kubeadmconstants.KubeAPIServer { + flags = append(flags, + options.APIServerAdvertiseAddress, + options.APIServerBindPort, + options.APIServerExtraArgs, + options.FeatureGatesString, + options.NetworkingServiceSubnet, + ) + } + if name == "all" || name == kubeadmconstants.KubeControllerManager { + flags = append(flags, + options.ControllerManagerExtraArgs, + options.NetworkingPodSubnet, + ) + } + if name == "all" || name == kubeadmconstants.KubeScheduler { + flags = append(flags, + options.SchedulerExtraArgs, + ) + } + return flags +} - subCmds = append(subCmds, cmd) +func runControlPlanePhase(c workflow.RunData) error { + data, ok := c.(controlPlaneData) + if !ok { + return errors.New("control-plane phase invoked with an invalid data struct") } - return subCmds + fmt.Printf("[control-plane] Using manifest folder %q\n", data.ManifestDir()) + return nil } -// runCmdControlPlane creates a cobra.Command Run function, by composing the call to the given cmdFunc with necessary additional steps (e.g preparation of input parameters) -func runCmdControlPlane(cmdFunc func(outDir string, cfg *kubeadmapi.InitConfiguration) error, outDir, cfgPath *string, featureGatesString *string, cfg *kubeadmapiv1beta1.InitConfiguration) func(cmd *cobra.Command, args []string) { - - // the following statement build a closure that wraps a call to a cmdFunc, binding - // the function itself with the specific parameters of each sub command. - // Please note that specific parameter should be passed as value, while other parameters - passed as reference - - // are shared between sub commands and gets access to current value e.g. flags value. - return func(cmd *cobra.Command, args []string) { - var err error - if err = validation.ValidateMixedArguments(cmd.Flags()); err != nil { - kubeadmutil.CheckErr(err) +func runControlPlaneSubPhase(component string) func(c workflow.RunData) error { + return func(c workflow.RunData) error { + data, ok := c.(controlPlaneData) + if !ok { + return errors.New("control-plane phase invoked with an invalid data struct") } - - if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, *featureGatesString); err != nil { - kubeadmutil.CheckErr(err) + cfg := data.Cfg() + + // special case to handle audit policy for the API server + if component == kubeadmconstants.KubeAPIServer && features.Enabled(cfg.FeatureGates, features.Auditing) { + // Setup the AuditPolicy (either it was passed in and exists or it wasn't passed in and generate a default policy) + if cfg.AuditPolicyConfiguration.Path != "" { + // TODO(chuckha) ensure passed in audit policy is valid so users don't have to find the error in the api server log. + if _, err := os.Stat(cfg.AuditPolicyConfiguration.Path); err != nil { + return fmt.Errorf("error getting file info for audit policy file %q [%v]", cfg.AuditPolicyConfiguration.Path, err) + } + } else { + cfg.AuditPolicyConfiguration.Path = filepath.Join(data.KubeConfigDir(), kubeadmconstants.AuditPolicyDir, kubeadmconstants.AuditPolicyFile) + if err := auditutil.CreateDefaultAuditLogPolicy(cfg.AuditPolicyConfiguration.Path); err != nil { + return fmt.Errorf("error creating default audit policy %q [%v]", cfg.AuditPolicyConfiguration.Path, err) + } + } } - // This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg) - kubeadmutil.CheckErr(err) - err = configutil.VerifyAPIServerBindAddress(internalcfg.APIEndpoint.AdvertiseAddress) - kubeadmutil.CheckErr(err) - - if err := features.ValidateVersion(features.InitFeatureGates, internalcfg.FeatureGates, internalcfg.KubernetesVersion); err != nil { - kubeadmutil.CheckErr(err) + fmt.Printf("[control-plane] Creating static Pod manifest for %q\n", component) + if err := controlplane.CreateStaticPodFiles(data.ManifestDir(), cfg, component); err != nil { + return err } - - // Execute the cmdFunc - err = cmdFunc(*outDir, internalcfg) - kubeadmutil.CheckErr(err) + return nil } } diff --git a/cmd/kubeadm/app/cmd/phases/controlplane_test.go b/cmd/kubeadm/app/cmd/phases/controlplane_test.go deleted file mode 100644 index a9ad56b3af743..0000000000000 --- a/cmd/kubeadm/app/cmd/phases/controlplane_test.go +++ /dev/null @@ -1,149 +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 phases - -import ( - "fmt" - "os" - "testing" - - testutil "k8s.io/kubernetes/cmd/kubeadm/test" - cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd" -) - -func TestControlPlaneSubCommandsHasFlags(t *testing.T) { - - subCmds := getControlPlaneSubCommands("", phaseTestK8sVersion) - - commonFlags := []string{ - "cert-dir", - "config", - } - - var tests = []struct { - command string - additionalFlags []string - }{ - { - command: "all", - additionalFlags: []string{ - "kubernetes-version", - "apiserver-advertise-address", - "apiserver-bind-port", - "service-cidr", - "pod-network-cidr", - "feature-gates", - }, - }, - { - command: "apiserver", - additionalFlags: []string{ - "kubernetes-version", - "apiserver-advertise-address", - "apiserver-bind-port", - "service-cidr", - "feature-gates", - }, - }, - { - command: "controller-manager", - additionalFlags: []string{ - "kubernetes-version", - "pod-network-cidr", - }, - }, - { - command: "scheduler", - additionalFlags: []string{ - "kubernetes-version", - }, - }, - } - - for _, test := range tests { - expectedFlags := append(commonFlags, test.additionalFlags...) - cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...) - } -} - -func TestControlPlaneCreateFilesWithFlags(t *testing.T) { - - var tests = []struct { - command string - additionalFlags []string - expectedFiles []string - }{ - { - command: "all", - additionalFlags: []string{ - "--kubernetes-version=v1.11.0", - "--apiserver-advertise-address=1.2.3.4", - "--apiserver-bind-port=6443", - "--service-cidr=1.2.3.4/16", - "--pod-network-cidr=1.2.3.4/16", - }, - expectedFiles: []string{ - "kube-apiserver.yaml", - "kube-controller-manager.yaml", - "kube-scheduler.yaml", - }, - }, - { - command: "apiserver", - additionalFlags: []string{ - "--kubernetes-version=v1.11.0", - "--apiserver-advertise-address=1.2.3.4", - "--apiserver-bind-port=6443", - "--service-cidr=1.2.3.4/16", - }, - expectedFiles: []string{"kube-apiserver.yaml"}, - }, - { - command: "controller-manager", - additionalFlags: []string{ - "--kubernetes-version=v1.11.0", - "--pod-network-cidr=1.2.3.4/16", - }, - expectedFiles: []string{"kube-controller-manager.yaml"}, - }, - { - command: "scheduler", - additionalFlags: []string{ - "--kubernetes-version=v1.11.0", - }, - expectedFiles: []string{"kube-scheduler.yaml"}, - }, - } - - for _, test := range tests { - - // Create temp folder for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - // Get subcommands working in the temporary directory - subCmds := getControlPlaneSubCommands(tmpdir, phaseTestK8sVersion) - - // Execute the subcommand - certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir) - allFlags := append(test.additionalFlags, certDirFlag) - cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...) - - // Checks that requested files are there - testutil.AssertFileExists(t, tmpdir, test.expectedFiles...) - } -} diff --git a/cmd/kubeadm/app/cmd/phases/etcd.go b/cmd/kubeadm/app/cmd/phases/etcd.go index 911cafbfb0396..5da45c2dbb645 100644 --- a/cmd/kubeadm/app/cmd/phases/etcd.go +++ b/cmd/kubeadm/app/cmd/phases/etcd.go @@ -19,84 +19,82 @@ package phases import ( "fmt" - "github.com/spf13/cobra" - + "github.com/golang/glog" + "github.com/pkg/errors" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" - kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" - kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - etcdLocalLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the static Pod manifest file for a local, single-node etcd instance and saves it to %s file. - `+cmdutil.AlphaDisclaimer), kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.Etcd, kubeadmconstants.GetStaticPodDirectory())) - etcdLocalExample = normalizer.Examples(` # Generates the static Pod manifest file for etcd, functionally - # equivalent to what generated by kubeadm init. - kubeadm alpha phase etcd local + # equivalent to what is generated by kubeadm init. + kubeadm init phase etcd local - # Generates the static Pod manifest file for etcd. - kubeadm alpha phase etcd local --config masterconfiguration.yaml + # Generates the static Pod manifest file for etcd using options + # read from a configuration file. + kubeadm init phase etcd local --config config.yaml `) ) -// NewCmdEtcd returns main command for Etcd phase -func NewCmdEtcd() *cobra.Command { - cmd := &cobra.Command{ - Use: "etcd", - Short: "Generates static Pod manifest file for etcd.", - Long: cmdutil.MacroCommandLongDescription, - } - - manifestPath := kubeadmconstants.GetStaticPodDirectory() - cmd.AddCommand(getEtcdSubCommands(manifestPath, "")...) - return cmd +type etcdData interface { + Cfg() *kubeadmapi.InitConfiguration + ManifestDir() string } -// getEtcdSubCommands returns sub commands for etcd phase -func getEtcdSubCommands(outDir, defaultKubernetesVersion string) []*cobra.Command { - - cfg := &kubeadmapiv1beta1.InitConfiguration{} - - // Default values for the cobra help text - kubeadmscheme.Scheme.Default(cfg) - - var cfgPath string - var subCmds []*cobra.Command - - properties := struct { - use string - short string - long string - examples string - cmdFunc func(outDir string, cfg *kubeadmapi.InitConfiguration) error - }{ - use: "local", - short: "Generates the static Pod manifest file for a local, single-node etcd instance", - long: etcdLocalLongDesc, - examples: etcdLocalExample, - cmdFunc: etcdphase.CreateLocalEtcdStaticPodManifestFile, +// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd. +func NewEtcdPhase() workflow.Phase { + phase := workflow.Phase{ + Name: "etcd", + Short: "Generates static Pod manifest file for local etcd.", + Example: etcdLocalExample, + Phases: []workflow.Phase{ + newEtcdLocalSubPhase(), + }, + CmdFlags: getEtcdPhaseFlags(), } + return phase +} - // Creates the UX Command - cmd := &cobra.Command{ - Use: properties.use, - Short: properties.short, - Long: properties.long, - Example: properties.examples, - Run: runCmdPhase(properties.cmdFunc, &outDir, &cfgPath, cfg, defaultKubernetesVersion), +func newEtcdLocalSubPhase() workflow.Phase { + phase := workflow.Phase{ + Name: "local", + Short: "Generates the static Pod manifest file for a local, single-node local etcd instance.", + Example: etcdLocalExample, + Run: runEtcdPhaseLocal(), + CmdFlags: getEtcdPhaseFlags(), } + return phase +} - // Add flags to the command - cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`) - cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental") - - subCmds = append(subCmds, cmd) +func getEtcdPhaseFlags() []string { + flags := []string{ + options.CertificatesDir, + options.CfgPath, + } + return flags +} - return subCmds +func runEtcdPhaseLocal() func(c workflow.RunData) error { + return func(c workflow.RunData) error { + data, ok := c.(etcdData) + if !ok { + return errors.New("etcd phase invoked with an invalid data struct") + } + cfg := data.Cfg() + + // Add etcd static pod spec only if external etcd is not configured + if cfg.Etcd.External == nil { + fmt.Printf("[etcd] Creating static Pod manifest for local etcd in %q\n", data.ManifestDir()) + if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(data.ManifestDir(), cfg); err != nil { + return errors.Wrap(err, "error creating local etcd static pod manifest file") + } + } else { + glog.V(1).Infof("[etcd] External etcd mode. Skipping the creation of a manifest for local etcd") + } + return nil + } } diff --git a/cmd/kubeadm/app/cmd/phases/etcd_test.go b/cmd/kubeadm/app/cmd/phases/etcd_test.go deleted file mode 100644 index cc12e3c8222dd..0000000000000 --- a/cmd/kubeadm/app/cmd/phases/etcd_test.go +++ /dev/null @@ -1,83 +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 phases - -import ( - "fmt" - "os" - "testing" - - testutil "k8s.io/kubernetes/cmd/kubeadm/test" - cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd" -) - -func TestEtcdSubCommandsHasFlags(t *testing.T) { - - subCmds := getEtcdSubCommands("", phaseTestK8sVersion) - - commonFlags := []string{ - "cert-dir", - "config", - } - - var tests = []struct { - command string - additionalFlags []string - }{ - { - command: "local", - }, - } - - for _, test := range tests { - expectedFlags := append(commonFlags, test.additionalFlags...) - cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...) - } -} - -func TestEtcdCreateFilesWithFlags(t *testing.T) { - - var tests = []struct { - command string - additionalFlags []string - expectedFiles []string - }{ - { - command: "local", - expectedFiles: []string{"etcd.yaml"}, - additionalFlags: []string{}, - }, - } - - for _, test := range tests { - - // Create temp folder for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - // Get subcommands working in the temporary directory - subCmds := getEtcdSubCommands(tmpdir, phaseTestK8sVersion) - - // Execute the subcommand - certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir) - allFlags := append(test.additionalFlags, certDirFlag) - cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...) - - // Checks that requested files are there - testutil.AssertFileExists(t, tmpdir, test.expectedFiles...) - } -} diff --git a/cmd/kubeadm/app/cmd/phases/kubeconfig.go b/cmd/kubeadm/app/cmd/phases/kubeconfig.go index 53a6b607c0936..d7160ccef92cc 100644 --- a/cmd/kubeadm/app/cmd/phases/kubeconfig.go +++ b/cmd/kubeadm/app/cmd/phases/kubeconfig.go @@ -1,5 +1,5 @@ /* -Copyright 2017 The Kubernetes Authors. +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. @@ -18,175 +18,133 @@ package phases import ( "fmt" - "io" - "path/filepath" - - "github.com/spf13/cobra" + "github.com/pkg/errors" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" - kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - allKubeconfigLongDesc = normalizer.LongDesc(` - Generates all kubeconfig files necessary to establish the control plane and the admin kubeconfig file. - ` + cmdutil.AlphaDisclaimer) - - allKubeconfigExample = normalizer.Examples(` - # Generates all kubeconfig files, functionally equivalent to what generated - # by kubeadm init. - kubeadm alpha phase kubeconfig all - - # Generates all kubeconfig files using options read from a configuration file. - kubeadm alpha phase kubeconfig all --config masterconfiguration.yaml - `) - - adminKubeconfigLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the kubeconfig file for the admin and for kubeadm itself, and saves it to %s file. - `+cmdutil.AlphaDisclaimer), kubeadmconstants.AdminKubeConfigFileName) - - kubeletKubeconfigLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the kubeconfig file for the kubelet to use and saves it to %s file. - - Please note that this should *only* be used for bootstrapping purposes. After your control plane is up, - you should request all kubelet credentials from the CSR API. - `+cmdutil.AlphaDisclaimer), filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)) - - controllerManagerKubeconfigLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the kubeconfig file for the controller manager to use and saves it to %s file. - `+cmdutil.AlphaDisclaimer), filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ControllerManagerKubeConfigFileName)) - - schedulerKubeconfigLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the kubeconfig file for the scheduler to use and saves it to %s file. - `+cmdutil.AlphaDisclaimer), filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.SchedulerKubeConfigFileName)) - - userKubeconfigLongDesc = normalizer.LongDesc(` - Outputs a kubeconfig file for an additional user. - ` + cmdutil.AlphaDisclaimer) - - userKubeconfigExample = normalizer.Examples(` - # Outputs a kubeconfig file for an additional user named foo - kubeadm alpha phase kubeconfig user --client-name=foo - `) + kubeconfigFilePhaseProperties = map[string]struct { + name string + short string + long string + }{ + kubeadmconstants.AdminKubeConfigFileName: { + name: "admin", + short: "Generates a kubeconfig file for the admin to use and for kubeadm itself", + long: "Generates the kubeconfig file for the admin and for kubeadm itself, and saves it to %s file.", + }, + kubeadmconstants.KubeletKubeConfigFileName: { + name: "kubelet", + short: "Generates a kubeconfig file for the kubelet to use *only* for cluster bootstrapping purposes", + long: normalizer.LongDesc(` + Generates the kubeconfig file for the kubelet to use and saves it to %s file. + + Please note that this should *only* be used for cluster bootstrapping purposes. After your control plane is up, + you should request all kubelet credentials from the CSR API.`), + }, + kubeadmconstants.ControllerManagerKubeConfigFileName: { + name: "controller-manager", + short: "Generates a kubeconfig file for the controller manager to use", + long: "Generates the kubeconfig file for the controller manager to use and saves it to %s file", + }, + kubeadmconstants.SchedulerKubeConfigFileName: { + name: "scheduler", + short: "Generates a kubeconfig file for the scheduler to use", + long: "Generates the kubeconfig file for the scheduler to use and saves it to %s file.", + }, + } ) -// NewCmdKubeConfig returns main command for kubeconfig phase -func NewCmdKubeConfig(out io.Writer) *cobra.Command { - cmd := &cobra.Command{ - Use: "kubeconfig", +// kubeConfigData defines the behavior that a runtime data struct passed to the kubeconfig phase +// should have. Please note that we are using an interface in order to make this phase reusable in different workflows +// (and thus with different runtime data struct, all of them requested to be compliant to this interface) +type kubeConfigData interface { + Cfg() *kubeadmapi.InitConfiguration + ExternalCA() bool + CertificateDir() string + CertificateWriteDir() string + KubeConfigDir() string +} + +// NewKubeConfigPhase creates a kubeadm workflow phase that creates all kubeconfig files necessary to establish the control plane and the admin kubeconfig file. +func NewKubeConfigPhase() workflow.Phase { + return workflow.Phase{ + Name: "kubeconfig", Short: "Generates all kubeconfig files necessary to establish the control plane and the admin kubeconfig file", - Long: cmdutil.MacroCommandLongDescription, + Phases: []workflow.Phase{ + NewKubeConfigFilePhase(kubeadmconstants.AdminKubeConfigFileName), + NewKubeConfigFilePhase(kubeadmconstants.KubeletKubeConfigFileName), + NewKubeConfigFilePhase(kubeadmconstants.ControllerManagerKubeConfigFileName), + NewKubeConfigFilePhase(kubeadmconstants.SchedulerKubeConfigFileName), + }, + Run: runKubeConfig, + CmdFlags: getKubeConfigPhaseFlags("all"), } - - cmd.AddCommand(getKubeConfigSubCommands(out, kubeadmconstants.KubernetesDir, "")...) - return cmd } -// getKubeConfigSubCommands returns sub commands for kubeconfig phase -func getKubeConfigSubCommands(out io.Writer, outDir, defaultKubernetesVersion string) []*cobra.Command { - - cfg := &kubeadmapiv1beta1.InitConfiguration{} - - // Default values for the cobra help text - kubeadmscheme.Scheme.Default(cfg) +// NewKubeConfigFilePhase creates a kubeadm workflow phase that creates a kubeconfig file. +func NewKubeConfigFilePhase(kubeConfigFileName string) workflow.Phase { + return workflow.Phase{ + Name: kubeconfigFilePhaseProperties[kubeConfigFileName].name, + Short: kubeconfigFilePhaseProperties[kubeConfigFileName].short, + Long: fmt.Sprintf(kubeconfigFilePhaseProperties[kubeConfigFileName].long, kubeConfigFileName), + Run: runKubeConfigFile(kubeConfigFileName), + CmdFlags: getKubeConfigPhaseFlags(kubeConfigFileName), + } +} - var cfgPath, token, clientName string - var organizations []string - var subCmds []*cobra.Command +func getKubeConfigPhaseFlags(name string) []string { + flags := []string{ + options.APIServerAdvertiseAddress, + options.APIServerBindPort, + options.CertificatesDir, + options.CfgPath, + options.KubeconfigDir, + } + if name == "all" || name == kubeadmconstants.KubeletKubeConfigFileName { + flags = append(flags, + options.NodeName, + ) + } + return flags +} - subCmdProperties := []struct { - use string - short string - long string - examples string - cmdFunc func(outDir string, cfg *kubeadmapi.InitConfiguration) error - }{ - { - use: "all", - short: "Generates all kubeconfig files necessary to establish the control plane and the admin kubeconfig file", - long: allKubeconfigLongDesc, - examples: allKubeconfigExample, - cmdFunc: kubeconfigphase.CreateInitKubeConfigFiles, - }, - { - use: "admin", - short: "Generates a kubeconfig file for the admin to use and for kubeadm itself", - long: adminKubeconfigLongDesc, - cmdFunc: kubeconfigphase.CreateAdminKubeConfigFile, - }, - { - use: "kubelet", - short: "Generates a kubeconfig file for the kubelet to use. Please note that this should be used *only* for bootstrapping purposes", - long: kubeletKubeconfigLongDesc, - cmdFunc: kubeconfigphase.CreateKubeletKubeConfigFile, - }, - { - use: "controller-manager", - short: "Generates a kubeconfig file for the controller manager to use", - long: controllerManagerKubeconfigLongDesc, - cmdFunc: kubeconfigphase.CreateControllerManagerKubeConfigFile, - }, - { - use: "scheduler", - short: "Generates a kubeconfig file for the scheduler to use", - long: schedulerKubeconfigLongDesc, - cmdFunc: kubeconfigphase.CreateSchedulerKubeConfigFile, - }, - { - use: "user", - short: "Outputs a kubeconfig file for an additional user", - long: userKubeconfigLongDesc, - examples: userKubeconfigExample, - cmdFunc: func(outDir string, cfg *kubeadmapi.InitConfiguration) error { - if clientName == "" { - return fmt.Errorf("missing required argument --client-name") - } - - // if the kubeconfig file for an additional user has to use a token, use it - if token != "" { - return kubeconfigphase.WriteKubeConfigWithToken(out, cfg, clientName, token) - } - - // Otherwise, write a kubeconfig file with a generate client cert - return kubeconfigphase.WriteKubeConfigWithClientCert(out, cfg, clientName, organizations) - }, - }, +func runKubeConfig(c workflow.RunData) error { + data, ok := c.(kubeConfigData) + if !ok { + return errors.New("kubeconfig phase invoked with an invalid data struct") } - for _, properties := range subCmdProperties { - // Creates the UX Command - cmd := &cobra.Command{ - Use: properties.use, - Short: properties.short, - Long: properties.long, - Example: properties.examples, - Run: runCmdPhase(properties.cmdFunc, &outDir, &cfgPath, cfg, defaultKubernetesVersion), - } + fmt.Printf("[kubeconfig] Using kubeconfig folder %q\n", data.KubeConfigDir()) + return nil +} - // Add flags to the command - if properties.use != "user" { - cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental") - } - cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where certificates are stored") - cmd.Flags().StringVar(&cfg.APIEndpoint.AdvertiseAddress, "apiserver-advertise-address", cfg.APIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on") - cmd.Flags().Int32Var(&cfg.APIEndpoint.BindPort, "apiserver-bind-port", cfg.APIEndpoint.BindPort, "The port the API server is accessible on") - cmd.Flags().StringVar(&outDir, "kubeconfig-dir", outDir, "The path where to save the kubeconfig file") - if properties.use == "all" || properties.use == "kubelet" { - cmd.Flags().StringVar(&cfg.NodeRegistration.Name, "node-name", cfg.NodeRegistration.Name, `The node name that should be used for the kubelet client certificate`) +// runKubeConfigFile executes kubeconfig creation logic. +func runKubeConfigFile(kubeConfigFileName string) func(workflow.RunData) error { + return func(c workflow.RunData) error { + data, ok := c.(kubeConfigData) + if !ok { + return errors.New("kubeconfig phase invoked with an invalid data struct") } - if properties.use == "user" { - cmd.Flags().StringVar(&token, "token", token, "The token that should be used as the authentication mechanism for this kubeconfig, instead of client certificates") - cmd.Flags().StringVar(&clientName, "client-name", clientName, "The name of user. It will be used as the CN if client certificates are created") - cmd.Flags().StringSliceVar(&organizations, "org", organizations, "The orgnizations of the client certificate. It will be used as the O if client certificates are created") + + // if external CA mode, skip certificate authority generation + if data.ExternalCA() { + fmt.Printf("[kubeconfig] External CA mode: Using user provided %s\n", kubeConfigFileName) + return nil } - subCmds = append(subCmds, cmd) - } + // if dryrunning, reads certificates from a temporary folder (and defer restore to the path originally specified by the user) + cfg := data.Cfg() + cfg.CertificatesDir = data.CertificateWriteDir() + defer func() { cfg.CertificatesDir = data.CertificateDir() }() - return subCmds + // creates the KubeConfig file (or use existing) + return kubeconfigphase.CreateKubeConfigFile(kubeConfigFileName, data.KubeConfigDir(), data.Cfg()) + } } diff --git a/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go b/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go deleted file mode 100644 index 56eefc876f452..0000000000000 --- a/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go +++ /dev/null @@ -1,390 +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 phases - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - "testing" - - "k8s.io/client-go/tools/clientcmd" - kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" - - testutil "k8s.io/kubernetes/cmd/kubeadm/test" - cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd" - kubeconfigtestutil "k8s.io/kubernetes/cmd/kubeadm/test/kubeconfig" -) - -func TestKubeConfigCSubCommandsHasFlags(t *testing.T) { - - subCmds := getKubeConfigSubCommands(nil, "", phaseTestK8sVersion) - - commonFlags := []string{ - "cert-dir", - "apiserver-advertise-address", - "apiserver-bind-port", - "kubeconfig-dir", - } - - var tests = []struct { - command string - additionalFlags []string - }{ - { - command: "all", - additionalFlags: []string{ - "config", - "node-name", - }, - }, - { - command: "admin", - additionalFlags: []string{ - "config", - }, - }, - { - command: "kubelet", - additionalFlags: []string{ - "config", - "node-name", - }, - }, - { - command: "controller-manager", - additionalFlags: []string{ - "config", - }, - }, - { - command: "scheduler", - additionalFlags: []string{ - "config", - }, - }, - { - command: "user", - additionalFlags: []string{ - "token", - "client-name", - }, - }, - } - - for _, test := range tests { - expectedFlags := append(commonFlags, test.additionalFlags...) - cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...) - } -} - -func TestKubeConfigSubCommandsThatCreateFilesWithFlags(t *testing.T) { - - commonFlags := []string{ - "--apiserver-advertise-address=1.2.3.4", - "--apiserver-bind-port=1234", - } - - var tests = []struct { - command string - additionalFlags []string - expectedFiles []string - }{ - { - command: "all", - additionalFlags: []string{"--node-name=valid-nome-name"}, - expectedFiles: []string{ - kubeadmconstants.AdminKubeConfigFileName, - kubeadmconstants.KubeletKubeConfigFileName, - kubeadmconstants.ControllerManagerKubeConfigFileName, - kubeadmconstants.SchedulerKubeConfigFileName, - }, - }, - { - command: "admin", - expectedFiles: []string{kubeadmconstants.AdminKubeConfigFileName}, - }, - { - command: "kubelet", - additionalFlags: []string{"--node-name=valid-nome-name"}, - expectedFiles: []string{kubeadmconstants.KubeletKubeConfigFileName}, - }, - { - command: "controller-manager", - expectedFiles: []string{kubeadmconstants.ControllerManagerKubeConfigFileName}, - }, - { - command: "scheduler", - expectedFiles: []string{kubeadmconstants.SchedulerKubeConfigFileName}, - }, - } - - var kubeConfigAssertions = map[string]struct { - clientName string - organizations []string - }{ - kubeadmconstants.AdminKubeConfigFileName: { - clientName: "kubernetes-admin", - organizations: []string{kubeadmconstants.MastersGroup}, - }, - kubeadmconstants.KubeletKubeConfigFileName: { - clientName: "system:node:valid-nome-name", - organizations: []string{kubeadmconstants.NodesGroup}, - }, - kubeadmconstants.ControllerManagerKubeConfigFileName: { - clientName: kubeadmconstants.ControllerManagerUser, - }, - kubeadmconstants.SchedulerKubeConfigFileName: { - clientName: kubeadmconstants.SchedulerUser, - }, - } - - for _, test := range tests { - - // Create temp folder for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - // Adds a pki folder with a ca certs to the temp folder - pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir) - - outputdir := tmpdir - - // Retrieves ca cert for assertions - caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkidir, kubeadmconstants.CACertAndKeyBaseName) - if err != nil { - t.Fatalf("couldn't retrieve ca cert: %v", err) - } - - // Get subcommands working in the temporary directory - subCmds := getKubeConfigSubCommands(nil, tmpdir, phaseTestK8sVersion) - - // Execute the subcommand - certDirFlag := fmt.Sprintf("--cert-dir=%s", pkidir) - outputDirFlag := fmt.Sprintf("--kubeconfig-dir=%s", outputdir) - allFlags := append(commonFlags, certDirFlag) - allFlags = append(allFlags, outputDirFlag) - allFlags = append(allFlags, test.additionalFlags...) - cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...) - - // Checks that requested files are there - testutil.AssertFileExists(t, tmpdir, test.expectedFiles...) - - // Checks contents of generated files - for _, file := range test.expectedFiles { - - // reads generated files - config, err := clientcmd.LoadFromFile(filepath.Join(tmpdir, file)) - if err != nil { - t.Errorf("couldn't load generated kubeconfig file: %v", err) - } - - // checks that CLI flags are properly propagated and kubeconfig properties are correct - kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert) - - expectedClientName := kubeConfigAssertions[file].clientName - expectedOrganizations := kubeConfigAssertions[file].organizations - kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, expectedClientName, expectedOrganizations...) - - } - } -} - -func TestKubeConfigSubCommandsThatCreateFilesWithConfigFile(t *testing.T) { - - var tests = []struct { - command string - expectedFiles []string - }{ - { - command: "all", - expectedFiles: []string{ - kubeadmconstants.AdminKubeConfigFileName, - kubeadmconstants.KubeletKubeConfigFileName, - kubeadmconstants.ControllerManagerKubeConfigFileName, - kubeadmconstants.SchedulerKubeConfigFileName, - }, - }, - { - command: "admin", - expectedFiles: []string{kubeadmconstants.AdminKubeConfigFileName}, - }, - { - command: "kubelet", - expectedFiles: []string{kubeadmconstants.KubeletKubeConfigFileName}, - }, - { - command: "controller-manager", - expectedFiles: []string{kubeadmconstants.ControllerManagerKubeConfigFileName}, - }, - { - command: "scheduler", - expectedFiles: []string{kubeadmconstants.SchedulerKubeConfigFileName}, - }, - } - - var kubeConfigAssertions = map[string]struct { - clientName string - organizations []string - }{ - kubeadmconstants.AdminKubeConfigFileName: { - clientName: "kubernetes-admin", - organizations: []string{kubeadmconstants.MastersGroup}, - }, - kubeadmconstants.KubeletKubeConfigFileName: { - clientName: "system:node:valid-node-name", - organizations: []string{kubeadmconstants.NodesGroup}, - }, - kubeadmconstants.ControllerManagerKubeConfigFileName: { - clientName: kubeadmconstants.ControllerManagerUser, - }, - kubeadmconstants.SchedulerKubeConfigFileName: { - clientName: kubeadmconstants.SchedulerUser, - }, - } - - for _, test := range tests { - - // Create temp folder for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - // Adds a pki folder with a ca certs to the temp folder - pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir) - - // Retrieves ca cert for assertions - caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkidir, kubeadmconstants.CACertAndKeyBaseName) - if err != nil { - t.Fatalf("couldn't retrieve ca cert: %v", err) - } - - // Adds a master configuration file - cfg := &kubeadmapi.InitConfiguration{ - APIEndpoint: kubeadmapi.APIEndpoint{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, - ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - CertificatesDir: pkidir, - }, - NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, - } - cfgPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg) - - // Get subcommands working in the temporary directory - subCmds := getKubeConfigSubCommands(nil, tmpdir, phaseTestK8sVersion) - - // Execute the subcommand - configFlag := fmt.Sprintf("--config=%s", cfgPath) - cmdtestutil.RunSubCommand(t, subCmds, test.command, configFlag) - - // Checks that requested files are there - testutil.AssertFileExists(t, tmpdir, test.expectedFiles...) - - // Checks contents of generated files - for _, file := range test.expectedFiles { - - // reads generated files - config, err := clientcmd.LoadFromFile(filepath.Join(tmpdir, file)) - if err != nil { - t.Errorf("couldn't load generated kubeconfig file: %v", err) - } - - // checks that config file properties are properly propagated and kubeconfig properties are correct - kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert) - - expectedClientName := kubeConfigAssertions[file].clientName - expectedOrganizations := kubeConfigAssertions[file].organizations - kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, expectedClientName, expectedOrganizations...) - - } - } -} - -func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) { - - // Temporary folders for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - // Adds a pki folder with a ca cert to the temp folder - pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir) - - outputdir := tmpdir - - // Retrieves ca cert for assertions - caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkidir, kubeadmconstants.CACertAndKeyBaseName) - if err != nil { - t.Fatalf("couldn't retrieve ca cert: %v", err) - } - - commonFlags := []string{ - "--apiserver-advertise-address=1.2.3.4", - "--apiserver-bind-port=1234", - "--client-name=myUser", - fmt.Sprintf("--cert-dir=%s", pkidir), - fmt.Sprintf("--kubeconfig-dir=%s", outputdir), - } - - var tests = []struct { - command string - withClientCert bool - withToken bool - additionalFlags []string - }{ - { // Test user subCommand withClientCert - command: "user", - withClientCert: true, - }, - { // Test user subCommand withToken - withToken: true, - command: "user", - additionalFlags: []string{"--token=123456"}, - }, - } - - for _, test := range tests { - buf := new(bytes.Buffer) - - // Get subcommands working in the temporary directory - subCmds := getKubeConfigSubCommands(buf, tmpdir, phaseTestK8sVersion) - - // Execute the subcommand - allFlags := append(commonFlags, test.additionalFlags...) - cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...) - - // reads kubeconfig written to stdout - config, err := clientcmd.Load(buf.Bytes()) - if err != nil { - t.Errorf("couldn't read kubeconfig file from buffer: %v", err) - continue - } - - // checks that CLI flags are properly propagated - kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert) - - if test.withClientCert { - // checks that kubeconfig files have expected client cert - kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, "myUser") - } - - if test.withToken { - // checks that kubeconfig files have expected token - kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithToken(t, config, "myUser", "123456") - } - } -} diff --git a/cmd/kubeadm/app/cmd/phases/kubelet.go b/cmd/kubeadm/app/cmd/phases/kubelet.go index 8c5b054981c44..72ef901e61d6b 100644 --- a/cmd/kubeadm/app/cmd/phases/kubelet.go +++ b/cmd/kubeadm/app/cmd/phases/kubelet.go @@ -17,357 +17,78 @@ limitations under the License. package phases import ( - "fmt" - - "github.com/spf13/cobra" - - "k8s.io/apimachinery/pkg/util/version" + "github.com/golang/glog" + "github.com/pkg/errors" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" - "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" - patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode" - "k8s.io/kubernetes/cmd/kubeadm/app/preflight" - kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" - configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" - kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" "k8s.io/kubernetes/pkg/util/normalizer" - utilsexec "k8s.io/utils/exec" ) var ( - kubeletWriteEnvFileLongDesc = normalizer.LongDesc(` - Writes an environment file with flags that should be passed to the kubelet executing on the master or node. - This --config flag can either consume a InitConfiguration object or a JoinConfiguration one, as this - function is used for both "kubeadm init" and "kubeadm join". - ` + cmdutil.AlphaDisclaimer) - - kubeletWriteEnvFileExample = normalizer.Examples(` + kubeletStartPhaseExample = normalizer.Examples(` # Writes a dynamic environment file with kubelet flags from a InitConfiguration file. - kubeadm alpha phase kubelet write-env-file --config masterconfig.yaml - - # Writes a dynamic environment file with kubelet flags from a JoinConfiguration file. - kubeadm alpha phase kubelet write-env-file --config nodeconfig.yaml - `) - - kubeletConfigUploadLongDesc = normalizer.LongDesc(` - Uploads kubelet configuration extracted from the kubeadm InitConfiguration object to a ConfigMap - of the form kubelet-config-1.X in the cluster, where X is the minor version of the current (API Server) Kubernetes version. - ` + cmdutil.AlphaDisclaimer) - - kubeletConfigUploadExample = normalizer.Examples(` - # Uploads the kubelet configuration from the kubeadm Config file to a ConfigMap in the cluster. - kubeadm alpha phase kubelet config upload --config kubeadm.yaml - `) - - kubeletConfigAnnotateCRILongDesc = normalizer.LongDesc(` - Adds an annotation to the current node with the CRI socket specified in the kubeadm InitConfiguration object. - ` + cmdutil.AlphaDisclaimer) - - kubeletConfigAnnotateCRIExample = normalizer.Examples(` - kubeadm alpha phase kubelet config annotate-cri --config kubeadm.yaml - `) - - kubeletConfigDownloadLongDesc = normalizer.LongDesc(` - Downloads the kubelet configuration from a ConfigMap of the form "kubelet-config-1.X" in the cluster, - where X is the minor version of the kubelet. Either kubeadm autodetects the kubelet version by exec-ing - "kubelet --version" or respects the --kubelet-version parameter. - ` + cmdutil.AlphaDisclaimer) - - kubeletConfigDownloadExample = normalizer.Examples(` - # Downloads the kubelet configuration from the ConfigMap in the cluster. Autodetects the kubelet version. - kubeadm alpha phase kubelet config download - - # Downloads the kubelet configuration from the ConfigMap in the cluster. Uses a specific desired kubelet version. - kubeadm alpha phase kubelet config download --kubelet-version v1.12.0 - `) - - kubeletConfigWriteToDiskLongDesc = normalizer.LongDesc(` - Writes kubelet configuration to disk, based on the kubeadm configuration passed via "--config". - ` + cmdutil.AlphaDisclaimer) - - kubeletConfigWriteToDiskExample = normalizer.Examples(` - # Extracts the kubelet configuration from a kubeadm configuration file - kubeadm alpha phase kubelet config write-to-disk --config kubeadm.yaml - `) - - kubeletConfigEnableDynamicLongDesc = normalizer.LongDesc(` - Enables or updates dynamic kubelet configuration for a Node, against the kubelet-config-1.X ConfigMap in the cluster, - where X is the minor version of the desired kubelet version. - - WARNING: This feature is still experimental, and disabled by default. Enable only if you know what you are doing, as it - may have surprising side-effects at this stage. - - ` + cmdutil.AlphaDisclaimer) - - kubeletConfigEnableDynamicExample = normalizer.Examples(` - # Enables dynamic kubelet configuration for a Node. - kubeadm alpha phase kubelet enable-dynamic-config --node-name node-1 --kubelet-version v1.12.0 - - WARNING: This feature is still experimental, and disabled by default. Enable only if you know what you are doing, as it - may have surprising side-effects at this stage. + kubeadm init phase kubelet-start --config masterconfig.yaml `) ) -// NewCmdKubelet returns command for `kubeadm phase kubelet` -func NewCmdKubelet() *cobra.Command { - cmd := &cobra.Command{ - Use: "kubelet", - Short: "Commands related to handling the kubelet.", - Long: cmdutil.MacroCommandLongDescription, - } - - cmd.AddCommand(NewCmdKubeletConfig()) - cmd.AddCommand(NewCmdKubeletWriteEnvFile()) - return cmd -} - -// NewCmdKubeletWriteEnvFile calls cobra.Command for writing the dynamic kubelet env file based on a InitConfiguration or JoinConfiguration object -func NewCmdKubeletWriteEnvFile() *cobra.Command { - var cfgPath string - - cmd := &cobra.Command{ - Use: "write-env-file", - Short: "Writes an environment file with runtime flags for the kubelet.", - Long: kubeletWriteEnvFileLongDesc, - Example: kubeletWriteEnvFileExample, - Run: func(cmd *cobra.Command, args []string) { - if len(cfgPath) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("The --config flag is mandatory")) - } - - err := RunKubeletWriteEnvFile(cfgPath) - kubeadmutil.CheckErr(err) - }, - } - - options.AddConfigFlag(cmd.Flags(), &cfgPath) - return cmd -} - -// RunKubeletWriteEnvFile is the function that is run when "kubeadm phase kubelet write-env-file" is executed -func RunKubeletWriteEnvFile(cfgPath string) error { - internalcfg, err := configutil.AnyConfigFileAndDefaultsToInternal(cfgPath) - if err != nil { - return err - } - - var nodeRegistrationObj *kubeadmapi.NodeRegistrationOptions - var featureGates map[string]bool - var registerWithTaints bool - - switch cfg := internalcfg.(type) { - case *kubeadmapi.InitConfiguration: - nodeRegistrationObj = &cfg.NodeRegistration - featureGates = cfg.FeatureGates - registerWithTaints = false - case *kubeadmapi.JoinConfiguration: - nodeRegistrationObj = &cfg.NodeRegistration - featureGates = cfg.FeatureGates - registerWithTaints = true - default: - return fmt.Errorf("couldn't read config file, no matching kind found") - } - - if err := kubeletphase.WriteKubeletDynamicEnvFile(nodeRegistrationObj, featureGates, registerWithTaints, constants.KubeletRunDirectory); err != nil { - return fmt.Errorf("error writing a dynamic environment file for the kubelet: %v", err) - } - return nil -} - -// NewCmdKubeletConfig returns command for `kubeadm phase kubelet config` -func NewCmdKubeletConfig() *cobra.Command { - cmd := &cobra.Command{ - Use: "config", - Short: "Handles kubelet configuration.", - Long: cmdutil.MacroCommandLongDescription, - } - - cmd.AddCommand(NewCmdKubeletConfigUpload()) - cmd.AddCommand(NewCmdKubeletAnnotateCRI()) - cmd.AddCommand(NewCmdKubeletConfigDownload()) - cmd.AddCommand(NewCmdKubeletConfigWriteToDisk()) - cmd.AddCommand(NewCmdKubeletConfigEnableDynamic()) - return cmd +// kubeletStartData defines the behavior that a runtime data struct passed to the kubelet start phase +// should have. Please note that we are using an interface in order to make this phase reusable in different workflows +// (and thus with different runtime data struct, all of them requested to be compliant to this interface) +type kubeletStartData interface { + Cfg() *kubeadmapi.InitConfiguration + DryRun() bool + KubeletDir() string } -// NewCmdKubeletConfigUpload calls cobra.Command for uploading dynamic kubelet configuration -func NewCmdKubeletConfigUpload() *cobra.Command { - cfg := &kubeadmapiv1beta1.InitConfiguration{} - var cfgPath string - kubeConfigFile := constants.GetAdminKubeConfigPath() - - cmd := &cobra.Command{ - Use: "upload", - Short: "Uploads kubelet configuration to a ConfigMap based on a kubeadm InitConfiguration file.", - Long: kubeletConfigUploadLongDesc, - Example: kubeletConfigUploadExample, - Run: func(cmd *cobra.Command, args []string) { - if len(cfgPath) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("The --config argument is required")) - } - - // KubernetesVersion is not used, but we set it explicitly to avoid the lookup - // of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig - SetKubernetesVersion(cfg) - - // This call returns the ready-to-use configuration based on the configuration file - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) - kubeadmutil.CheckErr(err) - - kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) - client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) - kubeadmutil.CheckErr(err) - - err = kubeletphase.CreateConfigMap(internalcfg, client) - kubeadmutil.CheckErr(err) +// NewKubeletStartPhase creates a kubeadm workflow phase that start kubelet on a node. +func NewKubeletStartPhase() workflow.Phase { + return workflow.Phase{ + Name: "kubelet-start", + Short: "Writes kubelet settings and (re)starts the kubelet", + Long: "Writes a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)starts kubelet.", + Example: kubeletStartPhaseExample, + Run: runKubeletStart, + CmdFlags: []string{ + options.CfgPath, + options.NodeCRISocket, + options.NodeName, }, } - - options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile) - options.AddConfigFlag(cmd.Flags(), &cfgPath) - return cmd } -// NewCmdKubeletAnnotateCRI calls cobra.Command for annotating the node with the given crisocket -func NewCmdKubeletAnnotateCRI() *cobra.Command { - cfg := &kubeadmapiv1beta1.InitConfiguration{} - var cfgPath string - kubeConfigFile := constants.GetAdminKubeConfigPath() - - cmd := &cobra.Command{ - Use: "annotate-cri", - Short: "annotates the node with the given crisocket", - Long: kubeletConfigAnnotateCRILongDesc, - Example: kubeletConfigAnnotateCRIExample, - Run: func(cmd *cobra.Command, args []string) { - if len(cfgPath) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("The --config argument is required")) - } - - // KubernetesVersion is not used, but we set it explicitly to avoid the lookup - // of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig - SetKubernetesVersion(cfg) - - // This call returns the ready-to-use configuration based on the configuration file - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) - kubeadmutil.CheckErr(err) - - kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) - client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) - kubeadmutil.CheckErr(err) - - err = patchnodephase.AnnotateCRISocket(client, internalcfg.NodeRegistration.Name, internalcfg.NodeRegistration.CRISocket) - kubeadmutil.CheckErr(err) - }, +// runKubeletStart executes kubelet start logic. +func runKubeletStart(c workflow.RunData) error { + data, ok := c.(kubeletStartData) + if !ok { + return errors.New("kubelet-start phase invoked with an invalid data struct") } - options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile) - options.AddConfigFlag(cmd.Flags(), &cfgPath) - return cmd -} - -// NewCmdKubeletConfigDownload calls cobra.Command for downloading the kubelet configuration from the kubelet-config-1.X ConfigMap in the cluster -func NewCmdKubeletConfigDownload() *cobra.Command { - var kubeletVersionStr string - // TODO: Be smarter about this and be able to load multiple kubeconfig files in different orders of precedence - kubeConfigFile := constants.GetKubeletKubeConfigPath() - - cmd := &cobra.Command{ - Use: "download", - Short: "Downloads the kubelet configuration from the cluster ConfigMap kubelet-config-1.X, where X is the minor version of the kubelet.", - Long: kubeletConfigDownloadLongDesc, - Example: kubeletConfigDownloadExample, - Run: func(cmd *cobra.Command, args []string) { - kubeletVersion, err := getKubeletVersion(kubeletVersionStr) - kubeadmutil.CheckErr(err) - - client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) - kubeadmutil.CheckErr(err) - - err = kubeletphase.DownloadConfig(client, kubeletVersion, constants.KubeletRunDirectory) - kubeadmutil.CheckErr(err) - }, + // First off, configure the kubelet. In this short timeframe, kubeadm is trying to stop/restart the kubelet + // Try to stop the kubelet service so no race conditions occur when configuring it + if !data.DryRun() { + glog.V(1).Infof("Stopping the kubelet") + kubeletphase.TryStopKubelet() } - options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile) - cmd.Flags().StringVar(&kubeletVersionStr, "kubelet-version", kubeletVersionStr, "The desired version for the kubelet. Defaults to being autodetected from 'kubelet --version'.") - return cmd -} - -func getKubeletVersion(kubeletVersionStr string) (*version.Version, error) { - if len(kubeletVersionStr) > 0 { - return version.ParseSemantic(kubeletVersionStr) + // Write env file with flags for the kubelet to use. We do not need to write the --register-with-taints for the master, + // as we handle that ourselves in the markmaster phase + // TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase? + if err := kubeletphase.WriteKubeletDynamicEnvFile(&data.Cfg().NodeRegistration, data.Cfg().FeatureGates, false, data.KubeletDir()); err != nil { + return errors.Wrap(err, "error writing a dynamic environment file for the kubelet") } - return preflight.GetKubeletVersion(utilsexec.New()) -} - -// NewCmdKubeletConfigWriteToDisk calls cobra.Command for writing init kubelet configuration -func NewCmdKubeletConfigWriteToDisk() *cobra.Command { - cfg := &kubeadmapiv1beta1.InitConfiguration{} - var cfgPath string - cmd := &cobra.Command{ - Use: "write-to-disk", - Short: "Writes kubelet configuration to disk, either based on the --config argument.", - Long: kubeletConfigWriteToDiskLongDesc, - Example: kubeletConfigWriteToDiskExample, - Run: func(cmd *cobra.Command, args []string) { - if len(cfgPath) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("The --config argument is required")) - } - - // KubernetesVersion is not used, but we set it explicitly to avoid the lookup - // of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig - SetKubernetesVersion(cfg) - - // This call returns the ready-to-use configuration based on the configuration file - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) - kubeadmutil.CheckErr(err) - err = kubeletphase.WriteConfigToDisk(internalcfg.ComponentConfigs.Kubelet, constants.KubeletRunDirectory) - kubeadmutil.CheckErr(err) - }, + // Write the kubelet configuration file to disk. + if err := kubeletphase.WriteConfigToDisk(data.Cfg().ComponentConfigs.Kubelet, data.KubeletDir()); err != nil { + return errors.Wrap(err, "error writing kubelet configuration to disk") } - options.AddConfigFlag(cmd.Flags(), &cfgPath) - return cmd -} - -// NewCmdKubeletConfigEnableDynamic calls cobra.Command for enabling dynamic kubelet configuration on node -// This feature is still in alpha and an experimental state -func NewCmdKubeletConfigEnableDynamic() *cobra.Command { - var nodeName, kubeletVersionStr string - kubeConfigFile := constants.GetAdminKubeConfigPath() - - cmd := &cobra.Command{ - Use: "enable-dynamic", - Short: "EXPERIMENTAL: Enables or updates dynamic kubelet configuration for a Node", - Long: kubeletConfigEnableDynamicLongDesc, - Example: kubeletConfigEnableDynamicExample, - Run: func(cmd *cobra.Command, args []string) { - if len(nodeName) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("The --node-name argument is required")) - } - if len(kubeletVersionStr) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("The --kubelet-version argument is required")) - } - - kubeletVersion, err := version.ParseSemantic(kubeletVersionStr) - kubeadmutil.CheckErr(err) - - kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) - client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) - kubeadmutil.CheckErr(err) - - err = kubeletphase.EnableDynamicConfigForNode(client, nodeName, kubeletVersion) - kubeadmutil.CheckErr(err) - }, + // Try to start the kubelet service in case it's inactive + if !data.DryRun() { + glog.V(1).Infof("Starting the kubelet") + kubeletphase.TryStartKubelet() } - options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile) - cmd.Flags().StringVar(&nodeName, "node-name", nodeName, "Name of the node that should enable the dynamic kubelet configuration") - cmd.Flags().StringVar(&kubeletVersionStr, "kubelet-version", kubeletVersionStr, "The desired version for the kubelet") - return cmd + return nil } diff --git a/cmd/kubeadm/app/cmd/phases/kubelet_test.go b/cmd/kubeadm/app/cmd/phases/kubelet_test.go deleted file mode 100644 index 4abfdd5d7cb1d..0000000000000 --- a/cmd/kubeadm/app/cmd/phases/kubelet_test.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -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 phases - -import ( - "testing" - - "github.com/spf13/cobra" - - cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd" -) - -func TestKubeletSubCommandsHasFlags(t *testing.T) { - subCmds := []*cobra.Command{ - NewCmdKubeletWriteEnvFile(), - NewCmdKubeletConfigUpload(), - NewCmdKubeletConfigDownload(), - NewCmdKubeletConfigWriteToDisk(), - NewCmdKubeletConfigEnableDynamic(), - } - - commonFlags := []string{} - - var tests = []struct { - command string - additionalFlags []string - }{ - { - command: "write-env-file", - additionalFlags: []string{ - "config", - }, - }, - { - command: "upload", - additionalFlags: []string{ - "kubeconfig", - "config", - }, - }, - { - command: "download", - additionalFlags: []string{ - "kubeconfig", - "kubelet-version", - }, - }, - { - command: "write-to-disk", - additionalFlags: []string{ - "config", - }, - }, - { - command: "enable-dynamic", - additionalFlags: []string{ - "kubeconfig", - "node-name", - "kubelet-version", - }, - }, - } - - for _, test := range tests { - expectedFlags := append(commonFlags, test.additionalFlags...) - cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...) - } -} diff --git a/cmd/kubeadm/app/cmd/phases/phase.go b/cmd/kubeadm/app/cmd/phases/phase.go deleted file mode 100644 index 1ecd0a9ad9d0e..0000000000000 --- a/cmd/kubeadm/app/cmd/phases/phase.go +++ /dev/null @@ -1,47 +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 phases - -import ( - "io" - - "github.com/spf13/cobra" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" -) - -// NewCmdPhase returns the cobra command for the "kubeadm phase" command (currently alpha-gated) -func NewCmdPhase(out io.Writer) *cobra.Command { - cmd := &cobra.Command{ - Use: "phase", - Short: "Invoke subsets of kubeadm functions separately for a manual install.", - Long: cmdutil.MacroCommandLongDescription, - } - - cmd.AddCommand(NewCmdAddon()) - cmd.AddCommand(NewCmdBootstrapToken()) - cmd.AddCommand(NewCmdCerts()) - cmd.AddCommand(NewCmdControlplane()) - cmd.AddCommand(NewCmdEtcd()) - cmd.AddCommand(NewCmdKubelet()) - cmd.AddCommand(NewCmdKubeConfig(out)) - cmd.AddCommand(NewCmdMarkMaster()) - cmd.AddCommand(NewCmdPreFlight()) - cmd.AddCommand(NewCmdSelfhosting()) - cmd.AddCommand(NewCmdUploadConfig()) - - return cmd -} diff --git a/cmd/kubeadm/app/cmd/phases/preflight.go b/cmd/kubeadm/app/cmd/phases/preflight.go index ac55b9a379686..3f3aa67b2a6c3 100644 --- a/cmd/kubeadm/app/cmd/phases/preflight.go +++ b/cmd/kubeadm/app/cmd/phases/preflight.go @@ -17,21 +17,14 @@ limitations under the License. package phases import ( - "errors" "fmt" - "github.com/spf13/cobra" + "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/sets" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" - kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" - "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" "k8s.io/kubernetes/cmd/kubeadm/app/preflight" - kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" - configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" "k8s.io/kubernetes/pkg/util/normalizer" utilsexec "k8s.io/utils/exec" ) @@ -41,17 +34,6 @@ var ( # Run master pre-flight checks using a config file. kubeadm init phase preflight --config kubeadm-config.yml `) - - nodePreflightLongDesc = normalizer.LongDesc(` - Run node pre-flight checks, functionally equivalent to what implemented by kubeadm join. - ` + cmdutil.AlphaDisclaimer) - - nodePreflightExample = normalizer.Examples(` - # Run node pre-flight checks. - kubeadm alpha phase preflight node - `) - - errorMissingConfigFlag = errors.New("the --config flag is mandatory") ) // preflightMasterData defines the behavior that a runtime data struct passed to the PreflightMaster master phase @@ -71,6 +53,10 @@ func NewPreflightMasterPhase() workflow.Phase { Long: "Run master pre-flight checks, functionally equivalent to what implemented by kubeadm init.", Example: masterPreflightExample, Run: runPreflightMaster, + CmdFlags: []string{ + options.CfgPath, + options.IgnorePreflightErrors, + }, } } @@ -78,12 +64,12 @@ func NewPreflightMasterPhase() workflow.Phase { func runPreflightMaster(c workflow.RunData) error { data, ok := c.(preflightMasterData) if !ok { - return fmt.Errorf("preflight phase invoked with an invalid data struct") + return errors.New("preflight phase invoked with an invalid data struct") } - fmt.Println("[preflight] running pre-flight checks") + fmt.Println("[preflight] Running pre-flight checks") if err := preflight.RunInitMasterChecks(utilsexec.New(), data.Cfg(), data.IgnorePreflightErrors()); err != nil { - return nil + return err } if !data.DryRun() { @@ -99,56 +85,3 @@ func runPreflightMaster(c workflow.RunData) error { return nil } - -// NewCmdPreFlight calls cobra.Command for preflight checks -func NewCmdPreFlight() *cobra.Command { - var cfgPath string - var ignorePreflightErrors []string - - cmd := &cobra.Command{ - Use: "preflight", - Short: "Run pre-flight checks", - Long: cmdutil.MacroCommandLongDescription, - } - - options.AddConfigFlag(cmd.PersistentFlags(), &cfgPath) - options.AddIgnorePreflightErrorsFlag(cmd.PersistentFlags(), &ignorePreflightErrors) - - cmd.AddCommand(NewCmdPreFlightNode(&cfgPath, &ignorePreflightErrors)) - - return cmd -} - -// NewCmdPreFlightNode calls cobra.Command for node preflight checks -func NewCmdPreFlightNode(cfgPath *string, ignorePreflightErrors *[]string) *cobra.Command { - cmd := &cobra.Command{ - Use: "node", - Short: "Run node pre-flight checks", - Long: nodePreflightLongDesc, - Example: nodePreflightExample, - Run: func(cmd *cobra.Command, args []string) { - if len(*cfgPath) == 0 { - kubeadmutil.CheckErr(errorMissingConfigFlag) - } - ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(*ignorePreflightErrors) - kubeadmutil.CheckErr(err) - - cfg := &kubeadmapiv1beta1.JoinConfiguration{} - kubeadmscheme.Scheme.Default(cfg) - - internalcfg, err := configutil.JoinConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg) - kubeadmutil.CheckErr(err) - err = configutil.VerifyAPIServerBindAddress(internalcfg.APIEndpoint.AdvertiseAddress) - kubeadmutil.CheckErr(err) - - fmt.Println("[preflight] running pre-flight checks") - - err = preflight.RunJoinNodeChecks(utilsexec.New(), internalcfg, ignorePreflightErrorsSet) - kubeadmutil.CheckErr(err) - - fmt.Println("[preflight] pre-flight checks passed") - }, - } - - return cmd -} diff --git a/cmd/kubeadm/app/cmd/phases/selfhosting.go b/cmd/kubeadm/app/cmd/phases/selfhosting.go index 06b3506038d11..6008181a39180 100644 --- a/cmd/kubeadm/app/cmd/phases/selfhosting.go +++ b/cmd/kubeadm/app/cmd/phases/selfhosting.go @@ -95,7 +95,7 @@ func getSelfhostingSubCommand() *cobra.Command { kubeadmutil.CheckErr(err) } - // Gets the kubernetes client + // Gets the Kubernetes client kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) kubeadmutil.CheckErr(err) diff --git a/cmd/kubeadm/app/cmd/phases/uploadconfig.go b/cmd/kubeadm/app/cmd/phases/uploadconfig.go index 595c252038286..f7318f03122f0 100644 --- a/cmd/kubeadm/app/cmd/phases/uploadconfig.go +++ b/cmd/kubeadm/app/cmd/phases/uploadconfig.go @@ -19,69 +19,127 @@ package phases import ( "fmt" - "github.com/spf13/cobra" - + "github.com/golang/glog" + "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" + clientset "k8s.io/client-go/kubernetes" + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" + kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" + patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode" "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig" - kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" - configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" - kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - uploadConfigLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Uploads the kubeadm init configuration of your cluster to a ConfigMap called %s in the %s namespace. + uploadKubeadmConfigLongDesc = fmt.Sprintf(normalizer.LongDesc(` + Uploads the kubeadm ClusterConfiguration to a ConfigMap called %s in the %s namespace. This enables correct configuration of system components and a seamless user experience when upgrading. Alternatively, you can use kubeadm config. - `+cmdutil.AlphaDisclaimer), kubeadmconstants.KubeadmConfigConfigMap, metav1.NamespaceSystem) + `), kubeadmconstants.KubeadmConfigConfigMap, metav1.NamespaceSystem) - uploadConfigExample = normalizer.Examples(` + uploadKubeadmConfigExample = normalizer.Examples(` # uploads the configuration of your cluster kubeadm alpha phase upload-config --config=myConfig.yaml `) + + uploadKubeletConfigLongDesc = normalizer.LongDesc(` + Uploads kubelet configuration extracted from the kubeadm InitConfiguration object to a ConfigMap + of the form kubelet-config-1.X in the cluster, where X is the minor version of the current (API Server) Kubernetes version. + `) + + uploadKubeletConfigExample = normalizer.Examples(` + # Uploads the kubelet configuration from the kubeadm Config file to a ConfigMap in the cluster. + kubeadm init phase upload-config kubelet --config kubeadm.yaml + `) ) -// NewCmdUploadConfig returns the Cobra command for running the uploadconfig phase -func NewCmdUploadConfig() *cobra.Command { - cfg := &kubeadmapiv1beta1.InitConfiguration{} - kubeConfigFile := kubeadmconstants.GetAdminKubeConfigPath() - var cfgPath string - - cmd := &cobra.Command{ - Use: "upload-config", - Short: "Uploads the currently used configuration for kubeadm to a ConfigMap", - Long: uploadConfigLongDesc, - Example: uploadConfigExample, +type uploadConfigData interface { + Cfg() *kubeadmapi.InitConfiguration + Client() (clientset.Interface, error) +} + +// NewUploadConfigPhase returns the phase to uploadConfig +func NewUploadConfigPhase() workflow.Phase { + return workflow.Phase{ + Name: "upload-config", Aliases: []string{"uploadconfig"}, - Run: func(_ *cobra.Command, args []string) { - if len(cfgPath) == 0 { - kubeadmutil.CheckErr(fmt.Errorf("the --config flag is mandatory")) - } + Short: "Uploads the kubeadm and kubelet configuration to a ConfigMap", + Long: cmdutil.MacroCommandLongDescription, + Phases: []workflow.Phase{ + { + Name: "kubeadm", + Short: "Uploads the kubeadm ClusterConfiguration to a ConfigMap", + Long: uploadKubeadmConfigLongDesc, + Example: uploadKubeadmConfigExample, + Run: runUploadKubeadmConfig, + CmdFlags: getUploadConfigPhaseFlags(), + }, + { + Name: "kubelet", + Short: "Uploads the kubelet component config to a ConfigMap", + Long: uploadKubeletConfigLongDesc, + Example: uploadKubeletConfigExample, + Run: runUploadKubeletConfig, + CmdFlags: getUploadConfigPhaseFlags(), + }, + }, + } +} + +func getUploadConfigPhaseFlags() []string { + return []string{ + options.CfgPath, + options.KubeconfigPath, + } +} - kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) - client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile) - kubeadmutil.CheckErr(err) +// runUploadKubeadmConfig uploads the kubeadm configuration to a ConfigMap +func runUploadKubeadmConfig(c workflow.RunData) error { + cfg, client, err := getUploadConfigData(c) + if err != nil { + return err + } - // KubernetesVersion is not used, but we set it explicitly to avoid the lookup - // of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig - SetKubernetesVersion(cfg) + glog.V(1).Infof("[upload-config] Uploading the kubeadm ClusterConfiguration to a ConfigMap") + if err := uploadconfig.UploadConfiguration(cfg, client); err != nil { + return errors.Wrap(err, "error uploading the kubeadm ClusterConfiguration") + } + return nil +} - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) - kubeadmutil.CheckErr(err) +// runUploadKubeletConfig uploads the kubelet configuration to a ConfigMap +func runUploadKubeletConfig(c workflow.RunData) error { + cfg, client, err := getUploadConfigData(c) + if err != nil { + return err + } - err = uploadconfig.UploadConfiguration(internalcfg, client) - kubeadmutil.CheckErr(err) - }, + glog.V(1).Infof("[upload-config] Uploading the kubelet component config to a ConfigMap") + if err = kubeletphase.CreateConfigMap(cfg, client); err != nil { + return errors.Wrap(err, "error creating kubelet configuration ConfigMap") } - options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile) - cmd.Flags().StringVar(&cfgPath, "config", "", "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental") + glog.V(1).Infof("[upload-config] Preserving the CRISocket information for the control-plane node") + if err := patchnodephase.AnnotateCRISocket(client, cfg.NodeRegistration.Name, cfg.NodeRegistration.CRISocket); err != nil { + return errors.Wrap(err, "Error writing Crisocket information for the control-plane node") + } + return nil +} - return cmd +func getUploadConfigData(c workflow.RunData) (*kubeadmapi.InitConfiguration, clientset.Interface, error) { + data, ok := c.(uploadConfigData) + if !ok { + return nil, nil, errors.New("upload-config phase invoked with an invalid data struct") + } + cfg := data.Cfg() + client, err := data.Client() + if err != nil { + return nil, nil, err + } + return cfg, client, err } diff --git a/cmd/kubeadm/app/cmd/phases/waitcontrolplane.go b/cmd/kubeadm/app/cmd/phases/waitcontrolplane.go new file mode 100644 index 0000000000000..4c6ac4be85b52 --- /dev/null +++ b/cmd/kubeadm/app/cmd/phases/waitcontrolplane.go @@ -0,0 +1,153 @@ +/* +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 phases + +import ( + "fmt" + "io" + "path/filepath" + "text/template" + "time" + + "github.com/golang/glog" + "github.com/pkg/errors" + "github.com/renstrom/dedent" + clientset "k8s.io/client-go/kubernetes" + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" + kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" + dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun" +) + +var ( + kubeletFailTempl = template.Must(template.New("init").Parse(dedent.Dedent(` + Unfortunately, an error has occurred: + {{ .Error }} + + This error is likely caused by: + - The kubelet is not running + - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled) + + If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands: + - 'systemctl status kubelet' + - 'journalctl -xeu kubelet' + + Additionally, a control plane component may have crashed or exited when started by the container runtime. + To troubleshoot, list all containers using your preferred container runtimes CLI, e.g. docker. + Here is one example how you may list all Kubernetes containers running in docker: + - 'docker ps -a | grep kube | grep -v pause' + Once you have found the failing container, you can inspect its logs with: + - 'docker logs CONTAINERID' + `))) +) + +type waitControlPlaneData interface { + Cfg() *kubeadmapi.InitConfiguration + ManifestDir() string + DryRun() bool + Client() (clientset.Interface, error) + OutputWriter() io.Writer +} + +// NewWaitControlPlanePhase is a hidden phase that runs after the control-plane and etcd phases +func NewWaitControlPlanePhase() workflow.Phase { + phase := workflow.Phase{ + Name: "wait-control-plane", + Run: runWaitControlPlanePhase, + Hidden: true, + } + return phase +} + +func runWaitControlPlanePhase(c workflow.RunData) error { + data, ok := c.(waitControlPlaneData) + if !ok { + return errors.New("wait-control-plane phase invoked with an invalid data struct") + } + + // If we're dry-running, print the generated manifests + if err := printFilesIfDryRunning(data); err != nil { + return errors.Wrap(err, "error printing files on dryrun") + } + + // waiter holds the apiclient.Waiter implementation of choice, responsible for querying the API server in various ways and waiting for conditions to be fulfilled + glog.V(1).Infof("[wait-control-plane] Waiting for the API server to be healthy") + + client, err := data.Client() + if err != nil { + return errors.Wrap(err, "cannot obtain client") + } + + timeout := data.Cfg().ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration + waiter, err := NewControlPlaneWaiter(data.DryRun(), timeout, client, data.OutputWriter()) + if err != nil { + return errors.Wrap(err, "error creating waiter") + } + + fmt.Printf("[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory %q. This can take up to %v\n", data.ManifestDir(), timeout) + + if err := waiter.WaitForKubeletAndFunc(waiter.WaitForAPI); err != nil { + ctx := map[string]string{ + "Error": fmt.Sprintf("%v", err), + } + kubeletFailTempl.Execute(data.OutputWriter(), ctx) + return errors.New("couldn't initialize a Kubernetes cluster") + } + + return nil +} + +// printFilesIfDryRunning prints the Static Pod manifests to stdout and informs about the temporary directory to go and lookup +func printFilesIfDryRunning(data waitControlPlaneData) error { + if !data.DryRun() { + return nil + } + manifestDir := data.ManifestDir() + + fmt.Printf("[dryrun] Wrote certificates, kubeconfig files and control plane manifests to the %q directory\n", manifestDir) + fmt.Println("[dryrun] The certificates or kubeconfig files would not be printed due to their sensitive nature") + fmt.Printf("[dryrun] Please examine the %q directory for details about what would be written\n", manifestDir) + + // Print the contents of the upgraded manifests and pretend like they were in /etc/kubernetes/manifests + files := []dryrunutil.FileToPrint{} + // Print static pod manifests + for _, component := range kubeadmconstants.MasterComponents { + realPath := kubeadmconstants.GetStaticPodFilepath(component, manifestDir) + outputPath := kubeadmconstants.GetStaticPodFilepath(component, kubeadmconstants.GetStaticPodDirectory()) + files = append(files, dryrunutil.NewFileToPrint(realPath, outputPath)) + } + // Print kubelet config manifests + kubeletConfigFiles := []string{kubeadmconstants.KubeletConfigurationFileName, kubeadmconstants.KubeletEnvFileName} + for _, filename := range kubeletConfigFiles { + realPath := filepath.Join(manifestDir, filename) + outputPath := filepath.Join(kubeadmconstants.KubeletRunDirectory, filename) + files = append(files, dryrunutil.NewFileToPrint(realPath, outputPath)) + } + + return dryrunutil.PrintDryRunFiles(files, data.OutputWriter()) +} + +// NewControlPlaneWaiter returns a new waiter that is used to wait on the control plane to boot up. +// TODO: make private (lowercase) after self-hosting phase is removed. +func NewControlPlaneWaiter(dryRun bool, timeout time.Duration, client clientset.Interface, out io.Writer) (apiclient.Waiter, error) { + if dryRun { + return dryrunutil.NewWaiter(), nil + } + + return apiclient.NewKubeWaiter(client, timeout, out), nil +} diff --git a/cmd/kubeadm/app/cmd/phases/workflow/BUILD b/cmd/kubeadm/app/cmd/phases/workflow/BUILD index 772ff0c66c72a..01571c97a71f5 100644 --- a/cmd/kubeadm/app/cmd/phases/workflow/BUILD +++ b/cmd/kubeadm/app/cmd/phases/workflow/BUILD @@ -10,6 +10,7 @@ go_library( importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow", visibility = ["//visibility:public"], deps = [ + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", ], @@ -22,6 +23,11 @@ go_test( "runner_test.go", ], embed = [":go_default_library"], + deps = [ + "//vendor/github.com/pkg/errors:go_default_library", + "//vendor/github.com/spf13/cobra:go_default_library", + "//vendor/github.com/spf13/pflag:go_default_library", + ], ) filegroup( diff --git a/cmd/kubeadm/app/cmd/phases/workflow/doc.go b/cmd/kubeadm/app/cmd/phases/workflow/doc.go index e5356047e010d..1dd69e315e688 100644 --- a/cmd/kubeadm/app/cmd/phases/workflow/doc.go +++ b/cmd/kubeadm/app/cmd/phases/workflow/doc.go @@ -24,7 +24,7 @@ For instance preflight Run master pre-flight checks certs Generates all PKI assets necessary to establish the control plane - /ca Generates a self-signed kubernetes CA to provision identities for Kubernetes components + /ca Generates a self-signed Kubernetes CA to provision identities for Kubernetes components /apiserver Generates an API server serving certificate and key ... kubeconfig Generates all kubeconfig files necessary to establish the control plane @@ -40,8 +40,21 @@ Each workflow can be defined and managed using a Runner, that will run all the phases according to the given order; nested phases will be executed immediately after their parent phase. -The Runner behavior can be changed by setting the RunnerOptions, typically -exposed as kubeadm command line flags, thus allowing to filter the list of phases -to be executed. +The phase runner can be bound to a cobra command; this operation sets the command description +giving evidence of the list of phases, and automatically creates sub commands +for invoking phases atomically. + +Autogenerated sub commands get flags according to the following rule: + +- global flags will be always inherited by autogenerated commands (this is managed by cobra) + +- local flags defined in the parent command might be inherited by autogenerated commands, +but this requires explicit opt-in so each phase can select the subset of relevant flags + +- it is possible to define additional flags that might be inherited by autogenerated commands +via explicit opt-in, but are not applied to the parent command + +In order to keep flags definition under control, please refer to the +"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" package. */ package workflow diff --git a/cmd/kubeadm/app/cmd/phases/workflow/phase.go b/cmd/kubeadm/app/cmd/phases/workflow/phase.go index be4bf56c6613c..5aac7c5a1a29a 100644 --- a/cmd/kubeadm/app/cmd/phases/workflow/phase.go +++ b/cmd/kubeadm/app/cmd/phases/workflow/phase.go @@ -24,6 +24,9 @@ type Phase struct { // the same workflow or phases belonging to the same parent phase). Name string + // Aliases returns the aliases for the phase. + Aliases []string + // Short description of the phase. Short string @@ -49,6 +52,12 @@ type Phase struct { // before executing the phase action. // If this function return nil, the phase action is always executed. RunIf func(data RunData) (bool, error) + + // CmdFlags defines the list of flags that should be assigned to the cobra command generated + // for this phase; flags are inherited from the parent command or defined as additional flags + // in the phase runner. If the values is not set or empty, no flags will be assigned to the command + // Nb. global flags are automatically inherited by nested cobra command + CmdFlags []string } // AppendPhase adds the given phase to the nested, ordered sequence of phases. diff --git a/cmd/kubeadm/app/cmd/phases/workflow/runner.go b/cmd/kubeadm/app/cmd/phases/workflow/runner.go index 2f1051ee81798..7d3f2e8de9c21 100644 --- a/cmd/kubeadm/app/cmd/phases/workflow/runner.go +++ b/cmd/kubeadm/app/cmd/phases/workflow/runner.go @@ -21,6 +21,7 @@ import ( "os" "strings" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -59,6 +60,10 @@ type Runner struct { // more than one time) runData RunData + // cmdAdditionalFlags holds additional flags that could be added to the subcommands generated + // for each phase. Flags could be inherited from the parent command too + cmdAdditionalFlags *pflag.FlagSet + // phaseRunners is part of the internal state of the runner and provides // a list of wrappers to phases composing the workflow with contextual // information supporting phase execution. @@ -84,7 +89,7 @@ type phaseRunner struct { selfPath []string // generatedName is the full name of the phase, that corresponds to the absolute - // path of the phase in the the workflow managed by the Runner. + // path of the phase in the workflow managed by the Runner. generatedName string // use is the phase usage string that will be printed in the workflow help. @@ -135,7 +140,7 @@ func (e *Runner) computePhaseRunFlags() (map[string]bool, error) { } for _, f := range e.Options.FilterPhases { if _, ok := phaseRunFlags[f]; !ok { - return phaseRunFlags, fmt.Errorf("invalid phase name: %s", f) + return phaseRunFlags, errors.Errorf("invalid phase name: %s", f) } phaseRunFlags[f] = true for _, c := range phaseHierarchy[f] { @@ -148,7 +153,7 @@ func (e *Runner) computePhaseRunFlags() (map[string]bool, error) { // to false and apply the same change to the underlying hierarchy for _, f := range e.Options.SkipPhases { if _, ok := phaseRunFlags[f]; !ok { - return phaseRunFlags, fmt.Errorf("invalid phase name: %s", f) + return phaseRunFlags, errors.Errorf("invalid phase name: %s", f) } phaseRunFlags[f] = false for _, c := range phaseHierarchy[f] { @@ -206,7 +211,7 @@ func (e *Runner) Run() error { // Check the condition and returns if the condition isn't satisfied (or fails) ok, err := p.RunIf(data) if err != nil { - return fmt.Errorf("error execution run condition for phase %s: %v", p.generatedName, err) + return errors.Wrapf(err, "error execution run condition for phase %s", p.generatedName) } if !ok { @@ -217,7 +222,7 @@ func (e *Runner) Run() error { // Runs the phase action (if defined) if p.Run != nil { if err := p.Run(data); err != nil { - return fmt.Errorf("error execution phase %s: %v", p.generatedName, err) + return errors.Wrapf(err, "error execution phase %s", p.generatedName) } } @@ -264,6 +269,16 @@ func (e *Runner) Help(cmdUse string) string { return line } +// SetPhaseSubcommandsAdditionalFlags allows to define flags to be added +// to the subcommands generated for each phase (but not existing in the parent command). +// Please note that this command needs to be done before BindToCommand. +func (e *Runner) SetPhaseSubcommandsAdditionalFlags(fn func(*pflag.FlagSet)) { + // creates a new NewFlagSet + e.cmdAdditionalFlags = pflag.NewFlagSet("phaseAdditionalFlags", pflag.ContinueOnError) + // invokes the function that sets additional flags + fn(e.cmdAdditionalFlags) +} + // BindToCommand bind the Runner to a cobra command by altering // command help, adding phase related flags and by adding phases subcommands // Please note that this command needs to be done once all the phases are added to the Runner. @@ -272,15 +287,7 @@ func (e *Runner) BindToCommand(cmd *cobra.Command) { return } - // alters the command description to show available phases - if cmd.Long != "" { - cmd.Long = fmt.Sprintf("%s\n\n%s\n", cmd.Long, e.Help(cmd.Use)) - } else { - cmd.Long = fmt.Sprintf("%s\n\n%s\n", cmd.Short, e.Help(cmd.Use)) - } - - // adds phase related flags - cmd.Flags().StringSliceVar(&e.Options.SkipPhases, "skip-phases", nil, "List of phases to be skipped") + e.prepareForExecution() // adds the phases subcommand phaseCommand := &cobra.Command{ @@ -294,12 +301,18 @@ func (e *Runner) BindToCommand(cmd *cobra.Command) { // generate all the nested subcommands for invoking single phases subcommands := map[string]*cobra.Command{} e.visitAll(func(p *phaseRunner) error { + // skip hidden phases + if p.Hidden { + return nil + } + // creates nested phase subcommand var phaseCmd = &cobra.Command{ Use: strings.ToLower(p.Name), Short: p.Short, Long: p.Long, Example: p.Example, + Aliases: p.Aliases, Run: func(cmd *cobra.Command, args []string) { e.Options.FilterPhases = []string{p.generatedName} if err := e.Run(); err != nil { @@ -310,10 +323,14 @@ func (e *Runner) BindToCommand(cmd *cobra.Command) { Args: cobra.NoArgs, // this forces cobra to fail if a wrong phase name is passed } - // makes the new command inherits flags from the main command - cmd.LocalNonPersistentFlags().VisitAll(func(f *pflag.Flag) { - phaseCmd.Flags().AddFlag(f) - }) + // makes the new command inherits local flags from the parent command + // Nb. global flags will be inherited automatically + inheritsFlags(cmd.Flags(), phaseCmd.Flags(), p.CmdFlags) + + // If defined, additional flags for phases should be added as well + if e.cmdAdditionalFlags != nil { + inheritsFlags(e.cmdAdditionalFlags, phaseCmd.Flags(), p.CmdFlags) + } // adds the command to parent if p.level == 0 { @@ -325,6 +342,32 @@ func (e *Runner) BindToCommand(cmd *cobra.Command) { subcommands[p.generatedName] = phaseCmd return nil }) + + // alters the command description to show available phases + if cmd.Long != "" { + cmd.Long = fmt.Sprintf("%s\n\n%s\n", cmd.Long, e.Help(cmd.Use)) + } else { + cmd.Long = fmt.Sprintf("%s\n\n%s\n", cmd.Short, e.Help(cmd.Use)) + } + + // adds phase related flags to the main command + cmd.Flags().StringSliceVar(&e.Options.SkipPhases, "skip-phases", nil, "List of phases to be skipped") +} + +func inheritsFlags(sourceFlags, targetFlags *pflag.FlagSet, cmdFlags []string) { + // If the list of flag to be inherited from the parent command is not defined, no flag is added + if cmdFlags == nil { + return + } + + // add all the flags to be inherited to the target flagSet + sourceFlags.VisitAll(func(f *pflag.Flag) { + for _, c := range cmdFlags { + if f.Name == c { + targetFlags.AddFlag(f) + } + } + }) } // visitAll provides a utility method for visiting all the phases in the workflow diff --git a/cmd/kubeadm/app/cmd/phases/workflow/runner_test.go b/cmd/kubeadm/app/cmd/phases/workflow/runner_test.go index 3aedf6acb7c79..b303e7d26b5d8 100644 --- a/cmd/kubeadm/app/cmd/phases/workflow/runner_test.go +++ b/cmd/kubeadm/app/cmd/phases/workflow/runner_test.go @@ -17,10 +17,14 @@ limitations under the License. package workflow import ( - "errors" "fmt" "reflect" + "strings" "testing" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/pflag" ) func phaseBuilder(name string, phases ...Phase) Phase { @@ -277,3 +281,195 @@ func TestHelp(t *testing.T) { t.Errorf("\nactual:\n\t%v\nexpected:\n\t%v\n", actual, expected) } } + +func phaseBuilder4(name string, cmdFlags []string, phases ...Phase) Phase { + return Phase{ + Name: name, + Phases: phases, + CmdFlags: cmdFlags, + } +} + +func TestBindToCommand(t *testing.T) { + + var usecases = []struct { + name string + runner Runner + expectedCmdAndFlags map[string][]string + setAdditionalFlags func(*pflag.FlagSet) + }{ + { + name: "when there are no phases, cmd should be left untouched", + runner: Runner{}, + }, + { + name: "phases should not inherits any parent flags by default", + runner: Runner{ + Phases: []Phase{phaseBuilder4("foo", nil)}, + }, + expectedCmdAndFlags: map[string][]string{ + "phase foo": {}, + }, + }, + { + name: "phases should be allowed to select parent flags to inherits", + runner: Runner{ + Phases: []Phase{phaseBuilder4("foo", []string{"flag1"})}, + }, + expectedCmdAndFlags: map[string][]string{ + "phase foo": {"flag1"}, //not "flag2" + }, + }, + { + name: "it should be possible to apply additional flags to all phases", + runner: Runner{ + Phases: []Phase{ + phaseBuilder4("foo", []string{"flag3"}), + phaseBuilder4("bar", []string{"flag1", "flag2", "flag3"}), + phaseBuilder4("baz", []string{"flag1"}), //test if additional flags are filtered too + }, + }, + setAdditionalFlags: func(flags *pflag.FlagSet) { + var dummy3 string + flags.StringVarP(&dummy3, "flag3", "c", "c", "c") + }, + expectedCmdAndFlags: map[string][]string{ + "phase foo": {"flag3"}, + "phase bar": {"flag1", "flag2", "flag3"}, + "phase baz": {"flag1"}, + }, + }, + { + name: "all the above applies to nested phases too", + runner: Runner{ + Phases: []Phase{ + phaseBuilder4("foo", []string{"flag3"}, + phaseBuilder4("bar", []string{"flag1", "flag2", "flag3"}), + phaseBuilder4("baz", []string{"flag1"}), //test if additional flags are filtered too + ), + }, + }, + setAdditionalFlags: func(flags *pflag.FlagSet) { + var dummy3 string + flags.StringVarP(&dummy3, "flag3", "c", "c", "c") + }, + expectedCmdAndFlags: map[string][]string{ + "phase foo": {"flag3"}, + "phase foo bar": {"flag1", "flag2", "flag3"}, + "phase foo baz": {"flag1"}, + }, + }, + } + for _, rt := range usecases { + t.Run(rt.name, func(t *testing.T) { + + var dummy1, dummy2 string + cmd := &cobra.Command{ + Use: "init", + } + + cmd.Flags().StringVarP(&dummy1, "flag1", "a", "a", "a") + cmd.Flags().StringVarP(&dummy2, "flag2", "b", "b", "b") + + if rt.setAdditionalFlags != nil { + rt.runner.SetPhaseSubcommandsAdditionalFlags(rt.setAdditionalFlags) + } + + rt.runner.BindToCommand(cmd) + + // in case of no phases, checks that cmd is untouched + if len(rt.runner.Phases) == 0 { + if cmd.Long != "" { + t.Error("cmd.Long is set while it should be leaved untouched\n") + } + + if cmd.Flags().Lookup("skip-phases") != nil { + t.Error("cmd has skip-phases flag while it should not\n") + } + + if getCmd(cmd, "phase") != nil { + t.Error("cmd has phase subcommand while it should not\n") + } + + return + } + + // Otherwise, if there are phases + + // Checks that cmd get the description set and the skip-phases flags + if cmd.Long == "" { + t.Error("cmd.Long not set\n") + } + + if cmd.Flags().Lookup("skip-phases") == nil { + t.Error("cmd didn't have skip-phases flag\n") + } + + // Checks that cmd gets a new phase subcommand (without local flags) + phaseCmd := getCmd(cmd, "phase") + if phaseCmd == nil { + t.Error("cmd didn't have phase subcommand\n") + return + } + if err := cmdHasFlags(phaseCmd); err != nil { + t.Errorf("command phase didn't have expected flags: %v\n", err) + } + + // Checks that cmd subcommand gets subcommand for phases (without flags properly sets) + for c, flags := range rt.expectedCmdAndFlags { + + cCmd := getCmd(cmd, c) + if cCmd == nil { + t.Errorf("cmd didn't have %s subcommand\n", c) + continue + } + + if err := cmdHasFlags(cCmd, flags...); err != nil { + t.Errorf("command %s didn't have expected flags: %v\n", c, err) + } + } + + }) + } +} + +func getCmd(parent *cobra.Command, nestedName string) *cobra.Command { + names := strings.Split(nestedName, " ") + for i, n := range names { + for _, c := range parent.Commands() { + if c.Name() == n { + if i == len(names)-1 { + return c + } + parent = c + } + } + } + + return nil +} + +func cmdHasFlags(cmd *cobra.Command, expectedFlags ...string) error { + flags := []string{} + cmd.Flags().VisitAll(func(f *pflag.Flag) { + flags = append(flags, f.Name) + }) + + for _, e := range expectedFlags { + found := false + for _, f := range flags { + if f == e { + found = true + } + } + if !found { + return errors.Errorf("flag %q does not exists in %s", e, flags) + } + } + + if len(flags) != len(expectedFlags) { + return errors.Errorf("expected flags %s, got %s", expectedFlags, flags) + } + + return nil +} diff --git a/cmd/kubeadm/app/cmd/reset.go b/cmd/kubeadm/app/cmd/reset.go index 0b2ac7a891efc..ce2e7883cc7b1 100644 --- a/cmd/kubeadm/app/cmd/reset.go +++ b/cmd/kubeadm/app/cmd/reset.go @@ -30,13 +30,17 @@ import ( "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/util/sets" + clientset "k8s.io/client-go/kubernetes" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/preflight" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" + configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" utilruntime "k8s.io/kubernetes/cmd/kubeadm/app/util/runtime" + utilstaticpod "k8s.io/kubernetes/cmd/kubeadm/app/util/staticpod" "k8s.io/kubernetes/pkg/util/initsystem" utilsexec "k8s.io/utils/exec" ) @@ -47,6 +51,7 @@ func NewCmdReset(in io.Reader, out io.Writer) *cobra.Command { var criSocketPath string var ignorePreflightErrors []string var forceReset bool + kubeConfigFile := kubeadmconstants.GetAdminKubeConfigPath() cmd := &cobra.Command{ Use: "reset", @@ -55,13 +60,18 @@ func NewCmdReset(in io.Reader, out io.Writer) *cobra.Command { ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(ignorePreflightErrors) kubeadmutil.CheckErr(err) + kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) + client, err := getClientset(kubeConfigFile, false) + kubeadmutil.CheckErr(err) + r, err := NewReset(in, ignorePreflightErrorsSet, forceReset, certsDir, criSocketPath) kubeadmutil.CheckErr(err) - kubeadmutil.CheckErr(r.Run(out)) + kubeadmutil.CheckErr(r.Run(out, client)) }, } options.AddIgnorePreflightErrorsFlag(cmd.PersistentFlags(), &ignorePreflightErrors) + options.AddKubeConfigFlag(cmd.PersistentFlags(), &kubeConfigFile) cmd.PersistentFlags().StringVar( &certsDir, "cert-dir", kubeadmapiv1beta1.DefaultCertificatesDir, @@ -114,7 +124,19 @@ func NewReset(in io.Reader, ignorePreflightErrors sets.String, forceReset bool, } // Run reverts any changes made to this host by "kubeadm init" or "kubeadm join". -func (r *Reset) Run(out io.Writer) error { +func (r *Reset) Run(out io.Writer, client clientset.Interface) error { + var dirsToClean []string + // Only clear etcd data when using local etcd. + etcdManifestPath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName, "etcd.yaml") + + glog.V(1).Infof("[reset] checking for etcd config") + etcdDataDir, err := getEtcdDataDir(etcdManifestPath, client) + if err == nil { + dirsToClean = append(dirsToClean, etcdDataDir) + } else { + fmt.Println("[reset] no etcd config found. Assuming external etcd") + fmt.Println("[reset] please manually reset etcd to prevent further issues") + } // Try to stop the kubelet service glog.V(1).Infof("[reset] getting init system") @@ -140,23 +162,11 @@ func (r *Reset) Run(out io.Writer) error { glog.Errorf("[reset] failed to unmount mounted directories in %s: %s\n", kubeadmconstants.KubeletRunDirectory, string(umountOutputBytes)) } - glog.V(1).Info("[reset] removing kubernetes-managed containers") + glog.V(1).Info("[reset] removing Kubernetes-managed containers") if err := removeContainers(utilsexec.New(), r.criSocketPath); err != nil { glog.Errorf("[reset] failed to remove containers: %+v", err) } - dirsToClean := []string{kubeadmconstants.KubeletRunDirectory, "/etc/cni/net.d", "/var/lib/dockershim", "/var/run/kubernetes"} - - // Only clear etcd data when the etcd manifest is found. In case it is not found, we must assume that the user - // provided external etcd endpoints. In that case, it is their own responsibility to reset etcd - etcdManifestPath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName, "etcd.yaml") - glog.V(1).Infof("[reset] checking for etcd manifest") - if _, err := os.Stat(etcdManifestPath); err == nil { - glog.V(1).Infof("Found one at %s", etcdManifestPath) - dirsToClean = append(dirsToClean, "/var/lib/etcd") - } else { - fmt.Printf("[reset] no etcd manifest found in %q. Assuming external etcd\n", etcdManifestPath) - fmt.Println("[reset] please manually reset etcd to prevent further issues") - } + dirsToClean = append(dirsToClean, []string{kubeadmconstants.KubeletRunDirectory, "/etc/cni/net.d", "/var/lib/dockershim", "/var/run/kubernetes"}...) // Then clean contents from the stateful kubelet, etcd and cni directories fmt.Printf("[reset] deleting contents of stateful directories: %v\n", dirsToClean) @@ -175,6 +185,33 @@ func (r *Reset) Run(out io.Writer) error { return nil } +func getEtcdDataDir(manifestPath string, client clientset.Interface) (string, error) { + const etcdVolumeName = "etcd-data" + var dataDir string + + cfg, err := configutil.FetchConfigFromFileOrCluster(client, os.Stdout, "reset", "", false) + if err == nil { + return cfg.Etcd.Local.DataDir, nil + } + glog.Warningf("[reset] Unable to fetch the kubeadm-config ConfigMap, using etcd pod spec as fallback: %v", err) + + etcdPod, err := utilstaticpod.ReadStaticPodFromDisk(manifestPath) + if err != nil { + return "", err + } + + for _, volumeMount := range etcdPod.Spec.Volumes { + if volumeMount.Name == etcdVolumeName { + dataDir = volumeMount.HostPath.Path + break + } + } + if dataDir == "" { + return dataDir, fmt.Errorf("invalid etcd pod manifest") + } + return dataDir, nil +} + func removeContainers(execer utilsexec.Interface, criSocketPath string) error { containerRuntime, err := utilruntime.NewContainerRuntime(execer, criSocketPath) if err != nil { diff --git a/cmd/kubeadm/app/cmd/reset_test.go b/cmd/kubeadm/app/cmd/reset_test.go index be35b56cb4a4c..f15dec5039205 100644 --- a/cmd/kubeadm/app/cmd/reset_test.go +++ b/cmd/kubeadm/app/cmd/reset_test.go @@ -23,14 +23,46 @@ import ( "path/filepath" "testing" + "github.com/renstrom/dedent" + + clientsetfake "k8s.io/client-go/kubernetes/fake" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/preflight" + testutil "k8s.io/kubernetes/cmd/kubeadm/test" "k8s.io/utils/exec" fakeexec "k8s.io/utils/exec/testing" ) +const ( + etcdPod = `apiVersion: v1 +kind: Pod +metadata: +spec: + volumes: + - hostPath: + path: /path/to/etcd + type: DirectoryOrCreate + name: etcd-data + - hostPath: + path: /etc/kubernetes/pki/etcd + type: DirectoryOrCreate + name: etcd-certs` + + etcdPodWithoutDataVolume = `apiVersion: v1 +kind: Pod +metadata: +spec: + volumes: + - hostPath: + path: /etc/kubernetes/pki/etcd + type: DirectoryOrCreate + name: etcd-certs` + + etcdPodInvalid = `invalid pod` +) + func assertExists(t *testing.T, path string) { if _, err := os.Stat(path); os.IsNotExist(err) { t.Errorf("file/directory does not exist; error: %s", err) @@ -234,3 +266,66 @@ func TestRemoveContainers(t *testing.T) { removeContainers(&fexec, "unix:///var/run/crio/crio.sock") } + +func TestGetEtcdDataDir(t *testing.T) { + tests := map[string]struct { + dataDir string + podYaml string + expectErr bool + writeManifest bool + }{ + "non-existent file returns error": { + dataDir: "", + podYaml: "", + expectErr: true, + writeManifest: false, + }, + "return etcd data dir": { + dataDir: "/path/to/etcd", + podYaml: etcdPod, + expectErr: false, + writeManifest: true, + }, + "invalid etcd pod": { + dataDir: "", + podYaml: etcdPodInvalid, + expectErr: true, + writeManifest: true, + }, + "etcd pod spec without data volume": { + dataDir: "", + podYaml: etcdPodWithoutDataVolume, + expectErr: true, + writeManifest: true, + }, + } + + for name, test := range tests { + tmpdir := testutil.SetupTempDir(t) + defer os.RemoveAll(tmpdir) + + manifestPath := filepath.Join(tmpdir, "etcd.yaml") + if test.writeManifest { + err := ioutil.WriteFile(manifestPath, []byte(test.podYaml), 0644) + if err != nil { + t.Fatalf(dedent.Dedent("failed to write pod manifest\n%s\n\tfatal error: %v"), name, err) + } + } + + client := clientsetfake.NewSimpleClientset() + dataDir, err := getEtcdDataDir(manifestPath, client) + if (err != nil) != test.expectErr { + t.Fatalf(dedent.Dedent( + "getEtcdDataDir failed\n%s\nexpected error: %t\n\tgot: %t\nerror: %v"), + name, + test.expectErr, + (err != nil), + err, + ) + } + + if dataDir != test.dataDir { + t.Fatalf(dedent.Dedent("getEtcdDataDir failed\n%s\n\texpected: %s\ngot: %s"), name, test.dataDir, dataDir) + } + } +} diff --git a/cmd/kubeadm/app/cmd/token.go b/cmd/kubeadm/app/cmd/token.go index 9bd5d28bb15e9..b5fc0334e4892 100644 --- a/cmd/kubeadm/app/cmd/token.go +++ b/cmd/kubeadm/app/cmd/token.go @@ -25,6 +25,7 @@ import ( "time" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/renstrom/dedent" "github.com/spf13/cobra" @@ -119,7 +120,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command { err = bto.ApplyTo(cfg) kubeadmutil.CheckErr(err) - glog.V(1).Infoln("[token] getting Clientsets from KubeConfig file") + glog.V(1).Infoln("[token] getting Clientsets from kubeconfig file") kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) client, err := getClientset(kubeConfigFile, dryRun) kubeadmutil.CheckErr(err) @@ -169,7 +170,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command { `), Run: func(tokenCmd *cobra.Command, args []string) { if len(args) < 1 { - kubeadmutil.CheckErr(fmt.Errorf("missing subcommand; 'token delete' is missing token of form %q", bootstrapapi.BootstrapTokenIDPattern)) + kubeadmutil.CheckErr(errors.Errorf("missing subcommand; 'token delete' is missing token of form %q", bootstrapapi.BootstrapTokenIDPattern)) } kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile) client, err := getClientset(kubeConfigFile, dryRun) @@ -230,7 +231,7 @@ func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, c if printJoinCommand { joinCommand, err := cmdutil.GetJoinCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), false) if err != nil { - return fmt.Errorf("failed to get join command: %v", err) + return errors.Wrap(err, "failed to get join command") } fmt.Fprintln(out, joinCommand) } else { @@ -271,7 +272,7 @@ func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) er glog.V(1).Infoln("[token] retrieving list of bootstrap tokens") secrets, err := client.CoreV1().Secrets(metav1.NamespaceSystem).List(listOptions) if err != nil { - return fmt.Errorf("failed to list bootstrap tokens [%v]", err) + return errors.Wrap(err, "failed to list bootstrap tokens") } w := tabwriter.NewWriter(out, 10, 4, 3, ' ', 0) @@ -302,7 +303,8 @@ func RunDeleteToken(out io.Writer, client clientset.Interface, tokenIDOrToken st // Okay, the full token with both id and secret was probably passed. Parse it and extract the ID only bts, err := kubeadmapiv1beta1.NewBootstrapTokenString(tokenIDOrToken) if err != nil { - return fmt.Errorf("given token or token id %q didn't match pattern %q or %q", tokenIDOrToken, bootstrapapi.BootstrapTokenIDPattern, bootstrapapi.BootstrapTokenIDPattern) + return errors.Errorf("given token or token id %q didn't match pattern %q or %q", + tokenIDOrToken, bootstrapapi.BootstrapTokenIDPattern, bootstrapapi.BootstrapTokenIDPattern) } tokenID = bts.ID } @@ -310,7 +312,7 @@ func RunDeleteToken(out io.Writer, client clientset.Interface, tokenIDOrToken st tokenSecretName := bootstraputil.BootstrapTokenSecretName(tokenID) glog.V(1).Infoln("[token] deleting token") if err := client.CoreV1().Secrets(metav1.NamespaceSystem).Delete(tokenSecretName, nil); err != nil { - return fmt.Errorf("failed to delete bootstrap token [%v]", err) + return errors.Wrap(err, "failed to delete bootstrap token") } fmt.Fprintf(out, "bootstrap token with id %q deleted\n", tokenID) return nil diff --git a/cmd/kubeadm/app/cmd/token_test.go b/cmd/kubeadm/app/cmd/token_test.go index f755c0d0780e9..b5ca50b565252 100644 --- a/cmd/kubeadm/app/cmd/token_test.go +++ b/cmd/kubeadm/app/cmd/token_test.go @@ -18,17 +18,11 @@ package cmd import ( "bytes" - "encoding/json" - "fmt" "io/ioutil" - "net/http" "os" "path/filepath" "regexp" - "strings" - "sync/atomic" "testing" - "time" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -37,7 +31,6 @@ import ( "k8s.io/client-go/kubernetes/fake" core "k8s.io/client-go/testing" "k8s.io/client-go/tools/clientcmd" - bootstrapapi "k8s.io/cluster-bootstrap/token/api" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" ) @@ -352,188 +345,3 @@ func TestRunDeleteToken(t *testing.T) { t.Errorf("RunDeleteToken() succeeded for an invalid token: %v", err) } } - -var httpTestItr uint32 -var httpSentResponse uint32 = 1 - -func TestRunListTokens(t *testing.T) { - var err error - var bufOut, bufErr bytes.Buffer - - tmpDir, err := ioutil.TempDir("", "kubeadm-token-test") - if err != nil { - t.Errorf("Unable to create temporary directory: %v", err) - } - defer os.RemoveAll(tmpDir) - fullPath := filepath.Join(tmpDir, "test-config-file") - - f, err := os.Create(fullPath) - if err != nil { - t.Errorf("Unable to create test file %q: %v", fullPath, err) - } - defer f.Close() - - // test config without secrets; should fail - if _, err = f.WriteString(testConfigToken); err != nil { - t.Errorf("Unable to write test file %q: %v", fullPath, err) - } - - client, err := getClientset(fullPath, true) - if err != nil { - t.Errorf("Unable to run getClientset() for test file %q: %v", fullPath, err) - } - - if err = RunListTokens(&bufOut, &bufErr, client); err == nil { - t.Errorf("RunListTokens() did not fail for a config without secrets: %v", err) - } - - // test config without secrets but use a dummy API server that returns secrets - portString := "9008" - http.HandleFunc("/", httpHandler) - httpServer := &http.Server{Addr: "localhost:" + portString} - go func() { - err := httpServer.ListenAndServe() - if err != nil { - t.Errorf("Failed to start dummy API server: localhost:%s", portString) - } - }() - - fmt.Printf("dummy API server listening on localhost:%s\n", portString) - testConfigTokenOpenPort := strings.Replace(testConfigToken, "server: localhost:8000", "server: localhost:"+portString, -1) - - if _, err = f.WriteString(testConfigTokenOpenPort); err != nil { - t.Errorf("Unable to write test file %q: %v", fullPath, err) - } - - client, err = getClientset(fullPath, true) - if err != nil { - t.Errorf("Unable to run getClientset() for test file %q: %v", fullPath, err) - } - - // the order of these tests should match the case check - // for httpTestItr in httpHandler - testCases := []struct { - name string - expectedError bool - }{ - { - name: "token-id not defined", - expectedError: true, - }, - { - name: "secret name not formatted correctly", - expectedError: true, - }, - { - name: "token-secret not defined", - expectedError: true, - }, - { - name: "token expiration not formatted correctly", - expectedError: true, - }, - { - name: "token expiration formatted correctly", - expectedError: false, - }, - { - name: "token usage constant not true", - expectedError: false, - }, - { - name: "token usage constant set to true", - expectedError: false, - }, - } - for _, tc := range testCases { - bufErr.Reset() - atomic.StoreUint32(&httpSentResponse, 0) - fmt.Printf("Running HTTP test case (%d) %q\n", atomic.LoadUint32(&httpTestItr), tc.name) - // should always return nil here if a valid list of secrets if fetched - err := RunListTokens(&bufOut, &bufErr, client) - if err != nil { - t.Errorf("HTTP test case %d: Was unable to fetch a list of secrets", atomic.LoadUint32(&httpTestItr)) - } - // wait for a response from the dummy HTTP server - timeSpent := 0 * time.Millisecond - timeToSleep := 50 * time.Millisecond - timeMax := 2000 * time.Millisecond - for { - if atomic.LoadUint32(&httpSentResponse) == 1 { - break - } - if timeSpent >= timeMax { - t.Errorf("HTTP test case %d: The server did not respond within %d ms", atomic.LoadUint32(&httpTestItr), timeMax) - } - timeSpent += timeToSleep - time.Sleep(timeToSleep) - } - // check if an error is written in the error buffer - hasError := bufErr.Len() != 0 - if hasError != tc.expectedError { - t.Errorf("HTTP test case %d: RunListTokens expected error: %v, saw: %v; %v", atomic.LoadUint32(&httpTestItr), tc.expectedError, hasError, bufErr.String()) - } - } -} - -// only one of these should run at a time in a goroutine -func httpHandler(w http.ResponseWriter, r *http.Request) { - tokenID := []byte("07401b") - tokenSecret := []byte("f395accd246ae52d") - tokenExpire := []byte("2012-11-01T22:08:41+00:00") - badValue := "bad-value" - name := bootstrapapi.BootstrapTokenSecretPrefix + string(tokenID) - tokenUsageKey := bootstrapapi.BootstrapTokenUsagePrefix + "test" - - secret := v1.Secret{} - secret.Type = bootstrapapi.SecretTypeBootstrapToken - secret.TypeMeta = metav1.TypeMeta{APIVersion: "v1", Kind: "Secret"} - secret.Data = map[string][]byte{} - - switch atomic.LoadUint32(&httpTestItr) { - case 0: - secret.Data[bootstrapapi.BootstrapTokenIDKey] = []byte("") - case 1: - secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID - secret.ObjectMeta = metav1.ObjectMeta{Name: badValue} - case 2: - secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID - secret.Data[bootstrapapi.BootstrapTokenSecretKey] = []byte("") - secret.ObjectMeta = metav1.ObjectMeta{Name: name} - case 3: - secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID - secret.Data[bootstrapapi.BootstrapTokenSecretKey] = tokenSecret - secret.Data[bootstrapapi.BootstrapTokenExpirationKey] = []byte(badValue) - secret.ObjectMeta = metav1.ObjectMeta{Name: name} - case 4: - secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID - secret.Data[bootstrapapi.BootstrapTokenSecretKey] = tokenSecret - secret.Data[bootstrapapi.BootstrapTokenExpirationKey] = tokenExpire - secret.ObjectMeta = metav1.ObjectMeta{Name: name} - case 5: - secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID - secret.Data[bootstrapapi.BootstrapTokenSecretKey] = tokenSecret - secret.Data[bootstrapapi.BootstrapTokenExpirationKey] = tokenExpire - secret.Data[tokenUsageKey] = []byte("false") - secret.ObjectMeta = metav1.ObjectMeta{Name: name} - case 6: - secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID - secret.Data[bootstrapapi.BootstrapTokenSecretKey] = tokenSecret - secret.Data[bootstrapapi.BootstrapTokenExpirationKey] = tokenExpire - secret.Data[tokenUsageKey] = []byte("true") - secret.ObjectMeta = metav1.ObjectMeta{Name: name} - } - - secretList := v1.SecretList{} - secretList.Items = []v1.Secret{secret} - secretList.TypeMeta = metav1.TypeMeta{APIVersion: "v1", Kind: "SecretList"} - - output, err := json.Marshal(secretList) - if err == nil { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - w.Write([]byte(output)) - } - atomic.AddUint32(&httpTestItr, 1) - atomic.StoreUint32(&httpSentResponse, 1) -} diff --git a/cmd/kubeadm/app/cmd/upgrade/BUILD b/cmd/kubeadm/app/cmd/upgrade/BUILD index 3a65d8314ceec..87a415563750a 100644 --- a/cmd/kubeadm/app/cmd/upgrade/BUILD +++ b/cmd/kubeadm/app/cmd/upgrade/BUILD @@ -40,6 +40,7 @@ go_library( "//staging/src/k8s.io/client-go/discovery/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/pmezard/go-difflib/difflib:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", diff --git a/cmd/kubeadm/app/cmd/upgrade/apply.go b/cmd/kubeadm/app/cmd/upgrade/apply.go index acffb90f4417d..af03ad615a698 100644 --- a/cmd/kubeadm/app/cmd/upgrade/apply.go +++ b/cmd/kubeadm/app/cmd/upgrade/apply.go @@ -22,8 +22,8 @@ import ( "time" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/util/version" clientset "k8s.io/client-go/kubernetes" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" @@ -169,7 +169,7 @@ func RunApply(flags *applyFlags) error { flags.newK8sVersionStr = upgradeVars.cfg.KubernetesVersion k8sVer, err := version.ParseSemantic(flags.newK8sVersionStr) if err != nil { - return fmt.Errorf("unable to parse normalized version %q as a semantic version", flags.newK8sVersionStr) + return errors.Errorf("unable to parse normalized version %q as a semantic version", flags.newK8sVersionStr) } flags.newK8sVersion = k8sVer @@ -180,7 +180,7 @@ func RunApply(flags *applyFlags) error { // Enforce the version skew policies glog.V(1).Infof("[upgrade/version] enforcing version skew policies") if err := EnforceVersionPolicies(flags, upgradeVars.versionGetter); err != nil { - return fmt.Errorf("[upgrade/version] FATAL: %v", err) + return errors.Wrap(err, "[upgrade/version] FATAL") } // If the current session is interactive, ask the user whether they really want to upgrade @@ -199,19 +199,19 @@ func RunApply(flags *applyFlags) error { componentsToPrepull = append(componentsToPrepull, constants.Etcd) } if err := upgrade.PrepullImagesInParallel(prepuller, flags.imagePullTimeout, componentsToPrepull); err != nil { - return fmt.Errorf("[upgrade/prepull] Failed prepulled the images for the control plane components error: %v", err) + return errors.Wrap(err, "[upgrade/prepull] Failed prepulled the images for the control plane components error") } // Now; perform the upgrade procedure glog.V(1).Infof("[upgrade/apply] performing upgrade") if err := PerformControlPlaneUpgrade(flags, upgradeVars.client, upgradeVars.waiter, upgradeVars.cfg); err != nil { - return fmt.Errorf("[upgrade/apply] FATAL: %v", err) + return errors.Wrap(err, "[upgrade/apply] FATAL") } // Upgrade RBAC rules and addons. glog.V(1).Infof("[upgrade/postupgrade] upgrading RBAC rules and addons") if err := upgrade.PerformPostUpgradeTasks(upgradeVars.client, upgradeVars.cfg, flags.newK8sVersion, flags.dryRun); err != nil { - return fmt.Errorf("[upgrade/postupgrade] FATAL post-upgrade error: %v", err) + return errors.Wrap(err, "[upgrade/postupgrade] FATAL post-upgrade error") } if flags.dryRun { @@ -235,7 +235,7 @@ func SetImplicitFlags(flags *applyFlags) error { } if len(flags.newK8sVersionStr) == 0 { - return fmt.Errorf("version string can't be empty") + return errors.New("version string can't be empty") } return nil @@ -250,13 +250,15 @@ func EnforceVersionPolicies(flags *applyFlags, versionGetter upgrade.VersionGett if versionSkewErrs != nil { if len(versionSkewErrs.Mandatory) > 0 { - return fmt.Errorf("The --version argument is invalid due to these fatal errors:\n\n%v\nPlease fix the misalignments highlighted above and try upgrading again", kubeadmutil.FormatErrMsg(versionSkewErrs.Mandatory)) + return errors.Errorf("the --version argument is invalid due to these fatal errors:\n\n%v\nPlease fix the misalignments highlighted above and try upgrading again", + kubeadmutil.FormatErrMsg(versionSkewErrs.Mandatory)) } if len(versionSkewErrs.Skippable) > 0 { // Return the error if the user hasn't specified the --force flag if !flags.force { - return fmt.Errorf("The --version argument is invalid due to these errors:\n\n%v\nCan be bypassed if you pass the --force flag", kubeadmutil.FormatErrMsg(versionSkewErrs.Skippable)) + return errors.Errorf("the --version argument is invalid due to these errors:\n\n%v\nCan be bypassed if you pass the --force flag", + kubeadmutil.FormatErrMsg(versionSkewErrs.Skippable)) } // Soft errors found, but --force was specified fmt.Printf("[upgrade/version] Found %d potential version compatibility errors but skipping since the --force flag is set: \n\n%v", len(versionSkewErrs.Skippable), kubeadmutil.FormatErrMsg(versionSkewErrs.Skippable)) @@ -303,7 +305,7 @@ func PerformStaticPodUpgrade(client clientset.Interface, waiter apiclient.Waiter } // The arguments oldEtcdClient and newEtdClient, are uninitialized because passing in the clients allow for mocking the client during testing - return upgrade.StaticPodControlPlane(waiter, pathManager, internalcfg, etcdUpgrade, nil, nil) + return upgrade.StaticPodControlPlane(client, waiter, pathManager, internalcfg, etcdUpgrade, nil, nil) } // DryRunStaticPodUpgrade fakes an upgrade of the control plane diff --git a/cmd/kubeadm/app/cmd/upgrade/common.go b/cmd/kubeadm/app/cmd/upgrade/common.go index fa975f025efd6..97d2bda4ccd84 100644 --- a/cmd/kubeadm/app/cmd/upgrade/common.go +++ b/cmd/kubeadm/app/cmd/upgrade/common.go @@ -24,6 +24,7 @@ import ( "os" "strings" + "github.com/pkg/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" @@ -54,12 +55,12 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin client, err := getClient(flags.kubeConfigPath, dryRun) if err != nil { - return nil, fmt.Errorf("couldn't create a Kubernetes client from file %q: %v", flags.kubeConfigPath, err) + return nil, errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath) } // Run healthchecks against the cluster if err := upgrade.CheckClusterHealth(client, flags.ignorePreflightErrorsSet); err != nil { - return nil, fmt.Errorf("[upgrade/health] FATAL: %v", err) + return nil, errors.Wrap(err, "[upgrade/health] FATAL") } // Fetch the configuration from a file or ConfigMap and validate it @@ -75,9 +76,9 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin fmt.Printf("\t- OPTION 2: Run 'kubeadm config upload from-file' and specify the same config file you passed to 'kubeadm init' when you created your master.\n") fmt.Printf("\t- OPTION 3: Pass a config file to 'kubeadm upgrade' using the --config flag.\n") fmt.Println("") - err = fmt.Errorf("the ConfigMap %q in the %s namespace used for getting configuration information was not found", constants.KubeadmConfigConfigMap, metav1.NamespaceSystem) + err = errors.Errorf("the ConfigMap %q in the %s namespace used for getting configuration information was not found", constants.KubeadmConfigConfigMap, metav1.NamespaceSystem) } - return nil, fmt.Errorf("[upgrade/config] FATAL: %v", err) + return nil, errors.Wrap(err, "[upgrade/config] FATAL") } // If a new k8s version should be set, apply the change before printing the config @@ -89,7 +90,7 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin if flags.featureGatesString != "" { cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, flags.featureGatesString) if err != nil { - return nil, fmt.Errorf("[upgrade/config] FATAL: %v", err) + return nil, errors.Wrap(err, "[upgrade/config] FATAL") } } @@ -98,7 +99,7 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin for _, m := range msg { fmt.Printf("[upgrade/config] %s\n", m) } - return nil, fmt.Errorf("[upgrade/config] FATAL. Unable to upgrade a cluster using deprecated feature-gate flags. Please see the release notes") + return nil, errors.New("[upgrade/config] FATAL. Unable to upgrade a cluster using deprecated feature-gate flags. Please see the release notes") } // If the user told us to print this information out; do it! @@ -153,7 +154,7 @@ func getClient(file string, dryRun bool) (clientset.Interface, error) { // API Server's version realServerVersion, err := dryRunGetter.Client().Discovery().ServerVersion() if err != nil { - return nil, fmt.Errorf("failed to get server version: %v", err) + return nil, errors.Wrap(err, "failed to get server version") } // Get the fake clientset @@ -165,7 +166,7 @@ func getClient(file string, dryRun bool) (clientset.Interface, error) { // we can convert it to that struct. fakeclientDiscovery, ok := fakeclient.Discovery().(*fakediscovery.FakeDiscovery) if !ok { - return nil, fmt.Errorf("couldn't set fake discovery's server version") + return nil, errors.New("couldn't set fake discovery's server version") } // Lastly, set the right server version to be used fakeclientDiscovery.FakedServerVersion = realServerVersion @@ -191,12 +192,12 @@ func InteractivelyConfirmUpgrade(question string) error { scanner := bufio.NewScanner(os.Stdin) scanner.Scan() if err := scanner.Err(); err != nil { - return fmt.Errorf("couldn't read from standard input: %v", err) + return errors.Wrap(err, "couldn't read from standard input") } answer := scanner.Text() if strings.ToLower(answer) == "y" || strings.ToLower(answer) == "yes" { return nil } - return fmt.Errorf("won't proceed; the user didn't answer (Y|y) in order to continue") + return errors.New("won't proceed; the user didn't answer (Y|y) in order to continue") } diff --git a/cmd/kubeadm/app/cmd/upgrade/common_test.go b/cmd/kubeadm/app/cmd/upgrade/common_test.go index 0554623eba1ee..5547b71cd2a30 100644 --- a/cmd/kubeadm/app/cmd/upgrade/common_test.go +++ b/cmd/kubeadm/app/cmd/upgrade/common_test.go @@ -43,12 +43,14 @@ func TestPrintConfiguration(t *testing.T) { }, }, expectedBytes: []byte(`[upgrade/config] Configuration used: + apiServer: {} apiVersion: kubeadm.k8s.io/v1beta1 auditPolicy: logDir: "" path: "" certificatesDir: "" controlPlaneEndpoint: "" + controllerManager: {} etcd: local: dataDir: /some/path @@ -60,6 +62,7 @@ func TestPrintConfiguration(t *testing.T) { dnsDomain: "" podSubnet: "" serviceSubnet: "" + scheduler: {} unifiedControlPlaneImage: "" `), }, @@ -76,12 +79,14 @@ func TestPrintConfiguration(t *testing.T) { }, }, expectedBytes: []byte(`[upgrade/config] Configuration used: + apiServer: {} apiVersion: kubeadm.k8s.io/v1beta1 auditPolicy: logDir: "" path: "" certificatesDir: "" controlPlaneEndpoint: "" + controllerManager: {} etcd: external: caFile: "" @@ -96,6 +101,7 @@ func TestPrintConfiguration(t *testing.T) { dnsDomain: "" podSubnet: "" serviceSubnet: 10.96.0.1/12 + scheduler: {} unifiedControlPlaneImage: "" `), }, diff --git a/cmd/kubeadm/app/cmd/upgrade/diff.go b/cmd/kubeadm/app/cmd/upgrade/diff.go index 1a43135eac654..5edd203d0347b 100644 --- a/cmd/kubeadm/app/cmd/upgrade/diff.go +++ b/cmd/kubeadm/app/cmd/upgrade/diff.go @@ -17,11 +17,11 @@ limitations under the License. package upgrade import ( - "fmt" "io" "io/ioutil" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/pmezard/go-difflib/difflib" "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" @@ -125,7 +125,7 @@ func runDiff(flags *diffFlags, args []string) error { return err } if path == "" { - return fmt.Errorf("empty manifest path") + return errors.New("empty manifest path") } existingManifest, err := ioutil.ReadFile(path) if err != nil { diff --git a/cmd/kubeadm/app/cmd/upgrade/node.go b/cmd/kubeadm/app/cmd/upgrade/node.go index 346e83b70f070..dbe3c9d9c5a52 100644 --- a/cmd/kubeadm/app/cmd/upgrade/node.go +++ b/cmd/kubeadm/app/cmd/upgrade/node.go @@ -23,8 +23,8 @@ import ( "path/filepath" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/util/version" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" @@ -66,6 +66,7 @@ type controlplaneUpgradeFlags struct { kubeConfigPath string advertiseAddress string nodeName string + etcdUpgrade bool dryRun bool } @@ -113,6 +114,7 @@ func NewCmdUpgradeControlPlane() *cobra.Command { flags := &controlplaneUpgradeFlags{ kubeConfigPath: constants.GetKubeletKubeConfigPath(), advertiseAddress: "", + etcdUpgrade: true, dryRun: false, } @@ -149,13 +151,14 @@ func NewCmdUpgradeControlPlane() *cobra.Command { options.AddKubeConfigFlag(cmd.Flags(), &flags.kubeConfigPath) cmd.Flags().BoolVar(&flags.dryRun, "dry-run", flags.dryRun, "Do not change any state, just output the actions that would be performed.") + cmd.Flags().BoolVar(&flags.etcdUpgrade, "etcd-upgrade", flags.etcdUpgrade, "Perform the upgrade of etcd.") return cmd } // RunUpgradeNodeConfig is executed when `kubeadm upgrade node config` runs. func RunUpgradeNodeConfig(flags *nodeUpgradeFlags) error { if len(flags.kubeletVersionStr) == 0 { - return fmt.Errorf("The --kubelet-version argument is required") + return errors.New("the --kubelet-version argument is required") } // Set up the kubelet directory to use. If dry-running, use a fake directory @@ -166,7 +169,7 @@ func RunUpgradeNodeConfig(flags *nodeUpgradeFlags) error { client, err := getClient(flags.kubeConfigPath, flags.dryRun) if err != nil { - return fmt.Errorf("couldn't create a Kubernetes client from file %q: %v", flags.kubeConfigPath, err) + return errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath) } // Parse the desired kubelet version @@ -181,7 +184,7 @@ func RunUpgradeNodeConfig(flags *nodeUpgradeFlags) error { // If we're dry-running, print the generated manifests, otherwise do nothing if err := printFilesIfDryRunning(flags.dryRun, kubeletDir); err != nil { - return fmt.Errorf("error printing files on dryrun: %v", err) + return errors.Wrap(err, "error printing files on dryrun") } fmt.Println("[upgrade] The configuration for this node was successfully updated!") @@ -194,7 +197,7 @@ func getKubeletDir(dryRun bool) (string, error) { if dryRun { dryRunDir, err := ioutil.TempDir("", "kubeadm-init-dryrun") if err != nil { - return "", fmt.Errorf("couldn't create a temporary directory: %v", err) + return "", errors.Wrap(err, "couldn't create a temporary directory") } return dryRunDir, nil } @@ -220,7 +223,7 @@ func RunUpgradeControlPlane(flags *controlplaneUpgradeFlags) error { client, err := getClient(flags.kubeConfigPath, flags.dryRun) if err != nil { - return fmt.Errorf("Couldn't create a Kubernetes client from file %q: %v", flags.kubeConfigPath, err) + return errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath) } waiter := apiclient.NewKubeWaiter(client, upgrade.UpgradeManifestTimeout, os.Stdout) @@ -228,22 +231,22 @@ func RunUpgradeControlPlane(flags *controlplaneUpgradeFlags) error { // Fetches the cluster configuration cfg, err := configutil.FetchConfigFromFileOrCluster(client, os.Stdout, "upgrade", "", false) if err != nil { - return fmt.Errorf("Unable to fetch the kubeadm-config ConfigMap: %v", err) + return errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap") } // Rotate API server certificate if needed if err := upgrade.BackupAPIServerCertIfNeeded(cfg, flags.dryRun); err != nil { - return fmt.Errorf("Unable to rotate API server certificate: %v", err) + return errors.Wrap(err, "unable to rotate API server certificate") } - // Upgrade the control plane + // Upgrade the control plane and etcd if installed on this node fmt.Printf("[upgrade] Upgrading your Static Pod-hosted control plane instance to version %q...\n", cfg.KubernetesVersion) if flags.dryRun { return DryRunStaticPodUpgrade(cfg) } - if err := PerformStaticPodUpgrade(client, waiter, cfg, false); err != nil { - return fmt.Errorf("Couldn't complete the static pod upgrade: %v", err) + if err := PerformStaticPodUpgrade(client, waiter, cfg, flags.etcdUpgrade); err != nil { + return errors.Wrap(err, "couldn't complete the static pod upgrade") } fmt.Println("[upgrade] The control plane instance for this node was successfully updated!") diff --git a/cmd/kubeadm/app/cmd/upgrade/plan.go b/cmd/kubeadm/app/cmd/upgrade/plan.go index a1478b4bfbf88..b71719c1adad2 100644 --- a/cmd/kubeadm/app/cmd/upgrade/plan.go +++ b/cmd/kubeadm/app/cmd/upgrade/plan.go @@ -25,8 +25,8 @@ import ( "text/tabwriter" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/util/version" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" @@ -111,11 +111,8 @@ func RunPlan(flags *planFlags) error { } etcdClient = client } else { - client, err := etcdutil.NewFromStaticPod( - []string{fmt.Sprintf("localhost:%d", constants.EtcdListenClientPort)}, - constants.GetStaticPodDirectory(), - upgradeVars.cfg.CertificatesDir, - ) + // Connects to local/stacked etcd existing in the cluster + client, err := etcdutil.NewFromCluster(upgradeVars.client, upgradeVars.cfg.CertificatesDir) if err != nil { return err } @@ -126,7 +123,7 @@ func RunPlan(flags *planFlags) error { glog.V(1).Infof("[upgrade/plan] computing upgrade possibilities") availUpgrades, err := upgrade.GetAvailableUpgrades(upgradeVars.versionGetter, flags.allowExperimentalUpgrades, flags.allowRCUpgrades, etcdClient, upgradeVars.cfg.FeatureGates, upgradeVars.client) if err != nil { - return fmt.Errorf("[upgrade/versions] FATAL: %v", err) + return errors.Wrap(err, "[upgrade/versions] FATAL") } // Tell the user which upgrades are available diff --git a/cmd/kubeadm/app/cmd/upgrade/upgrade.go b/cmd/kubeadm/app/cmd/upgrade/upgrade.go index 1d2ccabd6c18f..e4740f5c37a87 100644 --- a/cmd/kubeadm/app/cmd/upgrade/upgrade.go +++ b/cmd/kubeadm/app/cmd/upgrade/upgrade.go @@ -77,7 +77,6 @@ func addApplyPlanFlags(fs *pflag.FlagSet, flags *applyPlanFlags) { fs.BoolVar(&flags.allowExperimentalUpgrades, "allow-experimental-upgrades", flags.allowExperimentalUpgrades, "Show unstable versions of Kubernetes as an upgrade alternative and allow upgrading to an alpha/beta/release candidate versions of Kubernetes.") fs.BoolVar(&flags.allowRCUpgrades, "allow-release-candidate-upgrades", flags.allowRCUpgrades, "Show release candidate versions of Kubernetes as an upgrade alternative and allow upgrading to a release candidate versions of Kubernetes.") fs.BoolVar(&flags.printConfig, "print-config", flags.printConfig, "Specifies whether the configuration file that will be used in the upgrade should be printed or not.") - fs.MarkDeprecated("skip-preflight-checks", "it is now equivalent to --ignore-preflight-errors=all") fs.StringVar(&flags.featureGatesString, "feature-gates", flags.featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+ "Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n")) options.AddIgnorePreflightErrorsFlag(fs, &flags.ignorePreflightErrors) diff --git a/cmd/kubeadm/app/cmd/util/BUILD b/cmd/kubeadm/app/cmd/util/BUILD index 63418fadf02d4..aadf9f89f77cf 100644 --- a/cmd/kubeadm/app/cmd/util/BUILD +++ b/cmd/kubeadm/app/cmd/util/BUILD @@ -16,6 +16,7 @@ go_library( "//pkg/util/normalizer:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", ], ) diff --git a/cmd/kubeadm/app/cmd/util/cmdutil.go b/cmd/kubeadm/app/cmd/util/cmdutil.go index 748e80d2fb6ad..80a8563174952 100644 --- a/cmd/kubeadm/app/cmd/util/cmdutil.go +++ b/cmd/kubeadm/app/cmd/util/cmdutil.go @@ -17,8 +17,7 @@ limitations under the License. package util import ( - "fmt" - + "github.com/pkg/errors" "github.com/spf13/cobra" "k8s.io/client-go/tools/clientcmd" @@ -33,10 +32,10 @@ import ( func SubCmdRunE(name string) func(*cobra.Command, []string) error { return func(_ *cobra.Command, args []string) error { if len(args) < 1 { - return fmt.Errorf("missing subcommand; %q is not meant to be run on its own", name) + return errors.Errorf("missing subcommand; %q is not meant to be run on its own", name) } - return fmt.Errorf("invalid subcommand: %q", args[0]) + return errors.Errorf("invalid subcommand: %q", args[0]) } } @@ -51,12 +50,12 @@ func ValidateExactArgNumber(args []string, supportedArgs []string) error { } // break early for too many arguments if validArgs > lenSupported { - return fmt.Errorf("too many arguments. Required arguments: %v", supportedArgs) + return errors.Errorf("too many arguments. Required arguments: %v", supportedArgs) } } if validArgs < lenSupported { - return fmt.Errorf("missing one or more required arguments. Required arguments: %v", supportedArgs) + return errors.Errorf("missing one or more required arguments. Required arguments: %v", supportedArgs) } return nil } diff --git a/cmd/kubeadm/app/cmd/util/join.go b/cmd/kubeadm/app/cmd/util/join.go index 725dd4cd11df9..02408dae303a2 100644 --- a/cmd/kubeadm/app/cmd/util/join.go +++ b/cmd/kubeadm/app/cmd/util/join.go @@ -19,10 +19,10 @@ package util import ( "bytes" "crypto/x509" - "fmt" "html/template" "strings" + "github.com/pkg/errors" "k8s.io/client-go/tools/clientcmd" clientcertutil "k8s.io/client-go/util/cert" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" @@ -34,18 +34,18 @@ var joinCommandTemplate = template.Must(template.New("join").Parse(`` + )) // GetJoinCommand returns the kubeadm join command for a given token and -// and kubernetes cluster (the current cluster in the kubeconfig file) +// and Kubernetes cluster (the current cluster in the kubeconfig file) func GetJoinCommand(kubeConfigFile string, token string, skipTokenPrint bool) (string, error) { // load the kubeconfig file to get the CA certificate and endpoint config, err := clientcmd.LoadFromFile(kubeConfigFile) if err != nil { - return "", fmt.Errorf("failed to load kubeconfig: %v", err) + return "", errors.Wrap(err, "failed to load kubeconfig") } // load the default cluster config clusterConfig := kubeconfigutil.GetClusterFromKubeConfig(config) if clusterConfig == nil { - return "", fmt.Errorf("failed to get default cluster config") + return "", errors.New("failed to get default cluster config") } // load CA certificates from the kubeconfig (either from PEM data or by file path) @@ -53,15 +53,15 @@ func GetJoinCommand(kubeConfigFile string, token string, skipTokenPrint bool) (s if clusterConfig.CertificateAuthorityData != nil { caCerts, err = clientcertutil.ParseCertsPEM(clusterConfig.CertificateAuthorityData) if err != nil { - return "", fmt.Errorf("failed to parse CA certificate from kubeconfig: %v", err) + return "", errors.Wrap(err, "failed to parse CA certificate from kubeconfig") } } else if clusterConfig.CertificateAuthority != "" { caCerts, err = clientcertutil.CertsFromFile(clusterConfig.CertificateAuthority) if err != nil { - return "", fmt.Errorf("failed to load CA certificate referenced by kubeconfig: %v", err) + return "", errors.Wrap(err, "failed to load CA certificate referenced by kubeconfig") } } else { - return "", fmt.Errorf("no CA certificates found in kubeconfig") + return "", errors.New("no CA certificates found in kubeconfig") } // hash all the CA certs and include their public key pins as trusted values @@ -83,7 +83,7 @@ func GetJoinCommand(kubeConfigFile string, token string, skipTokenPrint bool) (s var out bytes.Buffer err = joinCommandTemplate.Execute(&out, ctx) if err != nil { - return "", fmt.Errorf("failed to render join command template: %v", err) + return "", errors.Wrap(err, "failed to render join command template") } return out.String(), nil } diff --git a/cmd/kubeadm/app/cmd/version.go b/cmd/kubeadm/app/cmd/version.go index 25aea36fb0c30..eb0628c6f1b02 100644 --- a/cmd/kubeadm/app/cmd/version.go +++ b/cmd/kubeadm/app/cmd/version.go @@ -23,6 +23,7 @@ import ( "github.com/ghodss/yaml" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/spf13/cobra" apimachineryversion "k8s.io/apimachinery/pkg/version" @@ -82,7 +83,7 @@ func RunVersion(out io.Writer, cmd *cobra.Command) error { } fmt.Fprintln(out, string(y)) default: - return fmt.Errorf("invalid output format: %s", of) + return errors.Errorf("invalid output format: %s", of) } return nil diff --git a/cmd/kubeadm/app/cmd/version_test.go b/cmd/kubeadm/app/cmd/version_test.go index 1f661913acd87..e22036b7f872b 100644 --- a/cmd/kubeadm/app/cmd/version_test.go +++ b/cmd/kubeadm/app/cmd/version_test.go @@ -19,8 +19,8 @@ package cmd import ( "bytes" "encoding/json" - "fmt" "github.com/ghodss/yaml" + "github.com/pkg/errors" "testing" ) @@ -80,7 +80,7 @@ func TestRunVersion(t *testing.T) { goto error } if buf.String() == "" { - err = fmt.Errorf("empty output") + err = errors.New("empty output") goto error } if tc.shouldBeValidYAML { diff --git a/cmd/kubeadm/app/componentconfigs/BUILD b/cmd/kubeadm/app/componentconfigs/BUILD index 59ab6d3b50724..736c6b29a35e4 100644 --- a/cmd/kubeadm/app/componentconfigs/BUILD +++ b/cmd/kubeadm/app/componentconfigs/BUILD @@ -32,6 +32,7 @@ go_library( "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/kube-proxy/config/v1alpha1:go_default_library", "//staging/src/k8s.io/kubelet/config/v1beta1:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library", ], ) diff --git a/cmd/kubeadm/app/componentconfigs/config.go b/cmd/kubeadm/app/componentconfigs/config.go index 784ab523409ea..6db8e61fe2ba3 100644 --- a/cmd/kubeadm/app/componentconfigs/config.go +++ b/cmd/kubeadm/app/componentconfigs/config.go @@ -17,7 +17,7 @@ limitations under the License. package componentconfigs import ( - "fmt" + "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -41,7 +41,8 @@ func GetFromKubeletConfigMap(client clientset.Interface, version *version.Versio kubeletConfigData, ok := kubeletCfg.Data[kubeadmconstants.KubeletBaseConfigurationConfigMapKey] if !ok { - return nil, fmt.Errorf("unexpected error when reading %s ConfigMap: %s key value pair missing", configMapName, kubeadmconstants.KubeletBaseConfigurationConfigMapKey) + return nil, errors.Errorf("unexpected error when reading %s ConfigMap: %s key value pair missing", + configMapName, kubeadmconstants.KubeletBaseConfigurationConfigMapKey) } // Decodes the kubeletConfigData into the internal component config @@ -66,7 +67,8 @@ func GetFromKubeProxyConfigMap(client clientset.Interface, version *version.Vers kubeproxyConfigData, ok := kubeproxyCfg.Data[kubeadmconstants.KubeProxyConfigMapKey] if !ok { - return nil, fmt.Errorf("unexpected error when reading %s ConfigMap: %s key value pair missing", kubeadmconstants.KubeProxyConfigMap, kubeadmconstants.KubeProxyConfigMapKey) + return nil, errors.Errorf("unexpected error when reading %s ConfigMap: %s key value pair missing", + kubeadmconstants.KubeProxyConfigMap, kubeadmconstants.KubeProxyConfigMapKey) } // Decodes the Config map dat into the internal component config diff --git a/cmd/kubeadm/app/componentconfigs/defaults.go b/cmd/kubeadm/app/componentconfigs/defaults.go index 082e5448c9e91..7920ab66a9a23 100644 --- a/cmd/kubeadm/app/componentconfigs/defaults.go +++ b/cmd/kubeadm/app/componentconfigs/defaults.go @@ -28,7 +28,7 @@ import ( ) const ( - // KubeproxyKubeConfigFileName defines the file name for the kube-proxy's KubeConfig file + // KubeproxyKubeConfigFileName defines the file name for the kube-proxy's kubeconfig file KubeproxyKubeConfigFileName = "/var/lib/kube-proxy/kubeconfig.conf" ) diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go index 04e7595f48c4d..71cc804b2a794 100644 --- a/cmd/kubeadm/app/constants/constants.go +++ b/cmd/kubeadm/app/constants/constants.go @@ -31,7 +31,7 @@ import ( "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" ) -// KubernetesDir is the directory kubernetes owns for storing various configuration files +// KubernetesDir is the directory Kubernetes owns for storing various configuration files // This semi-constant MUST NOT be modified during runtime. It's a variable solely for use in unit testing. var KubernetesDir = "/etc/kubernetes" @@ -135,18 +135,18 @@ const ( // FrontProxyClientCertCommonName defines front proxy certificate common name FrontProxyClientCertCommonName = "front-proxy-client" //used as subject.commonname attribute (CN) - // AdminKubeConfigFileName defines name for the KubeConfig aimed to be used by the superuser/admin of the cluster + // AdminKubeConfigFileName defines name for the kubeconfig aimed to be used by the superuser/admin of the cluster AdminKubeConfigFileName = "admin.conf" - // KubeletBootstrapKubeConfigFileName defines the file name for the KubeConfig that the kubelet will use to do + // KubeletBootstrapKubeConfigFileName defines the file name for the kubeconfig that the kubelet will use to do // the TLS bootstrap to get itself an unique credential KubeletBootstrapKubeConfigFileName = "bootstrap-kubelet.conf" - // KubeletKubeConfigFileName defines the file name for the KubeConfig that the master kubelet will use for talking + // KubeletKubeConfigFileName defines the file name for the kubeconfig that the master kubelet will use for talking // to the API server KubeletKubeConfigFileName = "kubelet.conf" - // ControllerManagerKubeConfigFileName defines the file name for the controller manager's KubeConfig file + // ControllerManagerKubeConfigFileName defines the file name for the controller manager's kubeconfig file ControllerManagerKubeConfigFileName = "controller-manager.conf" - // SchedulerKubeConfigFileName defines the file name for the scheduler's KubeConfig file + // SchedulerKubeConfigFileName defines the file name for the scheduler's kubeconfig file SchedulerKubeConfigFileName = "scheduler.conf" // Some well-known users and groups in the core Kubernetes authorization system @@ -178,6 +178,9 @@ const ( // TLSBootstrapTimeout specifies how long kubeadm should wait for the kubelet to perform the TLS Bootstrap TLSBootstrapTimeout = 2 * time.Minute + // DefaultControlPlaneTimeout specifies the default control plane (actually API Server) timeout for use by kubeadm + DefaultControlPlaneTimeout = 4 * time.Minute + // MinimumAddressesInServiceSubnet defines minimum amount of nodes the Service subnet should allow. // We need at least ten, because the DNS service is always at the tenth cluster clusterIP MinimumAddressesInServiceSubnet = 10 @@ -356,7 +359,7 @@ var ( // MinimumKubeletVersion specifies the minimum version of kubelet which kubeadm supports MinimumKubeletVersion = version.MustParseSemantic("v1.11.0") - // SupportedEtcdVersion lists officially supported etcd versions with corresponding kubernetes releases + // SupportedEtcdVersion lists officially supported etcd versions with corresponding Kubernetes releases SupportedEtcdVersion = map[uint8]string{ 10: "3.1.12", 11: "3.2.18", @@ -364,7 +367,7 @@ var ( } ) -// EtcdSupportedVersion returns officially supported version of etcd for a specific kubernetes release +// EtcdSupportedVersion returns officially supported version of etcd for a specific Kubernetes release // if passed version is not listed, the function returns nil and an error func EtcdSupportedVersion(versionString string) (*version.Version, error) { kubernetesVersion, err := version.ParseSemantic(versionString) @@ -379,7 +382,7 @@ func EtcdSupportedVersion(versionString string) (*version.Version, error) { } return etcdVersion, nil } - return nil, fmt.Errorf("Unsupported or unknown kubernetes version(%v)", kubernetesVersion) + return nil, fmt.Errorf("Unsupported or unknown Kubernetes version(%v)", kubernetesVersion) } // GetStaticPodDirectory returns the location on the disk where the Static Pod should be present diff --git a/cmd/kubeadm/app/constants/constants_test.go b/cmd/kubeadm/app/constants/constants_test.go index 1882a284103c6..50420c567d100 100644 --- a/cmd/kubeadm/app/constants/constants_test.go +++ b/cmd/kubeadm/app/constants/constants_test.go @@ -151,7 +151,7 @@ func TestEtcdSupportedVersion(t *testing.T) { { kubernetesVersion: "1.99.0", expectedVersion: nil, - expectedError: fmt.Errorf("Unsupported or unknown kubernetes version(1.99.0)"), + expectedError: fmt.Errorf("Unsupported or unknown Kubernetes version(1.99.0)"), }, { kubernetesVersion: "1.10.0", diff --git a/cmd/kubeadm/app/discovery/BUILD b/cmd/kubeadm/app/discovery/BUILD index 763bfc317432e..f6f53e40f8c28 100644 --- a/cmd/kubeadm/app/discovery/BUILD +++ b/cmd/kubeadm/app/discovery/BUILD @@ -17,6 +17,7 @@ go_library( "//cmd/kubeadm/app/discovery/token:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/discovery/discovery.go b/cmd/kubeadm/app/discovery/discovery.go index 3cbbafa55685c..7003d7a8babac 100644 --- a/cmd/kubeadm/app/discovery/discovery.go +++ b/cmd/kubeadm/app/discovery/discovery.go @@ -17,9 +17,10 @@ limitations under the License. package discovery import ( - "fmt" "net/url" + "github.com/pkg/errors" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/discovery/file" @@ -31,14 +32,14 @@ import ( // TokenUser defines token user const TokenUser = "tls-bootstrap-token-user" -// For returns a KubeConfig object that can be used for doing the TLS Bootstrap with the right credentials +// For returns a kubeconfig object that can be used for doing the TLS Bootstrap with the right credentials // Also, before returning anything, it makes sure it can trust the API Server func For(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Config, error) { // TODO: Print summary info about the CA certificate, along with the checksum signature // we also need an ability for the user to configure the client to validate received CA cert against a checksum config, err := DiscoverValidatedKubeConfig(cfg) if err != nil { - return nil, fmt.Errorf("couldn't validate the identity of the API Server: %v", err) + return nil, errors.Wrap(err, "couldn't validate the identity of the API Server") } if len(cfg.Discovery.TLSBootstrapToken) == 0 { @@ -66,7 +67,7 @@ func DiscoverValidatedKubeConfig(cfg *kubeadmapi.JoinConfiguration) (*clientcmda case cfg.Discovery.BootstrapToken != nil: return token.RetrieveValidatedConfigInfo(cfg) default: - return nil, fmt.Errorf("couldn't find a valid discovery configuration") + return nil, errors.New("couldn't find a valid discovery configuration") } } diff --git a/cmd/kubeadm/app/discovery/file/BUILD b/cmd/kubeadm/app/discovery/file/BUILD index 92f9da337f75d..baf06f9a06bea 100644 --- a/cmd/kubeadm/app/discovery/file/BUILD +++ b/cmd/kubeadm/app/discovery/file/BUILD @@ -19,6 +19,7 @@ go_library( "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/discovery/file/file.go b/cmd/kubeadm/app/discovery/file/file.go index b119f443f4d49..a7b60d616bb42 100644 --- a/cmd/kubeadm/app/discovery/file/file.go +++ b/cmd/kubeadm/app/discovery/file/file.go @@ -19,6 +19,8 @@ package file import ( "fmt" "io/ioutil" + + "github.com/pkg/errors" "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -50,7 +52,7 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien return nil, err } - // This is the cluster object we've got from the cluster-info KubeConfig file + // This is the cluster object we've got from the cluster-info kubeconfig file defaultCluster := kubeconfigutil.GetClusterFromKubeConfig(config) // Create a new kubeconfig object from the given, just copy over the server and the CA cert @@ -66,7 +68,7 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien user := config.Contexts[config.CurrentContext].AuthInfo authInfo, ok := config.AuthInfos[user] if !ok || authInfo == nil { - return nil, fmt.Errorf("empty settings for user %q", user) + return nil, errors.Errorf("empty settings for user %q", user) } if len(authInfo.ClientCertificateData) == 0 && len(authInfo.ClientCertificate) != 0 { clientCert, err := ioutil.ReadFile(authInfo.ClientCertificate) @@ -84,7 +86,7 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien } if len(authInfo.ClientCertificateData) == 0 || len(authInfo.ClientKeyData) == 0 { - return nil, fmt.Errorf("couldn't read authentication info from the given kubeconfig file") + return nil, errors.New("couldn't read authentication info from the given kubeconfig file") } kubeconfig = kubeconfigutil.CreateWithCerts( defaultCluster.Server, @@ -141,23 +143,23 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien func tryParseClusterInfoFromConfigMap(cm *v1.ConfigMap) (*clientcmdapi.Config, error) { kubeConfigString, ok := cm.Data[bootstrapapi.KubeConfigKey] if !ok || len(kubeConfigString) == 0 { - return nil, fmt.Errorf("no %s key in ConfigMap", bootstrapapi.KubeConfigKey) + return nil, errors.Errorf("no %s key in ConfigMap", bootstrapapi.KubeConfigKey) } parsedKubeConfig, err := clientcmd.Load([]byte(kubeConfigString)) if err != nil { - return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s ConfigMap: %v", bootstrapapi.ConfigMapClusterInfo, err) + return nil, errors.Wrapf(err, "couldn't parse the kubeconfig file in the %s ConfigMap", bootstrapapi.ConfigMapClusterInfo) } return parsedKubeConfig, nil } -// validateKubeConfig makes sure the user-provided KubeConfig file is valid +// validateKubeConfig makes sure the user-provided kubeconfig file is valid func validateKubeConfig(config *clientcmdapi.Config) error { if len(config.Clusters) < 1 { - return fmt.Errorf("the provided cluster-info KubeConfig file must have at least one Cluster defined") + return errors.New("the provided cluster-info kubeconfig file must have at least one Cluster defined") } defaultCluster := kubeconfigutil.GetClusterFromKubeConfig(config) if defaultCluster == nil { - return fmt.Errorf("the provided cluster-info KubeConfig file must have an unnamed Cluster or a CurrentContext that specifies a non-nil Cluster") + return errors.New("the provided cluster-info kubeconfig file must have an unnamed Cluster or a CurrentContext that specifies a non-nil Cluster") } return clientcmd.Validate(*config) } diff --git a/cmd/kubeadm/app/discovery/token/BUILD b/cmd/kubeadm/app/discovery/token/BUILD index 87ba6d47ded36..5b6008286cbe1 100644 --- a/cmd/kubeadm/app/discovery/token/BUILD +++ b/cmd/kubeadm/app/discovery/token/BUILD @@ -22,6 +22,7 @@ go_library( "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -42,8 +43,5 @@ go_test( name = "go_default_test", srcs = ["token_test.go"], embed = [":go_default_library"], - deps = [ - "//cmd/kubeadm/app/util/kubeconfig:go_default_library", - "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", - ], + deps = ["//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library"], ) diff --git a/cmd/kubeadm/app/discovery/token/token.go b/cmd/kubeadm/app/discovery/token/token.go index f919d753cd85a..9e874815b0520 100644 --- a/cmd/kubeadm/app/discovery/token/token.go +++ b/cmd/kubeadm/app/discovery/token/token.go @@ -24,6 +24,8 @@ import ( "sync" "time" + "github.com/pkg/errors" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" @@ -58,7 +60,7 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda // The function below runs for every endpoint, and all endpoints races with each other. // The endpoint that wins the race and completes the task first gets its kubeconfig returned below - baseKubeConfig, err := runForEndpointsAndReturnFirst(cfg.Discovery.BootstrapToken.APIServerEndpoints, cfg.Discovery.Timeout.Duration, func(endpoint string) (*clientcmdapi.Config, error) { + baseKubeConfig, err := fetchKubeConfigWithTimeout(cfg.Discovery.BootstrapToken.APIServerEndpoint, cfg.Discovery.Timeout.Duration, func(endpoint string) (*clientcmdapi.Config, error) { insecureBootstrapConfig := buildInsecureBootstrapKubeConfig(endpoint, cfg.ClusterName) clusterName := insecureBootstrapConfig.Contexts[insecureBootstrapConfig.CurrentContext].Cluster @@ -85,19 +87,20 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda // Validate the MAC on the kubeconfig from the ConfigMap and load it insecureKubeconfigString, ok := insecureClusterInfo.Data[bootstrapapi.KubeConfigKey] if !ok || len(insecureKubeconfigString) == 0 { - return nil, fmt.Errorf("there is no %s key in the %s ConfigMap. This API Server isn't set up for token bootstrapping, can't connect", bootstrapapi.KubeConfigKey, bootstrapapi.ConfigMapClusterInfo) + return nil, errors.Errorf("there is no %s key in the %s ConfigMap. This API Server isn't set up for token bootstrapping, can't connect", + bootstrapapi.KubeConfigKey, bootstrapapi.ConfigMapClusterInfo) } detachedJWSToken, ok := insecureClusterInfo.Data[bootstrapapi.JWSSignatureKeyPrefix+token.ID] if !ok || len(detachedJWSToken) == 0 { - return nil, fmt.Errorf("token id %q is invalid for this cluster or it has expired. Use \"kubeadm token create\" on the master node to creating a new valid token", token.ID) + return nil, errors.Errorf("token id %q is invalid for this cluster or it has expired. Use \"kubeadm token create\" on the master node to creating a new valid token", token.ID) } if !bootstrap.DetachedTokenIsValid(detachedJWSToken, insecureKubeconfigString, token.ID, token.Secret) { - return nil, fmt.Errorf("failed to verify JWS signature of received cluster info object, can't trust this API Server") + return nil, errors.New("failed to verify JWS signature of received cluster info object, can't trust this API Server") } insecureKubeconfigBytes := []byte(insecureKubeconfigString) insecureConfig, err := clientcmd.Load(insecureKubeconfigBytes) if err != nil { - return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err) + return nil, errors.Wrapf(err, "couldn't parse the kubeconfig file in the %s configmap", bootstrapapi.ConfigMapClusterInfo) } // If no TLS root CA pinning was specified, we're done @@ -108,7 +111,7 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda // Load the cluster CA from the Config if len(insecureConfig.Clusters) != 1 { - return nil, fmt.Errorf("expected the kubeconfig file in the %s configmap to have a single cluster, but it had %d", bootstrapapi.ConfigMapClusterInfo, len(insecureConfig.Clusters)) + return nil, errors.Errorf("expected the kubeconfig file in the %s configmap to have a single cluster, but it had %d", bootstrapapi.ConfigMapClusterInfo, len(insecureConfig.Clusters)) } var clusterCABytes []byte for _, cluster := range insecureConfig.Clusters { @@ -116,14 +119,14 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda } clusterCA, err := parsePEMCert(clusterCABytes) if err != nil { - return nil, fmt.Errorf("failed to parse cluster CA from the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err) + return nil, errors.Wrapf(err, "failed to parse cluster CA from the %s configmap", bootstrapapi.ConfigMapClusterInfo) } // Validate the cluster CA public key against the pinned set err = pubKeyPins.Check(clusterCA) if err != nil { - return nil, fmt.Errorf("cluster CA found in %s configmap is invalid: %v", bootstrapapi.ConfigMapClusterInfo, err) + return nil, errors.Wrapf(err, "cluster CA found in %s configmap is invalid", bootstrapapi.ConfigMapClusterInfo) } // Now that we know the proported cluster CA, connect back a second time validating with that CA @@ -148,12 +151,12 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda // Pull the kubeconfig from the securely-obtained ConfigMap and validate that it's the same as what we found the first time secureKubeconfigBytes := []byte(secureClusterInfo.Data[bootstrapapi.KubeConfigKey]) if !bytes.Equal(secureKubeconfigBytes, insecureKubeconfigBytes) { - return nil, fmt.Errorf("the second kubeconfig from the %s configmap (using validated TLS) was different from the first", bootstrapapi.ConfigMapClusterInfo) + return nil, errors.Errorf("the second kubeconfig from the %s configmap (using validated TLS) was different from the first", bootstrapapi.ConfigMapClusterInfo) } secureKubeconfig, err := clientcmd.Load(secureKubeconfigBytes) if err != nil { - return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err) + return nil, errors.Wrapf(err, "couldn't parse the kubeconfig file in the %s configmap", bootstrapapi.ConfigMapClusterInfo) } fmt.Printf("[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server %q\n", endpoint) @@ -166,7 +169,7 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda return baseKubeConfig, nil } -// buildInsecureBootstrapKubeConfig makes a KubeConfig object that connects insecurely to the API Server for bootstrapping purposes +// buildInsecureBootstrapKubeConfig makes a kubeconfig object that connects insecurely to the API Server for bootstrapping purposes func buildInsecureBootstrapKubeConfig(endpoint, clustername string) *clientcmdapi.Config { masterEndpoint := fmt.Sprintf("https://%s", endpoint) bootstrapConfig := kubeconfigutil.CreateBasic(masterEndpoint, clustername, BootstrapUser, []byte{}) @@ -174,44 +177,44 @@ func buildInsecureBootstrapKubeConfig(endpoint, clustername string) *clientcmdap return bootstrapConfig } -// buildSecureBootstrapKubeConfig makes a KubeConfig object that connects securely to the API Server for bootstrapping purposes (validating with the specified CA) +// buildSecureBootstrapKubeConfig makes a kubeconfig object that connects securely to the API Server for bootstrapping purposes (validating with the specified CA) func buildSecureBootstrapKubeConfig(endpoint string, caCert []byte, clustername string) *clientcmdapi.Config { masterEndpoint := fmt.Sprintf("https://%s", endpoint) bootstrapConfig := kubeconfigutil.CreateBasic(masterEndpoint, clustername, BootstrapUser, caCert) return bootstrapConfig } -// runForEndpointsAndReturnFirst loops the endpoints slice and let's the endpoints race for connecting to the master -func runForEndpointsAndReturnFirst(endpoints []string, discoveryTimeout time.Duration, fetchKubeConfigFunc func(string) (*clientcmdapi.Config, error)) (*clientcmdapi.Config, error) { +// fetchKubeConfigWithTimeout tries to run fetchKubeConfigFunc on every DiscoveryRetryInterval, but until discoveryTimeout is reached +func fetchKubeConfigWithTimeout(apiEndpoint string, discoveryTimeout time.Duration, fetchKubeConfigFunc func(string) (*clientcmdapi.Config, error)) (*clientcmdapi.Config, error) { stopChan := make(chan struct{}) var resultingKubeConfig *clientcmdapi.Config var once sync.Once var wg sync.WaitGroup - for _, endpoint := range endpoints { - wg.Add(1) - go func(apiEndpoint string) { - defer wg.Done() - wait.Until(func() { - fmt.Printf("[discovery] Trying to connect to API Server %q\n", apiEndpoint) - cfg, err := fetchKubeConfigFunc(apiEndpoint) - if err != nil { - fmt.Printf("[discovery] Failed to connect to API Server %q: %v\n", apiEndpoint, err) - return - } - fmt.Printf("[discovery] Successfully established connection with API Server %q\n", apiEndpoint) - - // connection established, stop all wait threads - once.Do(func() { - close(stopChan) - resultingKubeConfig = cfg - }) - }, constants.DiscoveryRetryInterval, stopChan) - }(endpoint) - } + + wg.Add(1) + go func() { + defer wg.Done() + wait.Until(func() { + fmt.Printf("[discovery] Trying to connect to API Server %q\n", apiEndpoint) + cfg, err := fetchKubeConfigFunc(apiEndpoint) + if err != nil { + fmt.Printf("[discovery] Failed to connect to API Server %q: %v\n", apiEndpoint, err) + return + } + fmt.Printf("[discovery] Successfully established connection with API Server %q\n", apiEndpoint) + once.Do(func() { + resultingKubeConfig = cfg + close(stopChan) + }) + }, constants.DiscoveryRetryInterval, stopChan) + }() + select { case <-time.After(discoveryTimeout): - close(stopChan) - err := fmt.Errorf("abort connecting to API servers after timeout of %v", discoveryTimeout) + once.Do(func() { + close(stopChan) + }) + err := errors.Errorf("abort connecting to API servers after timeout of %v", discoveryTimeout) fmt.Printf("[discovery] %v\n", err) wg.Wait() return nil, err @@ -225,10 +228,10 @@ func runForEndpointsAndReturnFirst(endpoints []string, discoveryTimeout time.Dur func parsePEMCert(certData []byte) (*x509.Certificate, error) { pemBlock, trailingData := pem.Decode(certData) if pemBlock == nil { - return nil, fmt.Errorf("invalid PEM data") + return nil, errors.New("invalid PEM data") } if len(trailingData) != 0 { - return nil, fmt.Errorf("trailing data after first PEM block") + return nil, errors.New("trailing data after first PEM block") } return x509.ParseCertificate(pemBlock.Bytes) } diff --git a/cmd/kubeadm/app/discovery/token/token_test.go b/cmd/kubeadm/app/discovery/token/token_test.go index 6140793bf951a..8be1147e0e107 100644 --- a/cmd/kubeadm/app/discovery/token/token_test.go +++ b/cmd/kubeadm/app/discovery/token/token_test.go @@ -17,12 +17,11 @@ limitations under the License. package token import ( - "strconv" + "fmt" "testing" "time" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" ) // testCertPEM is a simple self-signed test certificate issued with the openssl CLI: @@ -49,41 +48,49 @@ c1vuFqTnJBPcb7W//R/GI2Paicm1cmns9NLnPR35exHxFTy+D1yxmGokpoPMdife aH+sfuxT8xeTPb3kjzF9eJTlnEquUDLM -----END CERTIFICATE-----` -func TestRunForEndpointsAndReturnFirst(t *testing.T) { +func TestFetchKubeConfigWithTimeout(t *testing.T) { + const testAPIEndpoint = "sample-endpoint:1234" tests := []struct { - endpoints []string - expectedEndpoint string + name string + discoveryTimeout time.Duration + shouldFail bool }{ { - endpoints: []string{"1", "2", "3"}, - expectedEndpoint: "1", + name: "Timeout if value is not returned on time", + discoveryTimeout: 1 * time.Second, + shouldFail: true, }, { - endpoints: []string{"6", "5"}, - expectedEndpoint: "5", - }, - { - endpoints: []string{"10", "4"}, - expectedEndpoint: "4", + name: "Don't timeout if value is returned on time", + discoveryTimeout: 5 * time.Second, + shouldFail: false, }, } - for _, rt := range tests { - returnKubeConfig, err := runForEndpointsAndReturnFirst(rt.endpoints, 5*time.Minute, func(endpoint string) (*clientcmdapi.Config, error) { - timeout, _ := strconv.Atoi(endpoint) - time.Sleep(time.Second * time.Duration(timeout)) - return kubeconfigutil.CreateBasic(endpoint, "foo", "foo", []byte{}), nil + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + cfg, err := fetchKubeConfigWithTimeout(testAPIEndpoint, test.discoveryTimeout, func(apiEndpoint string) (*clientcmdapi.Config, error) { + if apiEndpoint != testAPIEndpoint { + return nil, fmt.Errorf("unexpected API server endpoint:\n\texpected: %q\n\tgot: %q", testAPIEndpoint, apiEndpoint) + } + + time.Sleep(3 * time.Second) + return &clientcmdapi.Config{}, nil + }) + + if test.shouldFail { + if err == nil { + t.Fatal("unexpected success") + } + } else { + if err != nil { + t.Fatalf("unexpected failure: %v", err) + } + if cfg == nil { + t.Fatal("cfg is nil") + } + } }) - if err != nil { - t.Errorf("unexpected error: %v for endpoint %s", err, rt.expectedEndpoint) - } - endpoint := returnKubeConfig.Clusters[returnKubeConfig.Contexts[returnKubeConfig.CurrentContext].Cluster].Server - if endpoint != rt.expectedEndpoint { - t.Errorf( - "failed TestRunForEndpointsAndReturnFirst:\n\texpected: %s\n\t actual: %s", - endpoint, - rt.expectedEndpoint, - ) - } } } diff --git a/cmd/kubeadm/app/features/features.go b/cmd/kubeadm/app/features/features.go index 7b4ba8577465b..3cc810beb038e 100644 --- a/cmd/kubeadm/app/features/features.go +++ b/cmd/kubeadm/app/features/features.go @@ -74,7 +74,7 @@ type Feature struct { // FeatureList represents a list of feature gates type FeatureList map[string]Feature -// ValidateVersion ensures that a feature gate list is compatible with the chosen kubernetes version +// ValidateVersion ensures that a feature gate list is compatible with the chosen Kubernetes version func ValidateVersion(allFeatures FeatureList, requestedFeatures map[string]bool, requestedVersion string) error { if requestedVersion == "" { return nil @@ -87,7 +87,7 @@ func ValidateVersion(allFeatures FeatureList, requestedFeatures map[string]bool, if minVersion := allFeatures[k].MinimumVersion; minVersion != nil { if !parsedExpVersion.AtLeast(minVersion) { return fmt.Errorf( - "the requested kubernetes version (%s) is incompatible with the %s feature gate, which needs %s as a minimum", + "the requested Kubernetes version (%s) is incompatible with the %s feature gate, which needs %s as a minimum", requestedVersion, k, minVersion) } } diff --git a/cmd/kubeadm/app/phases/addons/dns/BUILD b/cmd/kubeadm/app/phases/addons/dns/BUILD index 13adf8b2e00b7..adfebc4886be2 100644 --- a/cmd/kubeadm/app/phases/addons/dns/BUILD +++ b/cmd/kubeadm/app/phases/addons/dns/BUILD @@ -45,6 +45,7 @@ go_library( "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library", "//vendor/github.com/mholt/caddy/caddyfile:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/addons/dns/dns.go b/cmd/kubeadm/app/phases/addons/dns/dns.go index 4f259600c8ec9..6d238709c2ca7 100644 --- a/cmd/kubeadm/app/phases/addons/dns/dns.go +++ b/cmd/kubeadm/app/phases/addons/dns/dns.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/mholt/caddy/caddyfile" + "github.com/pkg/errors" apps "k8s.io/api/apps/v1" "k8s.io/api/core/v1" @@ -51,7 +52,7 @@ func DeployedDNSAddon(client clientset.Interface) (string, string, error) { deploymentsClient := client.AppsV1().Deployments(metav1.NamespaceSystem) deployments, err := deploymentsClient.List(metav1.ListOptions{LabelSelector: "k8s-app=kube-dns"}) if err != nil { - return "", "", fmt.Errorf("couldn't retrieve DNS addon deployments: %v", err) + return "", "", errors.Wrap(err, "couldn't retrieve DNS addon deployments") } switch len(deployments.Items) { @@ -64,7 +65,7 @@ func DeployedDNSAddon(client clientset.Interface) (string, string, error) { addonVersion := addonImageParts[len(addonImageParts)-1] return addonName, addonVersion, nil default: - return "", "", fmt.Errorf("multiple DNS addon deployments found: %v", deployments.Items) + return "", "", errors.Errorf("multiple DNS addon deployments found: %v", deployments.Items) } } @@ -105,14 +106,14 @@ func kubeDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster, }) if err != nil { - return fmt.Errorf("error when parsing kube-dns deployment template: %v", err) + return errors.Wrap(err, "error when parsing kube-dns deployment template") } dnsServiceBytes, err := kubeadmutil.ParseTemplate(KubeDNSService, struct{ DNSIP string }{ DNSIP: dnsip.String(), }) if err != nil { - return fmt.Errorf("error when parsing kube-proxy configmap template: %v", err) + return errors.Wrap(err, "error when parsing kube-proxy configmap template") } if err := createKubeDNSAddon(dnsDeploymentBytes, dnsServiceBytes, client); err != nil { @@ -136,7 +137,7 @@ func CreateServiceAccount(client clientset.Interface) error { func createKubeDNSAddon(deploymentBytes, serviceBytes []byte, client clientset.Interface) error { kubednsDeployment := &apps.Deployment{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), deploymentBytes, kubednsDeployment); err != nil { - return fmt.Errorf("unable to decode kube-dns deployment %v", err) + return errors.Wrap(err, "unable to decode kube-dns deployment") } // Create the Deployment for kube-dns or update it in case it already exists @@ -156,7 +157,7 @@ func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) Version: kubeadmconstants.CoreDNSVersion, }) if err != nil { - return fmt.Errorf("error when parsing CoreDNS deployment template: %v", err) + return errors.Wrap(err, "error when parsing CoreDNS deployment template") } // Get the kube-dns ConfigMap for translation to equivalent CoreDNS Config. @@ -188,7 +189,7 @@ func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) StubDomain: stubDomain, }) if err != nil { - return fmt.Errorf("error when parsing CoreDNS configMap template: %v", err) + return errors.Wrap(err, "error when parsing CoreDNS configMap template") } dnsip, err := kubeadmconstants.GetDNSIP(cfg.Networking.ServiceSubnet) @@ -201,7 +202,7 @@ func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) }) if err != nil { - return fmt.Errorf("error when parsing CoreDNS service template: %v", err) + return errors.Wrap(err, "error when parsing CoreDNS service template") } if err := createCoreDNSAddon(coreDNSDeploymentBytes, coreDNSServiceBytes, coreDNSConfigMapBytes, client); err != nil { @@ -214,7 +215,7 @@ func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, client clientset.Interface) error { coreDNSConfigMap := &v1.ConfigMap{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), configBytes, coreDNSConfigMap); err != nil { - return fmt.Errorf("unable to decode CoreDNS configmap %v", err) + return errors.Wrap(err, "unable to decode CoreDNS configmap") } // Create the ConfigMap for CoreDNS or retain it in case it already exists @@ -224,7 +225,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien coreDNSClusterRoles := &rbac.ClusterRole{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSClusterRole), coreDNSClusterRoles); err != nil { - return fmt.Errorf("unable to decode CoreDNS clusterroles %v", err) + return errors.Wrap(err, "unable to decode CoreDNS clusterroles") } // Create the Clusterroles for CoreDNS or update it in case it already exists @@ -234,7 +235,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien coreDNSClusterRolesBinding := &rbac.ClusterRoleBinding{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSClusterRoleBinding), coreDNSClusterRolesBinding); err != nil { - return fmt.Errorf("unable to decode CoreDNS clusterrolebindings %v", err) + return errors.Wrap(err, "unable to decode CoreDNS clusterrolebindings") } // Create the Clusterrolebindings for CoreDNS or update it in case it already exists @@ -244,7 +245,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien coreDNSServiceAccount := &v1.ServiceAccount{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSServiceAccount), coreDNSServiceAccount); err != nil { - return fmt.Errorf("unable to decode CoreDNS serviceaccount %v", err) + return errors.Wrap(err, "unable to decode CoreDNS serviceaccount") } // Create the ConfigMap for CoreDNS or update it in case it already exists @@ -254,7 +255,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien coreDNSDeployment := &apps.Deployment{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), deploymentBytes, coreDNSDeployment); err != nil { - return fmt.Errorf("unable to decode CoreDNS deployment %v", err) + return errors.Wrap(err, "unable to decode CoreDNS deployment") } // Create the Deployment for CoreDNS or update it in case it already exists @@ -268,7 +269,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien func createDNSService(dnsService *v1.Service, serviceBytes []byte, client clientset.Interface) error { if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), serviceBytes, dnsService); err != nil { - return fmt.Errorf("unable to decode the DNS service %v", err) + return errors.Wrap(err, "unable to decode the DNS service") } // Can't use a generic apiclient helper func here as we have to tolerate more than AlreadyExists. @@ -277,11 +278,11 @@ func createDNSService(dnsService *v1.Service, serviceBytes []byte, client client // Service "kube-dns" is invalid: spec.clusterIP: Invalid value: "10.96.0.10": provided IP is already allocated if !apierrors.IsAlreadyExists(err) && !apierrors.IsInvalid(err) { - return fmt.Errorf("unable to create a new DNS service: %v", err) + return errors.Wrap(err, "unable to create a new DNS service") } if _, err := client.CoreV1().Services(metav1.NamespaceSystem).Update(dnsService); err != nil { - return fmt.Errorf("unable to create/update the DNS service: %v", err) + return errors.Wrap(err, "unable to create/update the DNS service") } } return nil @@ -298,7 +299,7 @@ func translateStubDomainOfKubeDNSToProxyCoreDNS(dataField string, kubeDNSConfigM stubDomainData := make(map[string][]string) err := json.Unmarshal([]byte(proxy), &stubDomainData) if err != nil { - return "", fmt.Errorf("failed to parse JSON from 'kube-dns ConfigMap: %v", err) + return "", errors.Wrap(err, "failed to parse JSON from 'kube-dns ConfigMap") } var proxyStanza []interface{} @@ -340,7 +341,7 @@ func translateUpstreamNameServerOfKubeDNSToUpstreamProxyCoreDNS(dataField string err := json.Unmarshal([]byte(upstreamValues), &upstreamProxyIP) if err != nil { - return "", fmt.Errorf("failed to parse JSON from 'kube-dns ConfigMap: %v", err) + return "", errors.Wrap(err, "failed to parse JSON from 'kube-dns ConfigMap") } coreDNSProxyStanzaList := strings.Join(upstreamProxyIP, " ") @@ -365,7 +366,7 @@ func translateFederationsofKubeDNSToCoreDNS(dataField, coreDNSDomain string, kub err := json.Unmarshal([]byte(federation), &federationData) if err != nil { - return "", fmt.Errorf("failed to parse JSON from kube-dns ConfigMap: %v", err) + return "", errors.Wrap(err, "failed to parse JSON from kube-dns ConfigMap") } fStanza := map[string]interface{}{} diff --git a/cmd/kubeadm/app/phases/addons/proxy/BUILD b/cmd/kubeadm/app/phases/addons/proxy/BUILD index ea4fc05f916f0..9e7b581f79eff 100644 --- a/cmd/kubeadm/app/phases/addons/proxy/BUILD +++ b/cmd/kubeadm/app/phases/addons/proxy/BUILD @@ -47,6 +47,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/addons/proxy/proxy.go b/cmd/kubeadm/app/phases/addons/proxy/proxy.go index 862a89fa4188e..3d30f0cb0f918 100644 --- a/cmd/kubeadm/app/phases/addons/proxy/proxy.go +++ b/cmd/kubeadm/app/phases/addons/proxy/proxy.go @@ -20,6 +20,8 @@ import ( "bytes" "fmt" + "github.com/pkg/errors" + apps "k8s.io/api/apps/v1" "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" @@ -48,7 +50,7 @@ const ( // EnsureProxyAddon creates the kube-proxy addons func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error { if err := CreateServiceAccount(client); err != nil { - return fmt.Errorf("error when creating kube-proxy service account: %v", err) + return errors.Wrap(err, "error when creating kube-proxy service account") } // Generate Master Enpoint kubeconfig file @@ -59,7 +61,7 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf proxyBytes, err := componentconfigs.Known[componentconfigs.KubeProxyConfigurationKind].Marshal(cfg.ComponentConfigs.KubeProxy) if err != nil { - return fmt.Errorf("error when marshaling: %v", err) + return errors.Wrap(err, "error when marshaling") } var prefixBytes bytes.Buffer apiclient.PrintBytesWithLinePrefix(&prefixBytes, proxyBytes, " ") @@ -77,7 +79,7 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf ProxyConfigMapKey: constants.KubeProxyConfigMapKey, }) if err != nil { - return fmt.Errorf("error when parsing kube-proxy configmap template: %v", err) + return errors.Wrap(err, "error when parsing kube-proxy configmap template") } proxyDaemonSetBytes, err = kubeadmutil.ParseTemplate(KubeProxyDaemonSet19, struct{ Image, ProxyConfigMap, ProxyConfigMapKey string }{ Image: images.GetKubeControlPlaneImage(constants.KubeProxy, &cfg.ClusterConfiguration), @@ -85,13 +87,13 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf ProxyConfigMapKey: constants.KubeProxyConfigMapKey, }) if err != nil { - return fmt.Errorf("error when parsing kube-proxy daemonset template: %v", err) + return errors.Wrap(err, "error when parsing kube-proxy daemonset template") } if err := createKubeProxyAddon(proxyConfigMapBytes, proxyDaemonSetBytes, client); err != nil { return err } if err := CreateRBACRules(client); err != nil { - return fmt.Errorf("error when creating kube-proxy RBAC rules: %v", err) + return errors.Wrap(err, "error when creating kube-proxy RBAC rules") } fmt.Println("[addons] Applied essential addon: kube-proxy") @@ -117,7 +119,7 @@ func CreateRBACRules(client clientset.Interface) error { func createKubeProxyAddon(configMapBytes, daemonSetbytes []byte, client clientset.Interface) error { kubeproxyConfigMap := &v1.ConfigMap{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), configMapBytes, kubeproxyConfigMap); err != nil { - return fmt.Errorf("unable to decode kube-proxy configmap %v", err) + return errors.Wrap(err, "unable to decode kube-proxy configmap") } // Create the ConfigMap for kube-proxy or update it in case it already exists @@ -127,7 +129,7 @@ func createKubeProxyAddon(configMapBytes, daemonSetbytes []byte, client clientse kubeproxyDaemonSet := &apps.DaemonSet{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), daemonSetbytes, kubeproxyDaemonSet); err != nil { - return fmt.Errorf("unable to decode kube-proxy daemonset %v", err) + return errors.Wrap(err, "unable to decode kube-proxy daemonset") } // Create the DaemonSet for kube-proxy or update it in case it already exists diff --git a/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/BUILD b/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/BUILD index 435e32f17fc9b..8bd587953ccfd 100644 --- a/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/BUILD +++ b/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/BUILD @@ -35,6 +35,7 @@ go_library( "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo.go b/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo.go index a43d953885099..5e46d346e2a21 100644 --- a/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo.go +++ b/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo.go @@ -20,6 +20,8 @@ import ( "fmt" "github.com/golang/glog" + "github.com/pkg/errors" + "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -45,7 +47,7 @@ func CreateBootstrapConfigMapIfNotExists(client clientset.Interface, file string glog.V(1).Infoln("[bootstraptoken] loading admin kubeconfig") adminConfig, err := clientcmd.LoadFromFile(file) if err != nil { - return fmt.Errorf("failed to load admin kubeconfig [%v]", err) + return errors.Wrap(err, "failed to load admin kubeconfig") } adminCluster := adminConfig.Contexts[adminConfig.CurrentContext].Cluster diff --git a/cmd/kubeadm/app/phases/bootstraptoken/node/BUILD b/cmd/kubeadm/app/phases/bootstraptoken/node/BUILD index ee6ee2d471de2..6ee4c7c89a799 100644 --- a/cmd/kubeadm/app/phases/bootstraptoken/node/BUILD +++ b/cmd/kubeadm/app/phases/bootstraptoken/node/BUILD @@ -20,6 +20,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/bootstraptoken/node/token.go b/cmd/kubeadm/app/phases/bootstraptoken/node/token.go index 6ec927c54903c..27d4cf3f79bc1 100644 --- a/cmd/kubeadm/app/phases/bootstraptoken/node/token.go +++ b/cmd/kubeadm/app/phases/bootstraptoken/node/token.go @@ -17,7 +17,7 @@ limitations under the License. package node import ( - "fmt" + "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientset "k8s.io/client-go/kubernetes" @@ -41,14 +41,14 @@ func UpdateOrCreateTokens(client clientset.Interface, failIfExists bool, tokens secretName := bootstraputil.BootstrapTokenSecretName(token.Token.ID) secret, err := client.CoreV1().Secrets(metav1.NamespaceSystem).Get(secretName, metav1.GetOptions{}) if secret != nil && err == nil && failIfExists { - return fmt.Errorf("a token with id %q already exists", token.Token.ID) + return errors.Errorf("a token with id %q already exists", token.Token.ID) } updatedOrNewSecret := token.ToSecret() // Try to create or update the token with an exponential backoff err = apiclient.TryRunCommand(func() error { if err := apiclient.CreateOrUpdateSecret(client, updatedOrNewSecret); err != nil { - return fmt.Errorf("failed to create or update bootstrap token with name %s: %v", secretName, err) + return errors.Wrapf(err, "failed to create or update bootstrap token with name %s", secretName) } return nil }, 5) diff --git a/cmd/kubeadm/app/phases/certs/BUILD b/cmd/kubeadm/app/phases/certs/BUILD index 22772aaa459ea..ee39c18a4e6b0 100644 --- a/cmd/kubeadm/app/phases/certs/BUILD +++ b/cmd/kubeadm/app/phases/certs/BUILD @@ -16,10 +16,11 @@ go_test( deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//cmd/kubeadm/test:go_default_library", "//cmd/kubeadm/test/certs:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -34,9 +35,10 @@ go_library( deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -51,7 +53,6 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", - "//cmd/kubeadm/app/phases/certs/pkiutil:all-srcs", "//cmd/kubeadm/app/phases/certs/renewal:all-srcs", ], tags = ["automanaged"], diff --git a/cmd/kubeadm/app/phases/certs/certlist.go b/cmd/kubeadm/app/phases/certs/certlist.go index 54f473c03f12a..24b2342c9d24e 100644 --- a/cmd/kubeadm/app/phases/certs/certlist.go +++ b/cmd/kubeadm/app/phases/certs/certlist.go @@ -19,12 +19,13 @@ package certs import ( "crypto/rsa" "crypto/x509" - "fmt" + + "github.com/pkg/errors" certutil "k8s.io/client-go/util/cert" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" ) type configMutatorsFunc func(*kubeadmapi.InitConfiguration, *certutil.Config) error @@ -56,7 +57,7 @@ func (k *KubeadmCert) GetConfig(ic *kubeadmapi.InitConfiguration) (*certutil.Con func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) error { cfg, err := k.GetConfig(ic) if err != nil { - return fmt.Errorf("couldn't create %q certificate: %v", k.Name, err) + return errors.Wrapf(err, "couldn't create %q certificate", k.Name) } cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, cfg) if err != nil { @@ -71,7 +72,7 @@ func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x50 ) if err != nil { - return fmt.Errorf("failed to write certificate %q: %v", k.Name, err) + return errors.Wrapf(err, "failed to write certificate %q", k.Name) } return nil @@ -81,11 +82,11 @@ func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x50 func (k *KubeadmCert) CreateAsCA(ic *kubeadmapi.InitConfiguration) (*x509.Certificate, *rsa.PrivateKey, error) { cfg, err := k.GetConfig(ic) if err != nil { - return nil, nil, fmt.Errorf("couldn't get configuration for %q CA certificate: %v", k.Name, err) + return nil, nil, errors.Wrapf(err, "couldn't get configuration for %q CA certificate", k.Name) } caCert, caKey, err := NewCACertAndKey(cfg) if err != nil { - return nil, nil, fmt.Errorf("couldn't generate %q CA certificate: %v", k.Name, err) + return nil, nil, errors.Wrapf(err, "couldn't generate %q CA certificate", k.Name) } err = writeCertificateAuthorithyFilesIfNotExist( @@ -95,7 +96,7 @@ func (k *KubeadmCert) CreateAsCA(ic *kubeadmapi.InitConfiguration) (*x509.Certif caKey, ) if err != nil { - return nil, nil, fmt.Errorf("couldn't write out %q CA certificate: %v", k.Name, err) + return nil, nil, errors.Wrapf(err, "couldn't write out %q CA certificate", k.Name) } return caCert, caKey, nil @@ -118,7 +119,7 @@ func (t CertificateTree) CreateTree(ic *kubeadmapi.InitConfiguration) error { if err == nil { // Cert exists already, make sure it's valid if !caCert.IsCA { - return fmt.Errorf("certificate %q is not a CA", ca.Name) + return errors.Errorf("certificate %q is not a CA", ca.Name) } // Try and load a CA Key caKey, err = pkiutil.TryLoadKeyFromDisk(ic.CertificatesDir, ca.BaseName) @@ -131,10 +132,9 @@ func (t CertificateTree) CreateTree(ic *kubeadmapi.InitConfiguration) error { uxName: leaf.Name, } if err := validateSignedCertWithCA(cl, caCert); err != nil { - return fmt.Errorf("could not load expected certificate %q or validate the existence of key %q for it: %v", leaf.Name, ca.Name, err) + return errors.Wrapf(err, "could not load expected certificate %q or validate the existence of key %q for it", leaf.Name, ca.Name) } } - // CACert exists and all clients exist, continue to next CA. continue } // CA key exists; just use that to create new certificates. @@ -180,7 +180,7 @@ func (m CertificateMap) CertTree() (CertificateTree, error) { } else { ca, ok := m[cert.CAName] if !ok { - return nil, fmt.Errorf("Certificate %q references unknown CA %q", cert.Name, cert.CAName) + return nil, errors.Errorf("certificate %q references unknown CA %q", cert.Name, cert.CAName) } caMap[ca] = append(caMap[ca], cert) } @@ -236,16 +236,16 @@ var ( // KubeadmCertRootCA is the definition of the Kubernetes Root CA for the API Server and kubelet. KubeadmCertRootCA = KubeadmCert{ Name: "ca", - LongName: "self-signed kubernetes CA to provision identities for other kuberenets components", + LongName: "self-signed Kubernetes CA to provision identities for other Kubernetes components", BaseName: kubeadmconstants.CACertAndKeyBaseName, config: certutil.Config{ CommonName: "kubernetes", }, } - // KubeadmCertAPIServer is the definition of the cert used to serve the kubernetes API. + // KubeadmCertAPIServer is the definition of the cert used to serve the Kubernetes API. KubeadmCertAPIServer = KubeadmCert{ Name: "apiserver", - LongName: "certificate for serving the kubernetes API", + LongName: "certificate for serving the Kubernetes API", BaseName: kubeadmconstants.APIServerCertAndKeyBaseName, CAName: "ca", config: certutil.Config{ diff --git a/cmd/kubeadm/app/phases/certs/certs.go b/cmd/kubeadm/app/phases/certs/certs.go index 4f71ca271c45a..b25fea917eada 100644 --- a/cmd/kubeadm/app/phases/certs/certs.go +++ b/cmd/kubeadm/app/phases/certs/certs.go @@ -24,11 +24,11 @@ import ( "path/filepath" "github.com/golang/glog" - + "github.com/pkg/errors" certutil "k8s.io/client-go/util/cert" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" ) // CreatePKIAssets will create and write to disk all PKI assets necessary to establish the control plane. @@ -53,10 +53,10 @@ func CreatePKIAssets(cfg *kubeadmapi.InitConfiguration) error { } if err := certTree.CreateTree(cfg); err != nil { - return fmt.Errorf("Error creating PKI assets: %v", err) + return errors.Wrap(err, "error creating PKI assets") } - fmt.Printf("[certificates] valid certificates and keys now exist in %q\n", cfg.CertificatesDir) + fmt.Printf("[certs] valid certificates and keys now exist in %q\n", cfg.CertificatesDir) // Service accounts are not x509 certs, so handled separately if err := CreateServiceAccountKeyAndPublicKeyFiles(cfg); err != nil { @@ -87,7 +87,7 @@ func NewServiceAccountSigningKey() (*rsa.PrivateKey, error) { // The key does NOT exist, let's generate it now saSigningKey, err := certutil.NewPrivateKey() if err != nil { - return nil, fmt.Errorf("failure while creating service account token signing key: %v", err) + return nil, errors.Wrap(err, "failure while creating service account token signing key") } return saSigningKey, nil @@ -98,7 +98,7 @@ func NewCACertAndKey(certSpec *certutil.Config) (*x509.Certificate, *rsa.Private caCert, caKey, err := pkiutil.NewCertificateAuthority(certSpec) if err != nil { - return nil, nil, fmt.Errorf("failure while generating CA certificate and key: %v", err) + return nil, nil, errors.Wrap(err, "failure while generating CA certificate and key") } return caCert, caKey, nil @@ -108,7 +108,7 @@ func NewCACertAndKey(certSpec *certutil.Config) (*x509.Certificate, *rsa.Private // The certSpec should be one of the variables from this package. func CreateCACertAndKeyFiles(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration) error { if certSpec.CAName != "" { - return fmt.Errorf("This function should only be used for CAs, but cert %s has CA %s", certSpec.Name, certSpec.CAName) + return errors.Errorf("this function should only be used for CAs, but cert %s has CA %s", certSpec.Name, certSpec.CAName) } glog.V(1).Infof("creating a new certificate authority for %s", certSpec.Name) @@ -134,12 +134,12 @@ func CreateCACertAndKeyFiles(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfigur // The certSpec and caCertSpec should both be one of the variables from this package. func CreateCertAndKeyFilesWithCA(certSpec *KubeadmCert, caCertSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration) error { if certSpec.CAName != caCertSpec.Name { - return fmt.Errorf("Expected CAname for %s to be %q, but was %s", certSpec.Name, certSpec.CAName, caCertSpec.Name) + return errors.Errorf("expected CAname for %s to be %q, but was %s", certSpec.Name, certSpec.CAName, caCertSpec.Name) } caCert, caKey, err := LoadCertificateAuthority(cfg.CertificatesDir, caCertSpec.BaseName) if err != nil { - return fmt.Errorf("Couldn't load CA certificate %s: %v", caCertSpec.Name, err) + return errors.Wrapf(err, "couldn't load CA certificate %s", caCertSpec.Name) } return certSpec.CreateFromCA(cfg, caCert, caKey) @@ -149,18 +149,18 @@ func CreateCertAndKeyFilesWithCA(certSpec *KubeadmCert, caCertSpec *KubeadmCert, func LoadCertificateAuthority(pkiDir string, baseName string) (*x509.Certificate, *rsa.PrivateKey, error) { // Checks if certificate authority exists in the PKI directory if !pkiutil.CertOrKeyExist(pkiDir, baseName) { - return nil, nil, fmt.Errorf("couldn't load %s certificate authority from %s", baseName, pkiDir) + return nil, nil, errors.Errorf("couldn't load %s certificate authority from %s", baseName, pkiDir) } // Try to load certificate authority .crt and .key from the PKI directory caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName) if err != nil { - return nil, nil, fmt.Errorf("failure loading %s certificate authority: %v", baseName, err) + return nil, nil, errors.Wrapf(err, "failure loading %s certificate authority", baseName) } // Make sure the loaded CA cert actually is a CA if !caCert.IsCA { - return nil, nil, fmt.Errorf("%s certificate is not a certificate authority", baseName) + return nil, nil, errors.Errorf("%s certificate is not a certificate authority", baseName) } return caCert, caKey, nil @@ -178,26 +178,25 @@ func writeCertificateAuthorithyFilesIfNotExist(pkiDir string, baseName string, c // Try to load .crt and .key from the PKI directory caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName) if err != nil { - return fmt.Errorf("failure loading %s certificate: %v", baseName, err) + return errors.Wrapf(err, "failure loading %s certificate", baseName) } // Check if the existing cert is a CA if !caCert.IsCA { - return fmt.Errorf("certificate %s is not a CA", baseName) + return errors.Errorf("certificate %s is not a CA", baseName) } // kubeadm doesn't validate the existing certificate Authority more than this; // Basically, if we find a certificate file with the same path; and it is a CA // kubeadm thinks those files are equal and doesn't bother writing a new file - fmt.Printf("[certificates] Using the existing %s certificate and key.\n", baseName) + fmt.Printf("[certs] Using the existing %q certificate and key\n", baseName) } else { - // Write .crt and .key files to disk + fmt.Printf("[certs] Generating %q certificate and key\n", baseName) + if err := pkiutil.WriteCertAndKey(pkiDir, baseName, caCert, caKey); err != nil { - return fmt.Errorf("failure while saving %s certificate and key: %v", baseName, err) + return errors.Wrapf(err, "failure while saving %s certificate and key", baseName) } - - fmt.Printf("[certificates] Generated %s certificate and key.\n", baseName) } return nil } @@ -213,29 +212,28 @@ func writeCertificateFilesIfNotExist(pkiDir string, baseName string, signingCert // Try to load signed certificate .crt and .key from the PKI directory signedCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName) if err != nil { - return fmt.Errorf("failure loading %s certificate: %v", baseName, err) + return errors.Wrapf(err, "failure loading %s certificate", baseName) } // Check if the existing cert is signed by the given CA if err := signedCert.CheckSignatureFrom(signingCert); err != nil { - return fmt.Errorf("certificate %s is not signed by corresponding CA", baseName) + return errors.Errorf("certificate %s is not signed by corresponding CA", baseName) } // kubeadm doesn't validate the existing certificate more than this; // Basically, if we find a certificate file with the same path; and it is signed by // the expected certificate authority, kubeadm thinks those files are equal and // doesn't bother writing a new file - fmt.Printf("[certificates] Using the existing %s certificate and key.\n", baseName) + fmt.Printf("[certs] Using the existing %q certificate and key\n", baseName) } else { - // Write .crt and .key files to disk + fmt.Printf("[certs] Generating %q certificate and key\n", baseName) + if err := pkiutil.WriteCertAndKey(pkiDir, baseName, cert, key); err != nil { - return fmt.Errorf("failure while saving %s certificate and key: %v", baseName, err) + return errors.Wrapf(err, "failure while saving %s certificate and key", baseName) } - - fmt.Printf("[certificates] Generated %s certificate and key.\n", baseName) if pkiutil.HasServerAuth(cert) { - fmt.Printf("[certificates] %s serving cert is signed for DNS names %v and IPs %v\n", baseName, cert.DNSNames, cert.IPAddresses) + fmt.Printf("[certs] %s serving cert is signed for DNS names %v and IPs %v\n", baseName, cert.DNSNames, cert.IPAddresses) } } @@ -254,24 +252,25 @@ func writeKeyFilesIfNotExist(pkiDir string, baseName string, key *rsa.PrivateKey // Try to load .key from the PKI directory _, err := pkiutil.TryLoadKeyFromDisk(pkiDir, baseName) if err != nil { - return fmt.Errorf("%s key existed but it could not be loaded properly: %v", baseName, err) + return errors.Wrapf(err, "%s key existed but it could not be loaded properly", baseName) } // kubeadm doesn't validate the existing certificate key more than this; // Basically, if we find a key file with the same path kubeadm thinks those files // are equal and doesn't bother writing a new file - fmt.Printf("[certificates] Using the existing %s key.\n", baseName) + fmt.Printf("[certs] Using the existing %q key\n", baseName) } else { // Write .key and .pub files to disk + fmt.Printf("[certs] Generating %q key and public key\n", baseName) + if err := pkiutil.WriteKey(pkiDir, baseName, key); err != nil { - return fmt.Errorf("failure while saving %s key: %v", baseName, err) + return errors.Wrapf(err, "failure while saving %s key", baseName) } if err := pkiutil.WritePublicKey(pkiDir, baseName, &key.PublicKey); err != nil { - return fmt.Errorf("failure while saving %s public key: %v", baseName, err) + return errors.Wrapf(err, "failure while saving %s public key", baseName) } - fmt.Printf("[certificates] Generated %s key and public key.\n", baseName) } return nil @@ -285,7 +284,7 @@ type certKeyLocation struct { } // SharedCertificateExists verifies if the shared certificates - the certificates that must be -// equal across masters: ca.key, ca.crt, sa.key, sa.pub +// equal across masters: ca.key, ca.crt, sa.key, sa.pub + etcd/ca.key, etcd/ca.crt if local/stacked etcd func SharedCertificateExists(cfg *kubeadmapi.InitConfiguration) (bool, error) { if err := validateCACertAndKey(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName, "", "CA"}); err != nil { @@ -300,6 +299,13 @@ func SharedCertificateExists(cfg *kubeadmapi.InitConfiguration) (bool, error) { return false, err } + // in case of local/stacked etcd + if cfg.Etcd.External == nil { + if err := validateCACertAndKey(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.EtcdCACertAndKeyBaseName, "", "etcd CA"}); err != nil { + return false, err + } + } + return true, nil } @@ -314,7 +320,7 @@ func UsingExternalCA(cfg *kubeadmapi.InitConfiguration) (bool, error) { caKeyPath := filepath.Join(cfg.CertificatesDir, kubeadmconstants.CAKeyName) if _, err := os.Stat(caKeyPath); !os.IsNotExist(err) { - return false, fmt.Errorf("%s exists", kubeadmconstants.CAKeyName) + return false, errors.Errorf("%s exists", kubeadmconstants.CAKeyName) } if err := validateSignedCert(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName, kubeadmconstants.APIServerCertAndKeyBaseName, "API server"}); err != nil { @@ -335,7 +341,7 @@ func UsingExternalCA(cfg *kubeadmapi.InitConfiguration) (bool, error) { frontProxyCAKeyPath := filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCAKeyName) if _, err := os.Stat(frontProxyCAKeyPath); !os.IsNotExist(err) { - return false, fmt.Errorf("%s exists", kubeadmconstants.FrontProxyCAKeyName) + return false, errors.Errorf("%s exists", kubeadmconstants.FrontProxyCAKeyName) } if err := validateSignedCert(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.FrontProxyCACertAndKeyBaseName, kubeadmconstants.FrontProxyClientCertAndKeyBaseName, "front-proxy client"}); err != nil { @@ -350,12 +356,12 @@ func validateCACert(l certKeyLocation) error { // Check CA Cert caCert, err := pkiutil.TryLoadCertFromDisk(l.pkiDir, l.caBaseName) if err != nil { - return fmt.Errorf("failure loading certificate for %s: %v", l.uxName, err) + return errors.Wrapf(err, "failure loading certificate for %s", l.uxName) } // Check if cert is a CA if !caCert.IsCA { - return fmt.Errorf("certificate %s is not a CA", l.uxName) + return errors.Errorf("certificate %s is not a CA", l.uxName) } return nil } @@ -369,7 +375,7 @@ func validateCACertAndKey(l certKeyLocation) error { _, err := pkiutil.TryLoadKeyFromDisk(l.pkiDir, l.caBaseName) if err != nil { - return fmt.Errorf("failure loading key for %s: %v", l.uxName, err) + return errors.Wrapf(err, "failure loading key for %s", l.uxName) } return nil } @@ -380,7 +386,7 @@ func validateSignedCert(l certKeyLocation) error { // Try to load CA caCert, err := pkiutil.TryLoadCertFromDisk(l.pkiDir, l.caBaseName) if err != nil { - return fmt.Errorf("failure loading certificate authority for %s: %v", l.uxName, err) + return errors.Wrapf(err, "failure loading certificate authority for %s", l.uxName) } return validateSignedCertWithCA(l, caCert) @@ -391,12 +397,12 @@ func validateSignedCertWithCA(l certKeyLocation, caCert *x509.Certificate) error // Try to load key and signed certificate signedCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(l.pkiDir, l.baseName) if err != nil { - return fmt.Errorf("failure loading certificate for %s: %v", l.uxName, err) + return errors.Wrapf(err, "failure loading certificate for %s", l.uxName) } // Check if the cert is signed by the CA if err := signedCert.CheckSignatureFrom(caCert); err != nil { - return fmt.Errorf("certificate %s is not signed by corresponding CA", l.uxName) + return errors.Wrapf(err, "certificate %s is not signed by corresponding CA", l.uxName) } return nil } @@ -406,7 +412,7 @@ func validatePrivatePublicKey(l certKeyLocation) error { // Try to load key _, _, err := pkiutil.TryLoadPrivatePublicKeyFromDisk(l.pkiDir, l.baseName) if err != nil { - return fmt.Errorf("failure loading key for %s: %v", l.uxName, err) + return errors.Wrapf(err, "failure loading key for %s", l.uxName) } return nil } diff --git a/cmd/kubeadm/app/phases/certs/certs_test.go b/cmd/kubeadm/app/phases/certs/certs_test.go index cd936b01a1135..5412303202b77 100644 --- a/cmd/kubeadm/app/phases/certs/certs_test.go +++ b/cmd/kubeadm/app/phases/certs/certs_test.go @@ -19,16 +19,17 @@ package certs import ( "crypto/rsa" "crypto/x509" - "fmt" "os" "path" "path/filepath" "testing" + "github.com/pkg/errors" + certutil "k8s.io/client-go/util/cert" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" testutil "k8s.io/kubernetes/cmd/kubeadm/test" certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs" ) @@ -308,6 +309,8 @@ func TestSharedCertificateExists(t *testing.T) { "front-proxy-ca.key": caKey, "sa.pub": publicKey, "sa.key": key, + "etcd/ca.crt": caCert, + "etcd/ca.key": caKey, }, }, { @@ -318,6 +321,8 @@ func TestSharedCertificateExists(t *testing.T) { "front-proxy-ca.key": caKey, "sa.pub": publicKey, "sa.key": key, + "etcd/ca.crt": caCert, + "etcd/ca.key": caKey, }, expectedError: true, }, @@ -329,17 +334,34 @@ func TestSharedCertificateExists(t *testing.T) { "front-proxy-ca.crt": caCert, "front-proxy-ca.key": caKey, "sa.pub": publicKey, + "etcd/ca.crt": caCert, + "etcd/ca.key": caKey, + }, + expectedError: true, + }, + { + name: "missing front-proxy.crt", + files: pkiFiles{ + "ca.crt": caCert, + "ca.key": caKey, + "front-proxy-ca.key": caKey, + "sa.pub": publicKey, + "sa.key": key, + "etcd/ca.crt": caCert, + "etcd/ca.key": caKey, }, expectedError: true, }, { - name: "expected front-proxy.crt missing", + name: "missing etcd/ca.crt", files: pkiFiles{ "ca.crt": caCert, "ca.key": caKey, "front-proxy-ca.key": caKey, "sa.pub": publicKey, "sa.key": key, + "etcd/ca.crt": caCert, + "etcd/ca.key": caKey, }, expectedError: true, }, @@ -348,6 +370,7 @@ func TestSharedCertificateExists(t *testing.T) { for _, test := range tests { t.Run("", func(t *testing.T) { tmpdir := testutil.SetupTempDir(t) + os.MkdirAll(tmpdir+"/etcd", os.ModePerm) defer os.RemoveAll(tmpdir) cfg := &kubeadmapi.InitConfiguration{ @@ -682,14 +705,14 @@ func TestCreateCertificateFilesMethods(t *testing.T) { func deleteCAKey(cfg *kubeadmapi.InitConfiguration) error { if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.CAKeyName)); err != nil { - return fmt.Errorf("failed removing %s: %v", kubeadmconstants.CAKeyName, err) + return errors.Wrapf(err, "failed removing %s", kubeadmconstants.CAKeyName) } return nil } func deleteFrontProxyCAKey(cfg *kubeadmapi.InitConfiguration) error { if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCAKeyName)); err != nil { - return fmt.Errorf("failed removing %s: %v", kubeadmconstants.FrontProxyCAKeyName, err) + return errors.Wrapf(err, "failed removing %s", kubeadmconstants.FrontProxyCAKeyName) } return nil } diff --git a/cmd/kubeadm/app/phases/certs/doc.go b/cmd/kubeadm/app/phases/certs/doc.go index eea475c910c0c..1ab96d110b7ee 100644 --- a/cmd/kubeadm/app/phases/certs/doc.go +++ b/cmd/kubeadm/app/phases/certs/doc.go @@ -23,11 +23,11 @@ package certs INPUTS: From InitConfiguration .API.AdvertiseAddress is an optional parameter that can be passed for an extra addition to the SAN IPs - .APIServerCertSANs is an optional parameter for adding DNS names and IPs to the API Server serving cert SAN + .APIServer.CertSANs is an optional parameter for adding DNS names and IPs to the API Server serving cert SAN .Etcd.Local.ServerCertSANs is an optional parameter for adding DNS names and IPs to the etcd serving cert SAN .Etcd.Local.PeerCertSANs is an optional parameter for adding DNS names and IPs to the etcd peer cert SAN - .Networking.DNSDomain is needed for knowing which DNS name the internal kubernetes service has - .Networking.ServiceSubnet is needed for knowing which IP the internal kubernetes service is going to point to + .Networking.DNSDomain is needed for knowing which DNS name the internal Kubernetes service has + .Networking.ServiceSubnet is needed for knowing which IP the internal Kubernetes service is going to point to .CertificatesDir is required for knowing where all certificates should be stored OUTPUTS: diff --git a/cmd/kubeadm/app/phases/certs/renewal/BUILD b/cmd/kubeadm/app/phases/certs/renewal/BUILD index dfba2b89c4bd1..623ad5aa52ea2 100644 --- a/cmd/kubeadm/app/phases/certs/renewal/BUILD +++ b/cmd/kubeadm/app/phases/certs/renewal/BUILD @@ -11,7 +11,7 @@ go_library( importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/renewal", visibility = ["//visibility:public"], deps = [ - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library", @@ -32,7 +32,7 @@ go_test( embed = [":go_default_library"], deps = [ "//cmd/kubeadm/app/phases/certs:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//cmd/kubeadm/test:go_default_library", "//cmd/kubeadm/test/certs:go_default_library", "//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", diff --git a/cmd/kubeadm/app/phases/certs/renewal/certsapi.go b/cmd/kubeadm/app/phases/certs/renewal/certsapi.go index 1d5e45516e20b..949e17f31758c 100644 --- a/cmd/kubeadm/app/phases/certs/renewal/certsapi.go +++ b/cmd/kubeadm/app/phases/certs/renewal/certsapi.go @@ -21,7 +21,6 @@ import ( "crypto/rsa" "crypto/x509" "crypto/x509/pkix" - "fmt" "time" "github.com/pkg/errors" @@ -80,7 +79,7 @@ func (r *CertsAPIRenewal) Renew(cfg *certutil.Config) (*x509.Certificate, *rsa.P for i, usage := range cfg.Usages { certsAPIUsage, ok := usageMap[usage] if !ok { - return nil, nil, fmt.Errorf("unknown key usage: %v", usage) + return nil, nil, errors.Errorf("unknown key usage: %v", usage) } usages[i] = certsAPIUsage } @@ -112,7 +111,7 @@ func (r *CertsAPIRenewal) Renew(cfg *certutil.Config) (*x509.Certificate, *rsa.P select { case ev := <-watcher.ResultChan(): if ev.Type != watch.Modified { - return nil, nil, fmt.Errorf("unexpected event received: %q", ev.Type) + return nil, nil, errors.Errorf("unexpected event received: %q", ev.Type) } case <-time.After(watchTimeout): return nil, nil, errors.New("timeout trying to sign certificate") @@ -128,7 +127,7 @@ func (r *CertsAPIRenewal) Renew(cfg *certutil.Config) (*x509.Certificate, *rsa.P // TODO: under what circumstances are there more than one? if status := req.Status.Conditions[0].Type; status != certsapi.CertificateApproved { - return nil, nil, fmt.Errorf("unexpected certificate status: %v", status) + return nil, nil, errors.Errorf("unexpected certificate status: %v", status) } cert, err := x509.ParseCertificate(req.Status.Certificate) diff --git a/cmd/kubeadm/app/phases/certs/renewal/filerenewal.go b/cmd/kubeadm/app/phases/certs/renewal/filerenewal.go index 71090d5cf7def..df7c5f7f22383 100644 --- a/cmd/kubeadm/app/phases/certs/renewal/filerenewal.go +++ b/cmd/kubeadm/app/phases/certs/renewal/filerenewal.go @@ -21,7 +21,7 @@ import ( "crypto/x509" certutil "k8s.io/client-go/util/cert" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" ) // FileRenewal renews a certificate using local certs diff --git a/cmd/kubeadm/app/phases/certs/renewal/renewal.go b/cmd/kubeadm/app/phases/certs/renewal/renewal.go index e6eb7e2a434c6..7c8950c7e3cb5 100644 --- a/cmd/kubeadm/app/phases/certs/renewal/renewal.go +++ b/cmd/kubeadm/app/phases/certs/renewal/renewal.go @@ -18,11 +18,10 @@ package renewal import ( "crypto/x509" - "fmt" "github.com/pkg/errors" certutil "k8s.io/client-go/util/cert" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" ) // RenewExistingCert loads a certificate file, uses the renew interface to renew it, @@ -31,11 +30,11 @@ func RenewExistingCert(certsDir, baseName string, impl Interface) error { certificatePath, _ := pkiutil.PathsForCertAndKey(certsDir, baseName) certs, err := certutil.CertsFromFile(certificatePath) if err != nil { - return fmt.Errorf("failed to load existing certificate %s: %v", baseName, err) + return errors.Wrapf(err, "failed to load existing certificate %s", baseName) } if len(certs) != 1 { - return fmt.Errorf("wanted exactly one certificate, got %d", len(certs)) + return errors.Errorf("wanted exactly one certificate, got %d", len(certs)) } cfg := certToConfig(certs[0]) diff --git a/cmd/kubeadm/app/phases/certs/renewal/renewal_test.go b/cmd/kubeadm/app/phases/certs/renewal/renewal_test.go index bb31d10287c69..327542a4ab9bb 100644 --- a/cmd/kubeadm/app/phases/certs/renewal/renewal_test.go +++ b/cmd/kubeadm/app/phases/certs/renewal/renewal_test.go @@ -33,7 +33,7 @@ import ( k8stesting "k8s.io/client-go/testing" certutil "k8s.io/client-go/util/cert" "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" testutil "k8s.io/kubernetes/cmd/kubeadm/test" certtestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs" ) diff --git a/cmd/kubeadm/app/phases/controlplane/BUILD b/cmd/kubeadm/app/phases/controlplane/BUILD index 62487892691e9..faa2809ce902d 100644 --- a/cmd/kubeadm/app/phases/controlplane/BUILD +++ b/cmd/kubeadm/app/phases/controlplane/BUILD @@ -48,6 +48,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/controlplane/manifests.go b/cmd/kubeadm/app/phases/controlplane/manifests.go index d47a32b4e67f1..8376fdcc5adbd 100644 --- a/cmd/kubeadm/app/phases/controlplane/manifests.go +++ b/cmd/kubeadm/app/phases/controlplane/manifests.go @@ -25,6 +25,7 @@ import ( "strings" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/version" @@ -41,26 +42,8 @@ import ( // CreateInitStaticPodManifestFiles will write all static pod manifest files needed to bring up the control plane. func CreateInitStaticPodManifestFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration) error { - glog.V(1).Infoln("[controlplane] creating static pod files") - return createStaticPodFiles(manifestDir, cfg, kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeControllerManager, kubeadmconstants.KubeScheduler) -} - -// CreateAPIServerStaticPodManifestFile will write APIserver static pod manifest file. -func CreateAPIServerStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.InitConfiguration) error { - glog.V(1).Infoln("creating APIserver static pod files") - return createStaticPodFiles(manifestDir, cfg, kubeadmconstants.KubeAPIServer) -} - -// CreateControllerManagerStaticPodManifestFile will write controller manager static pod manifest file. -func CreateControllerManagerStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.InitConfiguration) error { - glog.V(1).Infoln("creating controller manager static pod files") - return createStaticPodFiles(manifestDir, cfg, kubeadmconstants.KubeControllerManager) -} - -// CreateSchedulerStaticPodManifestFile will write scheduler static pod manifest file. -func CreateSchedulerStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.InitConfiguration) error { - glog.V(1).Infoln("creating scheduler static pod files") - return createStaticPodFiles(manifestDir, cfg, kubeadmconstants.KubeScheduler) + glog.V(1).Infoln("[control-plane] creating static Pod files") + return CreateStaticPodFiles(manifestDir, cfg, kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeControllerManager, kubeadmconstants.KubeScheduler) } // GetStaticPodSpecs returns all staticPodSpecs actualized to the context of the current InitConfiguration @@ -105,8 +88,8 @@ func GetStaticPodSpecs(cfg *kubeadmapi.InitConfiguration, k8sVersion *version.Ve return staticPodSpecs } -// createStaticPodFiles creates all the requested static pod files. -func createStaticPodFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration, componentNames ...string) error { +// CreateStaticPodFiles creates all the requested static pod files. +func CreateStaticPodFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration, componentNames ...string) error { // TODO: Move the "pkg/util/version".Version object into the internal API instead of always parsing the string k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion) if err != nil { @@ -114,7 +97,7 @@ func createStaticPodFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration, } // gets the StaticPodSpecs, actualized for the current InitConfiguration - glog.V(1).Infoln("[controlplane] getting StaticPodSpecs") + glog.V(1).Infoln("[control-plane] getting StaticPodSpecs") specs := GetStaticPodSpecs(cfg, k8sVersion) // creates required static pod specs @@ -122,15 +105,15 @@ func createStaticPodFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration, // retrives the StaticPodSpec for given component spec, exists := specs[componentName] if !exists { - return fmt.Errorf("couldn't retrive StaticPodSpec for %s", componentName) + return errors.Errorf("couldn't retrive StaticPodSpec for %q", componentName) } // writes the StaticPodSpec to disk if err := staticpodutil.WriteStaticPodToDisk(componentName, manifestDir, spec); err != nil { - return fmt.Errorf("failed to create static pod manifest file for %q: %v", componentName, err) + return errors.Wrapf(err, "failed to create static pod manifest file for %q", componentName) } - fmt.Printf("[controlplane] wrote Static Pod manifest for component %s to %q\n", componentName, kubeadmconstants.GetStaticPodFilepath(componentName, manifestDir)) + glog.V(1).Infof("[control-plane] wrote static Pod manifest for component %q to %q\n", componentName, kubeadmconstants.GetStaticPodFilepath(componentName, manifestDir)) } return nil @@ -210,11 +193,11 @@ func getAPIServerCommand(cfg *kubeadmapi.InitConfiguration) []string { defaultArguments["audit-log-maxage"] = fmt.Sprintf("%d", *cfg.AuditPolicyConfiguration.LogMaxAge) } } - if cfg.APIServerExtraArgs == nil { - cfg.APIServerExtraArgs = map[string]string{} + if cfg.APIServer.ExtraArgs == nil { + cfg.APIServer.ExtraArgs = map[string]string{} } - cfg.APIServerExtraArgs["authorization-mode"] = getAuthzModes(cfg.APIServerExtraArgs["authorization-mode"]) - command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.APIServerExtraArgs)...) + cfg.APIServer.ExtraArgs["authorization-mode"] = getAuthzModes(cfg.APIServer.ExtraArgs["authorization-mode"]) + command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.APIServer.ExtraArgs)...) return command } @@ -319,7 +302,7 @@ func getControllerManagerCommand(cfg *kubeadmapi.InitConfiguration, k8sVersion * } command := []string{"kube-controller-manager"} - command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.ControllerManagerExtraArgs)...) + command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.ControllerManager.ExtraArgs)...) return command } @@ -333,7 +316,7 @@ func getSchedulerCommand(cfg *kubeadmapi.InitConfiguration) []string { } command := []string{"kube-scheduler"} - command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.SchedulerExtraArgs)...) + command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.Scheduler.ExtraArgs)...) return command } diff --git a/cmd/kubeadm/app/phases/controlplane/manifests_test.go b/cmd/kubeadm/app/phases/controlplane/manifests_test.go index 103af4c1fcace..df4044a162873 100644 --- a/cmd/kubeadm/app/phases/controlplane/manifests_test.go +++ b/cmd/kubeadm/app/phases/controlplane/manifests_test.go @@ -91,24 +91,19 @@ func TestGetStaticPodSpecs(t *testing.T) { func TestCreateStaticPodFilesAndWrappers(t *testing.T) { var tests = []struct { - createStaticPodFunction func(outDir string, cfg *kubeadmapi.InitConfiguration) error - expectedFiles []string + components []string }{ - { // CreateInitStaticPodManifestFiles - createStaticPodFunction: CreateInitStaticPodManifestFiles, - expectedFiles: []string{kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeControllerManager, kubeadmconstants.KubeScheduler}, + { + components: []string{kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeControllerManager, kubeadmconstants.KubeScheduler}, }, - { // CreateAPIServerStaticPodManifestFile - createStaticPodFunction: CreateAPIServerStaticPodManifestFile, - expectedFiles: []string{kubeadmconstants.KubeAPIServer}, + { + components: []string{kubeadmconstants.KubeAPIServer}, }, - { // CreateControllerManagerStaticPodManifestFile - createStaticPodFunction: CreateControllerManagerStaticPodManifestFile, - expectedFiles: []string{kubeadmconstants.KubeControllerManager}, + { + components: []string{kubeadmconstants.KubeControllerManager}, }, - { // CreateSchedulerStaticPodManifestFile - createStaticPodFunction: CreateSchedulerStaticPodManifestFile, - expectedFiles: []string{kubeadmconstants.KubeScheduler}, + { + components: []string{kubeadmconstants.KubeScheduler}, }, } @@ -127,16 +122,16 @@ func TestCreateStaticPodFilesAndWrappers(t *testing.T) { // Execute createStaticPodFunction manifestPath := filepath.Join(tmpdir, kubeadmconstants.ManifestsSubDirName) - err := test.createStaticPodFunction(manifestPath, cfg) + err := CreateStaticPodFiles(manifestPath, cfg, test.components...) if err != nil { t.Errorf("Error executing createStaticPodFunction: %v", err) continue } // Assert expected files are there - testutil.AssertFilesCount(t, manifestPath, len(test.expectedFiles)) + testutil.AssertFilesCount(t, manifestPath, len(test.components)) - for _, fileName := range test.expectedFiles { + for _, fileName := range test.components { testutil.AssertFileExists(t, manifestPath, fileName+".yaml") } } @@ -449,18 +444,22 @@ func TestGetAPIServerCommand(t *testing.T) { }, }, { - name: "test APIServerExtraArgs works as expected", + name: "test APIServer.ExtraArgs works as expected", cfg: &kubeadmapi.InitConfiguration{ APIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"}, ClusterConfiguration: kubeadmapi.ClusterConfiguration{ Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, FeatureGates: map[string]bool{features.DynamicKubeletConfig: true, features.Auditing: true}, - APIServerExtraArgs: map[string]string{ - "service-cluster-ip-range": "baz", - "advertise-address": "9.9.9.9", - "audit-policy-file": "/etc/config/audit.yaml", - "audit-log-path": "/var/log/kubernetes", + APIServer: kubeadmapi.APIServer{ + ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{ + "service-cluster-ip-range": "baz", + "advertise-address": "9.9.9.9", + "audit-policy-file": "/etc/config/audit.yaml", + "audit-log-path": "/var/log/kubernetes", + }, + }, }, }, }, @@ -505,8 +504,12 @@ func TestGetAPIServerCommand(t *testing.T) { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, - APIServerExtraArgs: map[string]string{ - "authorization-mode": authzmodes.ModeABAC, + APIServer: kubeadmapi.APIServer{ + ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{ + "authorization-mode": authzmodes.ModeABAC, + }, + }, }, }, }, @@ -547,8 +550,12 @@ func TestGetAPIServerCommand(t *testing.T) { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, - APIServerExtraArgs: map[string]string{ - "insecure-port": "1234", + APIServer: kubeadmapi.APIServer{ + ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{ + "insecure-port": "1234", + }, + }, }, }, }, @@ -589,8 +596,12 @@ func TestGetAPIServerCommand(t *testing.T) { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, - APIServerExtraArgs: map[string]string{ - "authorization-mode": authzmodes.ModeWebhook, + APIServer: kubeadmapi.APIServer{ + ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{ + "authorization-mode": authzmodes.ModeWebhook, + }, + }, }, }, }, @@ -715,10 +726,12 @@ func TestGetControllerManagerCommand(t *testing.T) { { name: "custom extra-args for v1.12.0-beta.2", cfg: &kubeadmapi.ClusterConfiguration{ - Networking: kubeadmapi.Networking{PodSubnet: "10.0.1.15/16"}, - ControllerManagerExtraArgs: map[string]string{"node-cidr-mask-size": "20"}, - CertificatesDir: testCertsDir, - KubernetesVersion: "v1.12.0-beta.2", + Networking: kubeadmapi.Networking{PodSubnet: "10.0.1.15/16"}, + ControllerManager: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{"node-cidr-mask-size": "20"}, + }, + CertificatesDir: testCertsDir, + KubernetesVersion: "v1.12.0-beta.2", }, expected: []string{ "kube-controller-manager", @@ -812,10 +825,12 @@ func TestGetControllerManagerCommand(t *testing.T) { { name: "custom extra-args for v1.11.3", cfg: &kubeadmapi.ClusterConfiguration{ - Networking: kubeadmapi.Networking{PodSubnet: "10.0.1.15/16"}, - ControllerManagerExtraArgs: map[string]string{"node-cidr-mask-size": "20"}, - CertificatesDir: testCertsDir, - KubernetesVersion: "v1.11.3", + Networking: kubeadmapi.Networking{PodSubnet: "10.0.1.15/16"}, + ControllerManager: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{"node-cidr-mask-size": "20"}, + }, + CertificatesDir: testCertsDir, + KubernetesVersion: "v1.11.3", }, expected: []string{ "kube-controller-manager", diff --git a/cmd/kubeadm/app/phases/controlplane/volumes.go b/cmd/kubeadm/app/phases/controlplane/volumes.go index 85f3ef8da1397..8ca3b9b8b042b 100644 --- a/cmd/kubeadm/app/phases/controlplane/volumes.go +++ b/cmd/kubeadm/app/phases/controlplane/volumes.go @@ -99,9 +99,9 @@ func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.InitConfiguration) con // Merge user defined mounts and ensure unique volume and volume mount // names - mounts.AddExtraHostPathMounts(kubeadmconstants.KubeAPIServer, cfg.APIServerExtraVolumes) - mounts.AddExtraHostPathMounts(kubeadmconstants.KubeControllerManager, cfg.ControllerManagerExtraVolumes) - mounts.AddExtraHostPathMounts(kubeadmconstants.KubeScheduler, cfg.SchedulerExtraVolumes) + mounts.AddExtraHostPathMounts(kubeadmconstants.KubeAPIServer, cfg.APIServer.ExtraVolumes) + mounts.AddExtraHostPathMounts(kubeadmconstants.KubeControllerManager, cfg.ControllerManager.ExtraVolumes) + mounts.AddExtraHostPathMounts(kubeadmconstants.KubeScheduler, cfg.Scheduler.ExtraVolumes) return mounts } @@ -151,7 +151,7 @@ func (c *controlPlaneHostPathMounts) AddExtraHostPathMounts(component string, ex for _, extraVol := range extraVols { fmt.Printf("[controlplane] Adding extra host path mount %q to %q\n", extraVol.Name, component) hostPathType := extraVol.PathType - c.NewHostPathMount(component, extraVol.Name, extraVol.HostPath, extraVol.MountPath, !extraVol.Writable, &hostPathType) + c.NewHostPathMount(component, extraVol.Name, extraVol.HostPath, extraVol.MountPath, extraVol.ReadOnly, &hostPathType) } } diff --git a/cmd/kubeadm/app/phases/controlplane/volumes_test.go b/cmd/kubeadm/app/phases/controlplane/volumes_test.go index 2f3b7649dd985..8d3dba07c117b 100644 --- a/cmd/kubeadm/app/phases/controlplane/volumes_test.go +++ b/cmd/kubeadm/app/phases/controlplane/volumes_test.go @@ -621,28 +621,28 @@ func TestAddExtraHostPathMounts(t *testing.T) { Name: "foo-0", HostPath: "/tmp/qux-0", MountPath: "/tmp/qux-0", - Writable: false, + ReadOnly: true, PathType: v1.HostPathFile, }, { Name: "bar-0", HostPath: "/tmp/asd-0", MountPath: "/tmp/asd-0", - Writable: true, + ReadOnly: false, PathType: v1.HostPathDirectory, }, { Name: "foo-1", HostPath: "/tmp/qux-1", MountPath: "/tmp/qux-1", - Writable: false, + ReadOnly: true, PathType: v1.HostPathFileOrCreate, }, { Name: "bar-1", HostPath: "/tmp/asd-1", MountPath: "/tmp/asd-1", - Writable: true, + ReadOnly: false, PathType: v1.HostPathDirectoryOrCreate, }, } @@ -672,8 +672,8 @@ func TestAddExtraHostPathMounts(t *testing.T) { if volMount.MountPath != hostMount.MountPath { t.Errorf("Expected container path %q", hostMount.MountPath) } - if volMount.ReadOnly != !hostMount.Writable { - t.Errorf("Expected volume writable setting %t", hostMount.Writable) + if volMount.ReadOnly != hostMount.ReadOnly { + t.Errorf("Expected volume readOnly setting %t", hostMount.ReadOnly) } } } diff --git a/cmd/kubeadm/app/phases/etcd/BUILD b/cmd/kubeadm/app/phases/etcd/BUILD index 339022fcfc179..d3268aa6e1afd 100644 --- a/cmd/kubeadm/app/phases/etcd/BUILD +++ b/cmd/kubeadm/app/phases/etcd/BUILD @@ -13,6 +13,7 @@ go_test( deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", + "//cmd/kubeadm/app/util/etcd:go_default_library", "//cmd/kubeadm/test:go_default_library", ], ) @@ -26,9 +27,12 @@ go_library( "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/images:go_default_library", "//cmd/kubeadm/app/util:go_default_library", + "//cmd/kubeadm/app/util/etcd:go_default_library", "//cmd/kubeadm/app/util/staticpod:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/etcd/local.go b/cmd/kubeadm/app/phases/etcd/local.go index 66333bd8423ae..79e661902300c 100644 --- a/cmd/kubeadm/app/phases/etcd/local.go +++ b/cmd/kubeadm/app/phases/etcd/local.go @@ -19,14 +19,18 @@ package etcd import ( "fmt" "path/filepath" + "strings" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/api/core/v1" + clientset "k8s.io/client-go/kubernetes" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/images" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" + etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd" staticpodutil "k8s.io/kubernetes/cmd/kubeadm/app/util/staticpod" ) @@ -36,13 +40,69 @@ const ( ) // CreateLocalEtcdStaticPodManifestFile will write local etcd static pod manifest file. +// This function is used by init - when the etcd cluster is empty - or by kubeadm +// upgrade - when the etcd cluster is already up and running (and the --initial-cluster flag have no impact) func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.InitConfiguration) error { if cfg.ClusterConfiguration.Etcd.External != nil { - return fmt.Errorf("etcd static pod manifest cannot be generated for cluster using external etcd") + return errors.New("etcd static pod manifest cannot be generated for cluster using external etcd") } - glog.V(1).Infoln("creating local etcd static pod manifest file") - // gets etcd StaticPodSpec, actualized for the current InitConfiguration - spec := GetEtcdPodSpec(cfg) + // gets etcd StaticPodSpec + emptyInitialCluster := []etcdutil.Member{} + spec := GetEtcdPodSpec(cfg, emptyInitialCluster) + // writes etcd StaticPod to disk + if err := staticpodutil.WriteStaticPodToDisk(kubeadmconstants.Etcd, manifestDir, spec); err != nil { + return err + } + + glog.V(1).Infof("[etcd] wrote Static Pod manifest for a local etcd instance to %q\n", kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.Etcd, manifestDir)) + return nil +} + +// CheckLocalEtcdClusterStatus verifies health state of local/stacked etcd cluster before installing a new etcd member +func CheckLocalEtcdClusterStatus(client clientset.Interface, cfg *kubeadmapi.InitConfiguration) error { + fmt.Println("[etcd] Checking Etcd cluster health") + + // creates an etcd client that connects to all the local/stacked etcd members + glog.V(1).Info("creating etcd client that connects to etcd pods") + etcdClient, err := etcdutil.NewFromCluster(client, cfg.CertificatesDir) + if err != nil { + return err + } + + // Checking health state + _, err = etcdClient.GetClusterStatus() + if err != nil { + return errors.Wrap(err, "etcd cluster is not healthy") + } + + return nil +} + +// CreateStackedEtcdStaticPodManifestFile will write local etcd static pod manifest file +// for an additional etcd member that is joining an existing local/stacked etcd cluster. +// Other members of the etcd cluster will be notified of the joining node in beforehand as well. +func CreateStackedEtcdStaticPodManifestFile(client clientset.Interface, manifestDir string, cfg *kubeadmapi.InitConfiguration) error { + // creates an etcd client that connects to all the local/stacked etcd members + glog.V(1).Info("creating etcd client that connects to etcd pods") + etcdClient, err := etcdutil.NewFromCluster(client, cfg.CertificatesDir) + if err != nil { + return err + } + + // notifies the other members of the etcd cluster about the joining member + etcdPeerAddress := fmt.Sprintf("https://%s:%d", cfg.APIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenPeerPort) + + glog.V(1).Infof("Adding etcd member: %s", etcdPeerAddress) + initialCluster, err := etcdClient.AddMember(cfg.NodeRegistration.Name, etcdPeerAddress) + if err != nil { + return err + } + fmt.Println("[etcd] Announced new etcd member joining to the existing etcd cluster") + glog.V(1).Infof("Updated etcd member list: %v", initialCluster) + + glog.V(1).Info("Creating local etcd static pod manifest file") + // gets etcd StaticPodSpec, actualized for the current InitConfiguration and the new list of etcd members + spec := GetEtcdPodSpec(cfg, initialCluster) // writes etcd StaticPod to disk if err := staticpodutil.WriteStaticPodToDisk(kubeadmconstants.Etcd, manifestDir, spec); err != nil { return err @@ -54,7 +114,7 @@ func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.In // GetEtcdPodSpec returns the etcd static Pod actualized to the context of the current InitConfiguration // NB. GetEtcdPodSpec methods holds the information about how kubeadm creates etcd static pod manifests. -func GetEtcdPodSpec(cfg *kubeadmapi.InitConfiguration) v1.Pod { +func GetEtcdPodSpec(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil.Member) v1.Pod { pathType := v1.HostPathDirectoryOrCreate etcdMounts := map[string]v1.Volume{ etcdVolumeName: staticpodutil.NewVolume(etcdVolumeName, cfg.Etcd.Local.DataDir, &pathType), @@ -62,7 +122,7 @@ func GetEtcdPodSpec(cfg *kubeadmapi.InitConfiguration) v1.Pod { } return staticpodutil.ComponentPod(v1.Container{ Name: kubeadmconstants.Etcd, - Command: getEtcdCommand(cfg), + Command: getEtcdCommand(cfg, initialCluster), Image: images.GetEtcdImage(&cfg.ClusterConfiguration), ImagePullPolicy: v1.PullIfNotPresent, // Mount the etcd datadir path read-write so etcd can store data in a more persistent manner @@ -78,13 +138,13 @@ func GetEtcdPodSpec(cfg *kubeadmapi.InitConfiguration) v1.Pod { } // getEtcdCommand builds the right etcd command from the given config object -func getEtcdCommand(cfg *kubeadmapi.InitConfiguration) []string { +func getEtcdCommand(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil.Member) []string { defaultArguments := map[string]string{ "name": cfg.GetNodeName(), - "listen-client-urls": fmt.Sprintf("https://127.0.0.1:%d", kubeadmconstants.EtcdListenClientPort), - "advertise-client-urls": fmt.Sprintf("https://127.0.0.1:%d", kubeadmconstants.EtcdListenClientPort), - "listen-peer-urls": fmt.Sprintf("https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), - "initial-advertise-peer-urls": fmt.Sprintf("https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), + "listen-client-urls": fmt.Sprintf("https://127.0.0.1:%d,https://%s:%d", kubeadmconstants.EtcdListenClientPort, cfg.APIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenClientPort), + "advertise-client-urls": fmt.Sprintf("https://%s:%d", cfg.APIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenClientPort), + "listen-peer-urls": fmt.Sprintf("https://%s:%d", cfg.APIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenPeerPort), + "initial-advertise-peer-urls": fmt.Sprintf("https://%s:%d", cfg.APIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenPeerPort), "data-dir": cfg.Etcd.Local.DataDir, "cert-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerCertName), "key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerKeyName), @@ -95,7 +155,19 @@ func getEtcdCommand(cfg *kubeadmapi.InitConfiguration) []string { "peer-trusted-ca-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdCACertName), "peer-client-cert-auth": "true", "snapshot-count": "10000", - "initial-cluster": fmt.Sprintf("%s=https://127.0.0.1:%d", cfg.GetNodeName(), kubeadmconstants.EtcdListenPeerPort), + } + + if len(initialCluster) == 0 { + defaultArguments["initial-cluster"] = fmt.Sprintf("%s=https://%s:%d", cfg.GetNodeName(), cfg.APIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenPeerPort) + } else { + // NB. the joining etcd instance should be part of the initialCluster list + endpoints := []string{} + for _, member := range initialCluster { + endpoints = append(endpoints, fmt.Sprintf("%s=%s", member.Name, member.PeerURL)) + } + + defaultArguments["initial-cluster"] = strings.Join(endpoints, ",") + defaultArguments["initial-cluster-state"] = "existing" } command := []string{"etcd"} diff --git a/cmd/kubeadm/app/phases/etcd/local_test.go b/cmd/kubeadm/app/phases/etcd/local_test.go index 5ee55d2561680..53c791a2706ff 100644 --- a/cmd/kubeadm/app/phases/etcd/local_test.go +++ b/cmd/kubeadm/app/phases/etcd/local_test.go @@ -26,12 +26,11 @@ import ( kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - + etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd" testutil "k8s.io/kubernetes/cmd/kubeadm/test" ) func TestGetEtcdPodSpec(t *testing.T) { - // Creates a Master Configuration cfg := &kubeadmapi.InitConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{ @@ -46,7 +45,7 @@ func TestGetEtcdPodSpec(t *testing.T) { } // Executes GetEtcdPodSpec - spec := GetEtcdPodSpec(cfg) + spec := GetEtcdPodSpec(cfg, []etcdutil.Member{}) // Assert each specs refers to the right pod if spec.Spec.Containers[0].Name != kubeadmconstants.Etcd { @@ -117,11 +116,17 @@ func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) { func TestGetEtcdCommand(t *testing.T) { var tests = []struct { - cfg *kubeadmapi.InitConfiguration - expected []string + name string + cfg *kubeadmapi.InitConfiguration + initialCluster []etcdutil.Member + expected []string }{ { + name: "Default args - with empty etcd initial cluster", cfg: &kubeadmapi.InitConfiguration{ + APIEndpoint: kubeadmapi.APIEndpoint{ + AdvertiseAddress: "1.2.3.4", + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{ Name: "foo", }, @@ -136,10 +141,10 @@ func TestGetEtcdCommand(t *testing.T) { expected: []string{ "etcd", "--name=foo", - fmt.Sprintf("--listen-client-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenClientPort), - fmt.Sprintf("--advertise-client-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenClientPort), - fmt.Sprintf("--listen-peer-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), - fmt.Sprintf("--initial-advertise-peer-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), + fmt.Sprintf("--listen-client-urls=https://127.0.0.1:%d,https://1.2.3.4:%d", kubeadmconstants.EtcdListenClientPort, kubeadmconstants.EtcdListenClientPort), + fmt.Sprintf("--advertise-client-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenClientPort), + fmt.Sprintf("--listen-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort), + fmt.Sprintf("--initial-advertise-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort), "--data-dir=/var/lib/etcd", "--cert-file=" + kubeadmconstants.EtcdServerCertName, "--key-file=" + kubeadmconstants.EtcdServerKeyName, @@ -150,33 +155,37 @@ func TestGetEtcdCommand(t *testing.T) { "--peer-trusted-ca-file=" + kubeadmconstants.EtcdCACertName, "--snapshot-count=10000", "--peer-client-cert-auth=true", - fmt.Sprintf("--initial-cluster=foo=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), + fmt.Sprintf("--initial-cluster=foo=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort), }, }, { + name: "Default args - With an existing etcd cluster", cfg: &kubeadmapi.InitConfiguration{ + APIEndpoint: kubeadmapi.APIEndpoint{ + AdvertiseAddress: "1.2.3.4", + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{ - Name: "bar", + Name: "foo", }, ClusterConfiguration: kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ DataDir: "/var/lib/etcd", - ExtraArgs: map[string]string{ - "listen-client-urls": "https://10.0.1.10:2379", - "advertise-client-urls": "https://10.0.1.10:2379", - }, }, }, }, }, + initialCluster: []etcdutil.Member{ + {Name: "foo", PeerURL: fmt.Sprintf("https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort)}, // NB. the joining etcd instance should be part of the initialCluster list + {Name: "bar", PeerURL: fmt.Sprintf("https://5.6.7.8:%d", kubeadmconstants.EtcdListenPeerPort)}, + }, expected: []string{ "etcd", - "--name=bar", - "--listen-client-urls=https://10.0.1.10:2379", - "--advertise-client-urls=https://10.0.1.10:2379", - fmt.Sprintf("--listen-peer-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), - fmt.Sprintf("--initial-advertise-peer-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), + "--name=foo", + fmt.Sprintf("--listen-client-urls=https://127.0.0.1:%d,https://1.2.3.4:%d", kubeadmconstants.EtcdListenClientPort, kubeadmconstants.EtcdListenClientPort), + fmt.Sprintf("--advertise-client-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenClientPort), + fmt.Sprintf("--listen-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort), + fmt.Sprintf("--initial-advertise-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort), "--data-dir=/var/lib/etcd", "--cert-file=" + kubeadmconstants.EtcdServerCertName, "--key-file=" + kubeadmconstants.EtcdServerKeyName, @@ -187,30 +196,39 @@ func TestGetEtcdCommand(t *testing.T) { "--peer-trusted-ca-file=" + kubeadmconstants.EtcdCACertName, "--snapshot-count=10000", "--peer-client-cert-auth=true", - fmt.Sprintf("--initial-cluster=bar=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), + "--initial-cluster-state=existing", + fmt.Sprintf("--initial-cluster=foo=https://1.2.3.4:%d,bar=https://5.6.7.8:%d", kubeadmconstants.EtcdListenPeerPort, kubeadmconstants.EtcdListenPeerPort), }, }, { + name: "Extra args", cfg: &kubeadmapi.InitConfiguration{ + APIEndpoint: kubeadmapi.APIEndpoint{ + AdvertiseAddress: "1.2.3.4", + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{ - Name: "wombat", + Name: "bar", }, ClusterConfiguration: kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ - DataDir: "/etc/foo", + DataDir: "/var/lib/etcd", + ExtraArgs: map[string]string{ + "listen-client-urls": "https://10.0.1.10:2379", + "advertise-client-urls": "https://10.0.1.10:2379", + }, }, }, }, }, expected: []string{ "etcd", - "--name=wombat", - fmt.Sprintf("--listen-client-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenClientPort), - fmt.Sprintf("--advertise-client-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenClientPort), - fmt.Sprintf("--listen-peer-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), - fmt.Sprintf("--initial-advertise-peer-urls=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), - "--data-dir=/etc/foo", + "--name=bar", + "--listen-client-urls=https://10.0.1.10:2379", + "--advertise-client-urls=https://10.0.1.10:2379", + fmt.Sprintf("--listen-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort), + fmt.Sprintf("--initial-advertise-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort), + "--data-dir=/var/lib/etcd", "--cert-file=" + kubeadmconstants.EtcdServerCertName, "--key-file=" + kubeadmconstants.EtcdServerKeyName, "--trusted-ca-file=" + kubeadmconstants.EtcdCACertName, @@ -220,17 +238,19 @@ func TestGetEtcdCommand(t *testing.T) { "--peer-trusted-ca-file=" + kubeadmconstants.EtcdCACertName, "--snapshot-count=10000", "--peer-client-cert-auth=true", - fmt.Sprintf("--initial-cluster=wombat=https://127.0.0.1:%d", kubeadmconstants.EtcdListenPeerPort), + fmt.Sprintf("--initial-cluster=bar=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort), }, }, } for _, rt := range tests { - actual := getEtcdCommand(rt.cfg) - sort.Strings(actual) - sort.Strings(rt.expected) - if !reflect.DeepEqual(actual, rt.expected) { - t.Errorf("failed getEtcdCommand:\nexpected:\n%v\nsaw:\n%v", rt.expected, actual) - } + t.Run(rt.name, func(t *testing.T) { + actual := getEtcdCommand(rt.cfg, rt.initialCluster) + sort.Strings(actual) + sort.Strings(rt.expected) + if !reflect.DeepEqual(actual, rt.expected) { + t.Errorf("failed getEtcdCommand:\nexpected:\n%v\nsaw:\n%v", rt.expected, actual) + } + }) } } diff --git a/cmd/kubeadm/app/phases/kubeconfig/BUILD b/cmd/kubeadm/app/phases/kubeconfig/BUILD index 1b7972eeef604..74e70c2bab719 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/BUILD +++ b/cmd/kubeadm/app/phases/kubeconfig/BUILD @@ -16,13 +16,14 @@ go_library( deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", "//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -46,12 +47,13 @@ go_test( deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", "//cmd/kubeadm/app/util:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//cmd/kubeadm/test:go_default_library", "//cmd/kubeadm/test/certs:go_default_library", "//cmd/kubeadm/test/kubeconfig:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", + "//vendor/github.com/renstrom/dedent:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/kubeconfig/doc.go b/cmd/kubeadm/app/phases/kubeconfig/doc.go index 30c3885c55873..3389ab78acbc9 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/doc.go +++ b/cmd/kubeadm/app/phases/kubeconfig/doc.go @@ -22,8 +22,8 @@ package kubeconfig INPUTS: From InitConfiguration - The Master API Server endpoint (AdvertiseAddress + BindPort) is required so the KubeConfig file knows where to find the master - The KubernetesDir path is required for knowing where to put the KubeConfig files + The Master API Server endpoint (AdvertiseAddress + BindPort) is required so the kubeconfig file knows where to find the master + The KubernetesDir path is required for knowing where to put the kubeconfig files The PKIPath is required for knowing where all certificates should be stored OUTPUTS: diff --git a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go index f4a90d455efbc..b18baf4ca902a 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go +++ b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors. +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. @@ -18,24 +18,23 @@ package kubeconfig import ( "bytes" + "crypto/rsa" "crypto/x509" "fmt" "io" "os" "path/filepath" - "crypto/rsa" - "github.com/golang/glog" - + "github.com/pkg/errors" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" certutil "k8s.io/client-go/util/cert" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" ) // clientCertAuth struct holds info required to build a client certificate to provide authentication info in a kubeconfig object @@ -87,32 +86,11 @@ func CreateJoinControlPlaneKubeConfigFiles(outDir string, cfg *kubeadmapi.InitCo ) } -// CreateAdminKubeConfigFile create a kubeconfig file for the admin to use and for kubeadm itself. +// CreateKubeConfigFile creates a kubeconfig file. // If the kubeconfig file already exists, it is used only if evaluated equal; otherwise an error is returned. -func CreateAdminKubeConfigFile(outDir string, cfg *kubeadmapi.InitConfiguration) error { - glog.V(1).Infoln("create a kubeconfig file for the admin and for kubeadm itself") - return createKubeConfigFiles(outDir, cfg, kubeadmconstants.AdminKubeConfigFileName) -} - -// CreateKubeletKubeConfigFile create a kubeconfig file for the Kubelet to use. -// If the kubeconfig file already exists, it is used only if evaluated equal; otherwise an error is returned. -func CreateKubeletKubeConfigFile(outDir string, cfg *kubeadmapi.InitConfiguration) error { - glog.V(1).Infoln("creating a kubeconfig file for the Kubelet") - return createKubeConfigFiles(outDir, cfg, kubeadmconstants.KubeletKubeConfigFileName) -} - -// CreateControllerManagerKubeConfigFile create a kubeconfig file for the ControllerManager to use. -// If the kubeconfig file already exists, it is used only if evaluated equal; otherwise an error is returned. -func CreateControllerManagerKubeConfigFile(outDir string, cfg *kubeadmapi.InitConfiguration) error { - glog.V(1).Infoln("creating kubeconfig file for the ControllerManager") - return createKubeConfigFiles(outDir, cfg, kubeadmconstants.ControllerManagerKubeConfigFileName) -} - -// CreateSchedulerKubeConfigFile create a create a kubeconfig file for the Scheduler to use. -// If the kubeconfig file already exists, it is used only if evaluated equal; otherwise an error is returned. -func CreateSchedulerKubeConfigFile(outDir string, cfg *kubeadmapi.InitConfiguration) error { - glog.V(1).Infoln("creating kubeconfig file for Scheduler") - return createKubeConfigFiles(outDir, cfg, kubeadmconstants.SchedulerKubeConfigFileName) +func CreateKubeConfigFile(kubeConfigFileName string, outDir string, cfg *kubeadmapi.InitConfiguration) error { + glog.V(1).Infof("creating kubeconfig file for %s", kubeConfigFileName) + return createKubeConfigFiles(outDir, cfg, kubeConfigFileName) } // createKubeConfigFiles creates all the requested kubeconfig files. @@ -129,7 +107,7 @@ func createKubeConfigFiles(outDir string, cfg *kubeadmapi.InitConfiguration, kub // retrives the KubeConfigSpec for given kubeConfigFileName spec, exists := specs[kubeConfigFileName] if !exists { - return fmt.Errorf("couldn't retrive KubeConfigSpec for %s", kubeConfigFileName) + return errors.Errorf("couldn't retrive KubeConfigSpec for %s", kubeConfigFileName) } // builds the KubeConfig object @@ -138,7 +116,7 @@ func createKubeConfigFiles(outDir string, cfg *kubeadmapi.InitConfiguration, kub return err } - // writes the KubeConfig to disk if it not exists + // writes the kubeconfig to disk if it not exists if err = createKubeConfigFileIfNotExists(outDir, kubeConfigFileName, config); err != nil { return err } @@ -153,7 +131,7 @@ func getKubeConfigSpecs(cfg *kubeadmapi.InitConfiguration) (map[string]*kubeConf caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName) if err != nil { - return nil, fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err) + return nil, errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded") } masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg) @@ -224,7 +202,7 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc } clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, &clientCertConfig) if err != nil { - return nil, fmt.Errorf("failure while creating %s client certificate: %v", spec.ClientName, err) + return nil, errors.Wrapf(err, "failure while creating %s client certificate", spec.ClientName) } // create a kubeconfig with the client certs @@ -238,28 +216,18 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc ), nil } -// createKubeConfigFileIfNotExists saves the KubeConfig object into a file if there isn't any file at the given path. -// If there already is a KubeConfig file at the given path; kubeadm tries to load it and check if the values in the -// existing and the expected config equals. If they do; kubeadm will just skip writing the file as it's up-to-date, -// but if a file exists but has old content or isn't a kubeconfig file, this function returns an error. -func createKubeConfigFileIfNotExists(outDir, filename string, config *clientcmdapi.Config) error { +// validateKubeConfig check if the kubeconfig file exist and has the expected CA and server URL +func validateKubeConfig(outDir, filename string, config *clientcmdapi.Config) error { kubeConfigFilePath := filepath.Join(outDir, filename) - // Check if the file exist, and if it doesn't, just write it to disk - if _, err := os.Stat(kubeConfigFilePath); os.IsNotExist(err) { - err = kubeconfigutil.WriteToDisk(kubeConfigFilePath, config) - if err != nil { - return fmt.Errorf("failed to save kubeconfig file %s on disk: %v", kubeConfigFilePath, err) - } - - fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", kubeConfigFilePath) - return nil + if _, err := os.Stat(kubeConfigFilePath); err != nil { + return err } // The kubeconfig already exists, let's check if it has got the same CA and server URL currentConfig, err := clientcmd.LoadFromFile(kubeConfigFilePath) if err != nil { - return fmt.Errorf("failed to load kubeconfig file %s that already exists on disk: %v", kubeConfigFilePath, err) + return errors.Wrapf(err, "failed to load kubeconfig file %s that already exists on disk", kubeConfigFilePath) } expectedCtx := config.CurrentContext @@ -269,17 +237,40 @@ func createKubeConfigFileIfNotExists(outDir, filename string, config *clientcmda // If the current CA cert on disk doesn't match the expected CA cert, error out because we have a file, but it's stale if !bytes.Equal(currentConfig.Clusters[currentCluster].CertificateAuthorityData, config.Clusters[expectedCluster].CertificateAuthorityData) { - return fmt.Errorf("a kubeconfig file %q exists already but has got the wrong CA cert", kubeConfigFilePath) + return errors.Errorf("a kubeconfig file %q exists already but has got the wrong CA cert", kubeConfigFilePath) } // If the current API Server location on disk doesn't match the expected API server, error out because we have a file, but it's stale if currentConfig.Clusters[currentCluster].Server != config.Clusters[expectedCluster].Server { - return fmt.Errorf("a kubeconfig file %q exists already but has got the wrong API Server URL", kubeConfigFilePath) + return errors.Errorf("a kubeconfig file %q exists already but has got the wrong API Server URL", kubeConfigFilePath) } + return nil +} + +// createKubeConfigFileIfNotExists saves the KubeConfig object into a file if there isn't any file at the given path. +// If there already is a kubeconfig file at the given path; kubeadm tries to load it and check if the values in the +// existing and the expected config equals. If they do; kubeadm will just skip writing the file as it's up-to-date, +// but if a file exists but has old content or isn't a kubeconfig file, this function returns an error. +func createKubeConfigFileIfNotExists(outDir, filename string, config *clientcmdapi.Config) error { + kubeConfigFilePath := filepath.Join(outDir, filename) + + err := validateKubeConfig(outDir, filename, config) + if err != nil { + // Check if the file exist, and if it doesn't, just write it to disk + if !os.IsNotExist(err) { + return err + } + fmt.Printf("[kubeconfig] Writing %q kubeconfig file\n", filename) + err = kubeconfigutil.WriteToDisk(kubeConfigFilePath, config) + if err != nil { + return errors.Wrapf(err, "failed to save kubeconfig file %q on disk", kubeConfigFilePath) + } + return nil + } // kubeadm doesn't validate the existing kubeconfig file more than this (kubeadm trusts the client certs to be valid) // Basically, if we find a kubeconfig file with the same path; the same CA cert and the same server URL; // kubeadm thinks those files are equal and doesn't bother writing a new file - fmt.Printf("[kubeconfig] Using existing up-to-date KubeConfig file: %q\n", kubeConfigFilePath) + fmt.Printf("[kubeconfig] Using existing up-to-date kubeconfig file: %q\n", kubeConfigFilePath) return nil } @@ -290,7 +281,7 @@ func WriteKubeConfigWithClientCert(out io.Writer, cfg *kubeadmapi.InitConfigurat // creates the KubeConfigSpecs, actualized for the current InitConfiguration caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName) if err != nil { - return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err) + return errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded") } masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg) @@ -317,7 +308,7 @@ func WriteKubeConfigWithToken(out io.Writer, cfg *kubeadmapi.InitConfiguration, // creates the KubeConfigSpecs, actualized for the current InitConfiguration caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName) if err != nil { - return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err) + return errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded") } masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg) @@ -346,12 +337,44 @@ func writeKubeConfigFromSpec(out io.Writer, spec *kubeConfigSpec, clustername st return err } - // writes the KubeConfig to disk if it not exists + // writes the kubeconfig to disk if it not exists configBytes, err := clientcmd.Write(*config) if err != nil { - return fmt.Errorf("failure while serializing admin kubeconfig: %v", err) + return errors.Wrap(err, "failure while serializing admin kubeconfig") } fmt.Fprintln(out, string(configBytes)) return nil } + +// ValidateKubeconfigsForExternalCA check if the kubeconfig file exist and has the expected CA and server URL using kubeadmapi.InitConfiguration. +func ValidateKubeconfigsForExternalCA(outDir string, cfg *kubeadmapi.InitConfiguration) error { + kubeConfigFileNames := []string{ + kubeadmconstants.AdminKubeConfigFileName, + kubeadmconstants.KubeletKubeConfigFileName, + kubeadmconstants.ControllerManagerKubeConfigFileName, + kubeadmconstants.SchedulerKubeConfigFileName, + } + + specs, err := getKubeConfigSpecs(cfg) + if err != nil { + return err + } + + for _, kubeConfigFileName := range kubeConfigFileNames { + spec, exists := specs[kubeConfigFileName] + if !exists { + return errors.Errorf("couldn't retrive KubeConfigSpec for %s", kubeConfigFileName) + } + + kubeconfig, err := buildKubeConfigFromSpec(spec, cfg.ClusterName) + if err != nil { + return err + } + + if err = validateKubeConfig(outDir, kubeConfigFileName, kubeconfig); err != nil { + return err + } + } + return nil +} diff --git a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go index 0e884e3f17f46..9fdbc81ee5677 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go +++ b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 The Kubernetes Authors. +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. @@ -23,15 +23,18 @@ import ( "fmt" "io" "os" + "path/filepath" "reflect" "testing" + "github.com/renstrom/dedent" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - pkiutil "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" + pkiutil "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" testutil "k8s.io/kubernetes/cmd/kubeadm/test" certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs" kubeconfigtestutil "k8s.io/kubernetes/cmd/kubeadm/test/kubeconfig" @@ -249,7 +252,7 @@ func TestCreateKubeConfigFileIfNotExists(t *testing.T) { } } - // Writes the KubeConfig file to disk + // Writes the kubeconfig file to disk err := createKubeConfigFileIfNotExists(tmpdir, "test.conf", test.kubeConfig) if test.expectedError && err == nil { t.Errorf("createKubeConfigFileIfNotExists didn't failed when expected to fail") @@ -292,22 +295,6 @@ func TestCreateKubeconfigFilesAndWrappers(t *testing.T) { kubeadmconstants.SchedulerKubeConfigFileName, }, }, - { // Test CreateAdminKubeConfigFile (wrapper to createKubeConfigFile) - createKubeConfigFunction: CreateAdminKubeConfigFile, - expectedFiles: []string{kubeadmconstants.AdminKubeConfigFileName}, - }, - { // Test CreateKubeletKubeConfigFile (wrapper to createKubeConfigFile) - createKubeConfigFunction: CreateKubeletKubeConfigFile, - expectedFiles: []string{kubeadmconstants.KubeletKubeConfigFileName}, - }, - { // Test CreateControllerManagerKubeConfigFile (wrapper to createKubeConfigFile) - createKubeConfigFunction: CreateControllerManagerKubeConfigFile, - expectedFiles: []string{kubeadmconstants.ControllerManagerKubeConfigFileName}, - }, - { // Test createKubeConfigFile (wrapper to createKubeConfigFile) - createKubeConfigFunction: CreateSchedulerKubeConfigFile, - expectedFiles: []string{kubeadmconstants.SchedulerKubeConfigFileName}, - }, } for _, test := range tests { @@ -453,6 +440,150 @@ func TestWriteKubeConfig(t *testing.T) { } } +func TestValidateKubeConfig(t *testing.T) { + caCert, caKey := certstestutil.SetupCertificateAuthorithy(t) + anotherCaCert, anotherCaKey := certstestutil.SetupCertificateAuthorithy(t) + + config := setupdKubeConfigWithClientAuth(t, caCert, caKey, "https://1.2.3.4:1234", "test-cluster", "myOrg1") + configWithAnotherClusterCa := setupdKubeConfigWithClientAuth(t, anotherCaCert, anotherCaKey, "https://1.2.3.4:1234", "test-cluster", "myOrg1") + configWithAnotherServerURL := setupdKubeConfigWithClientAuth(t, caCert, caKey, "https://4.3.2.1:4321", "test-cluster", "myOrg1") + + tests := map[string]struct { + existingKubeConfig *clientcmdapi.Config + kubeConfig *clientcmdapi.Config + expectedError bool + }{ + "kubeconfig don't exist": { + kubeConfig: config, + expectedError: true, + }, + "kubeconfig exist and has invalid ca": { + existingKubeConfig: configWithAnotherClusterCa, + kubeConfig: config, + expectedError: true, + }, + "kubeconfig exist and has invalid server url": { + existingKubeConfig: configWithAnotherServerURL, + kubeConfig: config, + expectedError: true, + }, + "kubeconfig exist and is valid": { + existingKubeConfig: config, + kubeConfig: config, + expectedError: false, + }, + } + + for name, test := range tests { + tmpdir := testutil.SetupTempDir(t) + defer os.RemoveAll(tmpdir) + + if test.existingKubeConfig != nil { + if err := createKubeConfigFileIfNotExists(tmpdir, "test.conf", test.existingKubeConfig); err != nil { + t.Errorf("createKubeConfigFileIfNotExists failed") + } + } + + err := validateKubeConfig(tmpdir, "test.conf", test.kubeConfig) + if (err != nil) != test.expectedError { + t.Fatalf(dedent.Dedent( + "validateKubeConfig failed\n%s\nexpected error: %t\n\tgot: %t\nerror: %v"), + name, + test.expectedError, + (err != nil), + err, + ) + } + } +} + +func TestValidateKubeconfigsForExternalCA(t *testing.T) { + tmpDir := testutil.SetupTempDir(t) + defer os.RemoveAll(tmpDir) + pkiDir := filepath.Join(tmpDir, "pki") + + initConfig := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + CertificatesDir: pkiDir, + }, + APIEndpoint: kubeadmapi.APIEndpoint{ + BindPort: 1234, + AdvertiseAddress: "1.2.3.4", + }, + } + + caCert, caKey := certstestutil.SetupCertificateAuthorithy(t) + anotherCaCert, anotherCaKey := certstestutil.SetupCertificateAuthorithy(t) + if err := pkiutil.WriteCertAndKey(pkiDir, kubeadmconstants.CACertAndKeyBaseName, caCert, caKey); err != nil { + t.Fatalf("failure while saving CA certificate and key: %v", err) + } + + config := setupdKubeConfigWithClientAuth(t, caCert, caKey, "https://1.2.3.4:1234", "test-cluster", "myOrg1") + configWithAnotherClusterCa := setupdKubeConfigWithClientAuth(t, anotherCaCert, anotherCaKey, "https://1.2.3.4:1234", "test-cluster", "myOrg1") + configWithAnotherServerURL := setupdKubeConfigWithClientAuth(t, caCert, caKey, "https://4.3.2.1:4321", "test-cluster", "myOrg1") + + tests := map[string]struct { + filesToWrite map[string]*clientcmdapi.Config + initConfig *kubeadmapi.InitConfiguration + expectedError bool + }{ + "files don't exist": { + initConfig: initConfig, + expectedError: true, + }, + "some files don't exist": { + filesToWrite: map[string]*clientcmdapi.Config{ + kubeadmconstants.AdminKubeConfigFileName: config, + kubeadmconstants.KubeletKubeConfigFileName: config, + }, + initConfig: initConfig, + expectedError: true, + }, + "some files are invalid": { + filesToWrite: map[string]*clientcmdapi.Config{ + kubeadmconstants.AdminKubeConfigFileName: config, + kubeadmconstants.KubeletKubeConfigFileName: config, + kubeadmconstants.ControllerManagerKubeConfigFileName: configWithAnotherClusterCa, + kubeadmconstants.SchedulerKubeConfigFileName: configWithAnotherServerURL, + }, + initConfig: initConfig, + expectedError: true, + }, + "all files are valid": { + filesToWrite: map[string]*clientcmdapi.Config{ + kubeadmconstants.AdminKubeConfigFileName: config, + kubeadmconstants.KubeletKubeConfigFileName: config, + kubeadmconstants.ControllerManagerKubeConfigFileName: config, + kubeadmconstants.SchedulerKubeConfigFileName: config, + }, + initConfig: initConfig, + expectedError: false, + }, + } + + for name, test := range tests { + tmpdir := testutil.SetupTempDir(t) + defer os.RemoveAll(tmpdir) + + for name, config := range test.filesToWrite { + if err := createKubeConfigFileIfNotExists(tmpdir, name, config); err != nil { + t.Errorf("createKubeConfigFileIfNotExists failed") + } + } + + err := ValidateKubeconfigsForExternalCA(tmpdir, test.initConfig) + if (err != nil) != test.expectedError { + t.Fatalf(dedent.Dedent( + "ValidateKubeconfigsForExternalCA failed\n%s\nexpected error: %t\n\tgot: %t\nerror: %v"), + name, + test.expectedError, + (err != nil), + err, + ) + } + } +} + // setupdKubeConfigWithClientAuth is a test utility function that wraps buildKubeConfigFromSpec for building a KubeConfig object With ClientAuth func setupdKubeConfigWithClientAuth(t *testing.T, caCert *x509.Certificate, caKey *rsa.PrivateKey, APIServer, clientName, clustername string, organizations ...string) *clientcmdapi.Config { spec := &kubeConfigSpec{ diff --git a/cmd/kubeadm/app/phases/kubelet/BUILD b/cmd/kubeadm/app/phases/kubelet/BUILD index 9628eba4e0838..4e440c47721b5 100644 --- a/cmd/kubeadm/app/phases/kubelet/BUILD +++ b/cmd/kubeadm/app/phases/kubelet/BUILD @@ -30,6 +30,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/kubelet/config.go b/cmd/kubeadm/app/phases/kubelet/config.go index d6390408e719e..4797404220bc3 100644 --- a/cmd/kubeadm/app/phases/kubelet/config.go +++ b/cmd/kubeadm/app/phases/kubelet/config.go @@ -22,6 +22,8 @@ import ( "os" "path/filepath" + "github.com/pkg/errors" + "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -77,7 +79,7 @@ func CreateConfigMap(cfg *kubeadmapi.InitConfiguration, client clientset.Interfa } if err := createConfigMapRBACRules(client, k8sVersion); err != nil { - return fmt.Errorf("error creating kubelet configuration configmap RBAC rules: %v", err) + return errors.Wrap(err, "error creating kubelet configuration configmap RBAC rules") } return nil } @@ -155,15 +157,15 @@ func getConfigBytes(kubeletConfig *kubeletconfig.KubeletConfiguration) ([]byte, // writeConfigBytesToDisk writes a byte slice down to disk at the specific location of the kubelet config file func writeConfigBytesToDisk(b []byte, kubeletDir string) error { configFile := filepath.Join(kubeletDir, kubeadmconstants.KubeletConfigurationFileName) - fmt.Printf("[kubelet] Writing kubelet configuration to file %q\n", configFile) + fmt.Printf("[kubelet-start] Writing kubelet configuration to file %q\n", configFile) // creates target folder if not already exists if err := os.MkdirAll(kubeletDir, 0700); err != nil { - return fmt.Errorf("failed to create directory %q: %v", kubeletDir, err) + return errors.Wrapf(err, "failed to create directory %q", kubeletDir) } if err := ioutil.WriteFile(configFile, b, 0644); err != nil { - return fmt.Errorf("failed to write kubelet configuration to the file %q: %v", configFile, err) + return errors.Wrapf(err, "failed to write kubelet configuration to the file %q", configFile) } return nil } diff --git a/cmd/kubeadm/app/phases/kubelet/dynamic.go b/cmd/kubeadm/app/phases/kubelet/dynamic.go index d8b381ff81386..d601b6d53c90f 100644 --- a/cmd/kubeadm/app/phases/kubelet/dynamic.go +++ b/cmd/kubeadm/app/phases/kubelet/dynamic.go @@ -19,6 +19,8 @@ package kubelet import ( "fmt" + "github.com/pkg/errors" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/version" @@ -39,7 +41,7 @@ func EnableDynamicConfigForNode(client clientset.Interface, nodeName string, kub _, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(configMapName, metav1.GetOptions{}) if err != nil { - return fmt.Errorf("couldn't get the kubelet configuration ConfigMap: %v", err) + return errors.Wrap(err, "couldn't get the kubelet configuration ConfigMap") } // Loop on every falsy return. Return with an error if raised. Exit successfully if true is returned. diff --git a/cmd/kubeadm/app/phases/kubelet/flags.go b/cmd/kubeadm/app/phases/kubelet/flags.go index 05ffc1ad7d515..6037e20292af0 100644 --- a/cmd/kubeadm/app/phases/kubelet/flags.go +++ b/cmd/kubeadm/app/phases/kubelet/flags.go @@ -24,6 +24,8 @@ import ( "strings" "github.com/golang/glog" + "github.com/pkg/errors" + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/constants" @@ -43,7 +45,7 @@ type kubeletFlagsOpts struct { defaultHostname string } -// WriteKubeletDynamicEnvFile writes a environment file with dynamic flags to the kubelet. +// WriteKubeletDynamicEnvFile writes an environment file with dynamic flags to the kubelet. // Used at "kubeadm init" and "kubeadm join" time. func WriteKubeletDynamicEnvFile(nodeRegOpts *kubeadmapi.NodeRegistrationOptions, featureGates map[string]bool, registerTaintsUsingFlags bool, kubeletDir string) error { hostName, err := nodeutil.GetHostname("") @@ -119,14 +121,14 @@ func buildKubeletArgMap(opts kubeletFlagsOpts) map[string]string { // writeKubeletFlagBytesToDisk writes a byte slice down to disk at the specific location of the kubelet flag overrides file func writeKubeletFlagBytesToDisk(b []byte, kubeletDir string) error { kubeletEnvFilePath := filepath.Join(kubeletDir, constants.KubeletEnvFileName) - fmt.Printf("[kubelet] Writing kubelet environment file with flags to file %q\n", kubeletEnvFilePath) + fmt.Printf("[kubelet-start] Writing kubelet environment file with flags to file %q\n", kubeletEnvFilePath) // creates target folder if not already exists if err := os.MkdirAll(kubeletDir, 0700); err != nil { - return fmt.Errorf("failed to create directory %q: %v", kubeletDir, err) + return errors.Wrapf(err, "failed to create directory %q", kubeletDir) } if err := ioutil.WriteFile(kubeletEnvFilePath, b, 0644); err != nil { - return fmt.Errorf("failed to write kubelet configuration to the file %q: %v", kubeletEnvFilePath, err) + return errors.Wrapf(err, "failed to write kubelet configuration to the file %q", kubeletEnvFilePath) } return nil } diff --git a/cmd/kubeadm/app/phases/kubelet/flags_test.go b/cmd/kubeadm/app/phases/kubelet/flags_test.go index b1738750003e4..b0464dacbb0df 100644 --- a/cmd/kubeadm/app/phases/kubelet/flags_test.go +++ b/cmd/kubeadm/app/phases/kubelet/flags_test.go @@ -79,7 +79,7 @@ var ( errCgroupExecer = fakeExecer{ ioMap: map[string]fakeCmd{ "docker info": { - err: fmt.Errorf("no such binary: docker"), + err: errors.New("no such binary: docker"), }, }, } diff --git a/cmd/kubeadm/app/phases/kubelet/kubelet.go b/cmd/kubeadm/app/phases/kubelet/kubelet.go index 76a29139917fa..388774800aa67 100644 --- a/cmd/kubeadm/app/phases/kubelet/kubelet.go +++ b/cmd/kubeadm/app/phases/kubelet/kubelet.go @@ -27,19 +27,19 @@ func TryStartKubelet() { // If we notice that the kubelet service is inactive, try to start it initSystem, err := initsystem.GetInitSystem() if err != nil { - fmt.Println("[preflight] no supported init system detected, won't make sure the kubelet is running properly.") + fmt.Println("[kubelet-start] no supported init system detected, won't make sure the kubelet is running properly.") return } if !initSystem.ServiceExists("kubelet") { - fmt.Println("[preflight] couldn't detect a kubelet service, can't make sure the kubelet is running properly.") + fmt.Println("[kubelet-start] couldn't detect a kubelet service, can't make sure the kubelet is running properly.") } - fmt.Println("[preflight] Activating the kubelet service") + fmt.Println("[kubelet-start] Activating the kubelet service") // This runs "systemctl daemon-reload && systemctl restart kubelet" if err := initSystem.ServiceRestart("kubelet"); err != nil { - fmt.Printf("[preflight] WARNING: unable to start the kubelet service: [%v]\n", err) - fmt.Printf("[preflight] please ensure kubelet is reloaded and running manually.\n") + fmt.Printf("[kubelet-start] WARNING: unable to start the kubelet service: [%v]\n", err) + fmt.Printf("[kubelet-start] please ensure kubelet is reloaded and running manually.\n") } } @@ -48,16 +48,16 @@ func TryStopKubelet() { // If we notice that the kubelet service is inactive, try to start it initSystem, err := initsystem.GetInitSystem() if err != nil { - fmt.Println("[preflight] no supported init system detected, won't make sure the kubelet not running for a short period of time while setting up configuration for it.") + fmt.Println("[kubelet-start] no supported init system detected, won't make sure the kubelet not running for a short period of time while setting up configuration for it.") return } if !initSystem.ServiceExists("kubelet") { - fmt.Println("[preflight] couldn't detect a kubelet service, can't make sure the kubelet not running for a short period of time while setting up configuration for it.") + fmt.Println("[kubelet-start] couldn't detect a kubelet service, can't make sure the kubelet not running for a short period of time while setting up configuration for it.") } // This runs "systemctl daemon-reload && systemctl stop kubelet" if err := initSystem.ServiceStop("kubelet"); err != nil { - fmt.Printf("[preflight] WARNING: unable to stop the kubelet service momentarily: [%v]\n", err) + fmt.Printf("[kubelet-start] WARNING: unable to stop the kubelet service momentarily: [%v]\n", err) } } diff --git a/cmd/kubeadm/app/phases/selfhosting/BUILD b/cmd/kubeadm/app/phases/selfhosting/BUILD index 7099f7fe64905..af669d900e4de 100644 --- a/cmd/kubeadm/app/phases/selfhosting/BUILD +++ b/cmd/kubeadm/app/phases/selfhosting/BUILD @@ -19,6 +19,7 @@ go_test( "//cmd/kubeadm/app/util:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -43,6 +44,7 @@ go_library( "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/selfhosting/selfhosting.go b/cmd/kubeadm/app/phases/selfhosting/selfhosting.go index 362029695eab3..2048963369db1 100644 --- a/cmd/kubeadm/app/phases/selfhosting/selfhosting.go +++ b/cmd/kubeadm/app/phases/selfhosting/selfhosting.go @@ -24,6 +24,7 @@ import ( "github.com/golang/glog" + "github.com/pkg/errors" apps "k8s.io/api/apps/v1" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -111,7 +112,7 @@ func CreateSelfHostedControlPlane(manifestsDir, kubeConfigDir string, cfg *kubea // Remove the old Static Pod manifest if not dryrunning if !dryRun { if err := os.RemoveAll(manifestPath); err != nil { - return fmt.Errorf("unable to delete static pod manifest for %s [%v]", componentName, err) + return errors.Wrapf(err, "unable to delete static pod manifest for %s ", componentName) } } @@ -179,18 +180,18 @@ func BuildSelfHostedComponentLabelQuery(componentName string) string { func loadPodSpecFromFile(filePath string) (*v1.PodSpec, error) { podDef, err := ioutil.ReadFile(filePath) if err != nil { - return nil, fmt.Errorf("failed to read file path %s: %+v", filePath, err) + return nil, errors.Wrapf(err, "failed to read file path %s", filePath) } if len(podDef) == 0 { - return nil, fmt.Errorf("file was empty: %s", filePath) + return nil, errors.Errorf("file was empty: %s", filePath) } codec := clientscheme.Codecs.UniversalDecoder() pod := &v1.Pod{} if err = runtime.DecodeInto(codec, podDef, pod); err != nil { - return nil, fmt.Errorf("failed decoding pod: %v", err) + return nil, errors.Wrap(err, "failed decoding pod") } return &pod.Spec, nil diff --git a/cmd/kubeadm/app/phases/selfhosting/selfhosting_test.go b/cmd/kubeadm/app/phases/selfhosting/selfhosting_test.go index 8d7e757f675d1..9532367d413d8 100644 --- a/cmd/kubeadm/app/phases/selfhosting/selfhosting_test.go +++ b/cmd/kubeadm/app/phases/selfhosting/selfhosting_test.go @@ -18,11 +18,12 @@ package selfhosting import ( "bytes" - "fmt" "io/ioutil" "os" "testing" + "github.com/pkg/errors" + apps "k8s.io/api/apps/v1" "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/util" @@ -588,13 +589,13 @@ spec: func createTempFileWithContent(content []byte) (string, error) { tempFile, err := ioutil.TempFile("", "") if err != nil { - return "", fmt.Errorf("cannot create temporary file: %v", err) + return "", errors.Wrap(err, "cannot create temporary file") } if _, err = tempFile.Write([]byte(content)); err != nil { - return "", fmt.Errorf("cannot save temporary file: %v", err) + return "", errors.Wrap(err, "cannot save temporary file") } if err = tempFile.Close(); err != nil { - return "", fmt.Errorf("cannot close temporary file: %v", err) + return "", errors.Wrap(err, "cannot close temporary file") } return tempFile.Name(), nil } diff --git a/cmd/kubeadm/app/phases/upgrade/BUILD b/cmd/kubeadm/app/phases/upgrade/BUILD index c1accd0ecfc51..ad2dab44982f1 100644 --- a/cmd/kubeadm/app/phases/upgrade/BUILD +++ b/cmd/kubeadm/app/phases/upgrade/BUILD @@ -49,6 +49,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -81,12 +82,12 @@ go_test( "//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/phases/certs:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", "//cmd/kubeadm/app/phases/controlplane:go_default_library", "//cmd/kubeadm/app/phases/etcd:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", "//cmd/kubeadm/app/util/etcd:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//cmd/kubeadm/test:go_default_library", "//cmd/kubeadm/test/certs:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", @@ -96,5 +97,6 @@ go_test( "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//vendor/github.com/coreos/etcd/clientv3:go_default_library", "//vendor/github.com/coreos/etcd/pkg/transport:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/upgrade/compute.go b/cmd/kubeadm/app/phases/upgrade/compute.go index a9c7f13d34c58..92cf121ae979f 100644 --- a/cmd/kubeadm/app/phases/upgrade/compute.go +++ b/cmd/kubeadm/app/phases/upgrade/compute.go @@ -302,7 +302,7 @@ func minorUpgradePossibleWithPatchRelease(stableVersion, patchVersion *versionut func getSuggestedEtcdVersion(kubernetesVersion string) string { etcdVersion, err := kubeadmconstants.EtcdSupportedVersion(kubernetesVersion) if err != nil { - fmt.Printf("[upgrade/versions] WARNING: No recommended etcd for requested kubernetes version (%s)\n", kubernetesVersion) + fmt.Printf("[upgrade/versions] WARNING: No recommended etcd for requested Kubernetes version (%s)\n", kubernetesVersion) return "N/A" } return etcdVersion.String() diff --git a/cmd/kubeadm/app/phases/upgrade/compute_test.go b/cmd/kubeadm/app/phases/upgrade/compute_test.go index 6c9a143df04ca..b0cbcdcd5ba51 100644 --- a/cmd/kubeadm/app/phases/upgrade/compute_test.go +++ b/cmd/kubeadm/app/phases/upgrade/compute_test.go @@ -23,6 +23,8 @@ import ( "time" "github.com/coreos/etcd/clientv3" + "github.com/pkg/errors" + apps "k8s.io/api/apps/v1" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -89,7 +91,7 @@ func (f fakeEtcdClient) GetClusterStatus() (map[string]*clientv3.StatusResponse, func (f fakeEtcdClient) GetVersion() (string, error) { versions, _ := f.GetClusterVersions() if f.mismatchedVersions { - return "", fmt.Errorf("etcd cluster contains endpoints with mismatched versions: %v", versions) + return "", errors.Errorf("etcd cluster contains endpoints with mismatched versions: %v", versions) } return "3.1.12", nil } @@ -107,6 +109,12 @@ func (f fakeEtcdClient) GetClusterVersions() (map[string]string, error) { }, nil } +func (f fakeEtcdClient) Sync() error { return nil } + +func (f fakeEtcdClient) AddMember(name string, peerAddrs string) ([]etcdutil.Member, error) { + return []etcdutil.Member{}, nil +} + func TestGetAvailableUpgrades(t *testing.T) { etcdClient := fakeEtcdClient{} tests := []struct { @@ -724,7 +732,7 @@ func TestGetAvailableUpgrades(t *testing.T) { } // Instantiating a fake etcd cluster for being able to get etcd version for a corresponding - // kubernetes release. + // Kubernetes release. for _, rt := range tests { t.Run(rt.name, func(t *testing.T) { diff --git a/cmd/kubeadm/app/phases/upgrade/health.go b/cmd/kubeadm/app/phases/upgrade/health.go index 50b014dee6ec4..2c4eac7fa9133 100644 --- a/cmd/kubeadm/app/phases/upgrade/health.go +++ b/cmd/kubeadm/app/phases/upgrade/health.go @@ -21,6 +21,8 @@ import ( "net/http" "os" + "github.com/pkg/errors" + apps "k8s.io/api/apps/v1" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -102,7 +104,7 @@ func apiServerHealthy(client clientset.Interface) error { } client.Discovery().RESTClient().Get().AbsPath("/healthz").Do().StatusCode(&healthStatus) if healthStatus != http.StatusOK { - return fmt.Errorf("the API Server is unhealthy; /healthz didn't return %q", "ok") + return errors.Errorf("the API Server is unhealthy; /healthz didn't return %q", "ok") } return nil } @@ -116,16 +118,16 @@ func masterNodesReady(client clientset.Interface) error { LabelSelector: selector.String(), }) if err != nil { - return fmt.Errorf("couldn't list masters in cluster: %v", err) + return errors.Wrap(err, "couldn't list masters in cluster") } if len(masters.Items) == 0 { - return fmt.Errorf("failed to find any nodes with master role") + return errors.New("failed to find any nodes with master role") } notReadyMasters := getNotReadyNodes(masters.Items) if len(notReadyMasters) != 0 { - return fmt.Errorf("there are NotReady masters in the cluster: %v", notReadyMasters) + return errors.Errorf("there are NotReady masters in the cluster: %v", notReadyMasters) } return nil } @@ -138,7 +140,7 @@ func controlPlaneHealth(client clientset.Interface) error { } if len(notReadyDaemonSets) != 0 { - return fmt.Errorf("there are control plane DaemonSets in the cluster that are not ready: %v", notReadyDaemonSets) + return errors.Errorf("there are control plane DaemonSets in the cluster that are not ready: %v", notReadyDaemonSets) } return nil } @@ -155,7 +157,7 @@ func staticPodManifestHealth(_ clientset.Interface) error { if len(nonExistentManifests) == 0 { return nil } - return fmt.Errorf("The control plane seems to be Static Pod-hosted, but some of the manifests don't seem to exist on disk. This probably means you're running 'kubeadm upgrade' on a remote machine, which is not supported for a Static Pod-hosted cluster. Manifest files not found: %v", nonExistentManifests) + return errors.Errorf("The control plane seems to be Static Pod-hosted, but some of the manifests don't seem to exist on disk. This probably means you're running 'kubeadm upgrade' on a remote machine, which is not supported for a Static Pod-hosted cluster. Manifest files not found: %v", nonExistentManifests) } // IsControlPlaneSelfHosted returns whether the control plane is self hosted or not @@ -176,11 +178,11 @@ func getNotReadyDaemonSets(client clientset.Interface) ([]error, error) { dsName := constants.AddSelfHostedPrefix(component) ds, err := client.AppsV1().DaemonSets(metav1.NamespaceSystem).Get(dsName, metav1.GetOptions{}) if err != nil { - return nil, fmt.Errorf("couldn't get daemonset %q in the %s namespace", dsName, metav1.NamespaceSystem) + return nil, errors.Errorf("couldn't get daemonset %q in the %s namespace", dsName, metav1.NamespaceSystem) } if err := daemonSetHealth(&ds.Status); err != nil { - notReadyDaemonSets = append(notReadyDaemonSets, fmt.Errorf("DaemonSet %q not healthy: %v", dsName, err)) + notReadyDaemonSets = append(notReadyDaemonSets, errors.Wrapf(err, "DaemonSet %q not healthy", dsName)) } } return notReadyDaemonSets, nil @@ -189,13 +191,14 @@ func getNotReadyDaemonSets(client clientset.Interface) ([]error, error) { // daemonSetHealth is a helper function for getting the health of a DaemonSet's status func daemonSetHealth(dsStatus *apps.DaemonSetStatus) error { if dsStatus.CurrentNumberScheduled != dsStatus.DesiredNumberScheduled { - return fmt.Errorf("current number of scheduled Pods ('%d') doesn't match the amount of desired Pods ('%d')", dsStatus.CurrentNumberScheduled, dsStatus.DesiredNumberScheduled) + return errors.Errorf("current number of scheduled Pods ('%d') doesn't match the amount of desired Pods ('%d')", + dsStatus.CurrentNumberScheduled, dsStatus.DesiredNumberScheduled) } if dsStatus.NumberAvailable == 0 { - return fmt.Errorf("no available Pods for DaemonSet") + return errors.New("no available Pods for DaemonSet") } if dsStatus.NumberReady == 0 { - return fmt.Errorf("no ready Pods for DaemonSet") + return errors.New("no ready Pods for DaemonSet") } return nil } diff --git a/cmd/kubeadm/app/phases/upgrade/policy.go b/cmd/kubeadm/app/phases/upgrade/policy.go index 0a296ecb74b05..876e1ad12825b 100644 --- a/cmd/kubeadm/app/phases/upgrade/policy.go +++ b/cmd/kubeadm/app/phases/upgrade/policy.go @@ -17,9 +17,10 @@ limitations under the License. package upgrade import ( - "fmt" "strings" + "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/util/version" "k8s.io/kubernetes/cmd/kubeadm/app/constants" ) @@ -52,32 +53,32 @@ func EnforceVersionPolicies(versionGetter VersionGetter, newK8sVersionStr string clusterVersionStr, clusterVersion, err := versionGetter.ClusterVersion() if err != nil { // This case can't be forced: kubeadm has to be able to lookup cluster version for upgrades to work - skewErrors.Mandatory = append(skewErrors.Mandatory, fmt.Errorf("Unable to fetch cluster version: %v", err)) + skewErrors.Mandatory = append(skewErrors.Mandatory, errors.Wrap(err, "Unable to fetch cluster version")) return skewErrors } kubeadmVersionStr, kubeadmVersion, err := versionGetter.KubeadmVersion() if err != nil { // This case can't be forced: kubeadm has to be able to lookup its version for upgrades to work - skewErrors.Mandatory = append(skewErrors.Mandatory, fmt.Errorf("Unable to fetch kubeadm version: %v", err)) + skewErrors.Mandatory = append(skewErrors.Mandatory, errors.Wrap(err, "Unable to fetch kubeadm version")) return skewErrors } kubeletVersions, err := versionGetter.KubeletVersions() if err != nil { // This is a non-critical error; continue although kubeadm couldn't look this up - skewErrors.Skippable = append(skewErrors.Skippable, fmt.Errorf("Unable to fetch kubelet version: %v", err)) + skewErrors.Skippable = append(skewErrors.Skippable, errors.Wrap(err, "Unable to fetch kubelet version")) } // Make sure the new version is a supported version (higher than the minimum one supported) if constants.MinimumControlPlaneVersion.AtLeast(newK8sVersion) { // This must not happen, kubeadm always supports a minimum version; and we can't go below that - skewErrors.Mandatory = append(skewErrors.Mandatory, fmt.Errorf("Specified version to upgrade to %q is equal to or lower than the minimum supported version %q. Please specify a higher version to upgrade to", newK8sVersionStr, clusterVersionStr)) + skewErrors.Mandatory = append(skewErrors.Mandatory, errors.Errorf("Specified version to upgrade to %q is equal to or lower than the minimum supported version %q. Please specify a higher version to upgrade to", newK8sVersionStr, clusterVersionStr)) } // kubeadm doesn't support upgrades between two minor versions; e.g. a v1.7 -> v1.9 upgrade is not supported right away if newK8sVersion.Minor() > clusterVersion.Minor()+MaximumAllowedMinorVersionUpgradeSkew { - tooLargeUpgradeSkewErr := fmt.Errorf("Specified version to upgrade to %q is too high; kubeadm can upgrade only %d minor version at a time", newK8sVersionStr, MaximumAllowedMinorVersionUpgradeSkew) + tooLargeUpgradeSkewErr := errors.Errorf("Specified version to upgrade to %q is too high; kubeadm can upgrade only %d minor version at a time", newK8sVersionStr, MaximumAllowedMinorVersionUpgradeSkew) // If the version that we're about to upgrade to is a released version, we should fully enforce this policy // If the version is a CI/dev/experimental version, it's okay to jump two minor version steps, but then require the -f flag if len(newK8sVersion.PreRelease()) == 0 { @@ -89,7 +90,7 @@ func EnforceVersionPolicies(versionGetter VersionGetter, newK8sVersionStr string // kubeadm doesn't support downgrades between two minor versions; e.g. a v1.9 -> v1.7 downgrade is not supported right away if newK8sVersion.Minor() < clusterVersion.Minor()-MaximumAllowedMinorVersionDowngradeSkew { - tooLargeDowngradeSkewErr := fmt.Errorf("Specified version to downgrade to %q is too low; kubeadm can downgrade only %d minor version at a time", newK8sVersionStr, MaximumAllowedMinorVersionDowngradeSkew) + tooLargeDowngradeSkewErr := errors.Errorf("Specified version to downgrade to %q is too low; kubeadm can downgrade only %d minor version at a time", newK8sVersionStr, MaximumAllowedMinorVersionDowngradeSkew) // If the version that we're about to downgrade to is a released version, we should fully enforce this policy // If the version is a CI/dev/experimental version, it's okay to jump two minor version steps, but then require the -f flag if len(newK8sVersion.PreRelease()) == 0 { @@ -102,7 +103,7 @@ func EnforceVersionPolicies(versionGetter VersionGetter, newK8sVersionStr string // If the kubeadm version is lower than what we want to upgrade to; error if kubeadmVersion.LessThan(newK8sVersion) { if newK8sVersion.Minor() > kubeadmVersion.Minor() { - tooLargeKubeadmSkew := fmt.Errorf("Specified version to upgrade to %q is at least one minor release higher than the kubeadm minor release (%d > %d). Such an upgrade is not supported", newK8sVersionStr, newK8sVersion.Minor(), kubeadmVersion.Minor()) + tooLargeKubeadmSkew := errors.Errorf("Specified version to upgrade to %q is at least one minor release higher than the kubeadm minor release (%d > %d). Such an upgrade is not supported", newK8sVersionStr, newK8sVersion.Minor(), kubeadmVersion.Minor()) // This is unsupported; kubeadm has no idea how it should handle a newer minor release than itself // If the version is a CI/dev/experimental version though, lower the severity of this check, but then require the -f flag if len(newK8sVersion.PreRelease()) == 0 { @@ -112,13 +113,13 @@ func EnforceVersionPolicies(versionGetter VersionGetter, newK8sVersionStr string } } else { // Upgrading to a higher patch version than kubeadm is ok if the user specifies --force. Not recommended, but possible. - skewErrors.Skippable = append(skewErrors.Skippable, fmt.Errorf("Specified version to upgrade to %q is higher than the kubeadm version %q. Upgrade kubeadm first using the tool you used to install kubeadm", newK8sVersionStr, kubeadmVersionStr)) + skewErrors.Skippable = append(skewErrors.Skippable, errors.Errorf("Specified version to upgrade to %q is higher than the kubeadm version %q. Upgrade kubeadm first using the tool you used to install kubeadm", newK8sVersionStr, kubeadmVersionStr)) } } if kubeadmVersion.Major() > newK8sVersion.Major() || kubeadmVersion.Minor() > newK8sVersion.Minor() { - skewErrors.Skippable = append(skewErrors.Skippable, fmt.Errorf("Kubeadm version %s can only be used to upgrade to Kubernetes version %d.%d", kubeadmVersionStr, kubeadmVersion.Major(), kubeadmVersion.Minor())) + skewErrors.Skippable = append(skewErrors.Skippable, errors.Errorf("Kubeadm version %s can only be used to upgrade to Kubernetes version %d.%d", kubeadmVersionStr, kubeadmVersion.Major(), kubeadmVersion.Minor())) } // Detect if the version is unstable and the user didn't allow that @@ -159,7 +160,7 @@ func detectUnstableVersionError(newK8sVersion *version.Version, newK8sVersionStr return nil } - return fmt.Errorf("Specified version to upgrade to %q is an unstable version and such upgrades weren't allowed via setting the --allow-*-upgrades flags", newK8sVersionStr) + return errors.Errorf("Specified version to upgrade to %q is an unstable version and such upgrades weren't allowed via setting the --allow-*-upgrades flags", newK8sVersionStr) } // detectTooOldKubelets errors out if the kubelet versions are so old that an unsupported skew would happen if the cluster was upgraded @@ -169,7 +170,7 @@ func detectTooOldKubelets(newK8sVersion *version.Version, kubeletVersions map[st kubeletVersion, err := version.ParseSemantic(versionStr) if err != nil { - return fmt.Errorf("couldn't parse kubelet version %s", versionStr) + return errors.Errorf("couldn't parse kubelet version %s", versionStr) } if newK8sVersion.Minor() > kubeletVersion.Minor()+MaximumAllowedMinorVersionKubeletSkew { @@ -180,5 +181,5 @@ func detectTooOldKubelets(newK8sVersion *version.Version, kubeletVersions map[st return nil } - return fmt.Errorf("There are kubelets in this cluster that are too old that have these versions %v", tooOldKubeletVersions) + return errors.Errorf("There are kubelets in this cluster that are too old that have these versions %v", tooOldKubeletVersions) } diff --git a/cmd/kubeadm/app/phases/upgrade/postupgrade.go b/cmd/kubeadm/app/phases/upgrade/postupgrade.go index 7c8f0e9206c1a..7d19b889a484a 100644 --- a/cmd/kubeadm/app/phases/upgrade/postupgrade.go +++ b/cmd/kubeadm/app/phases/upgrade/postupgrade.go @@ -23,6 +23,8 @@ import ( "path/filepath" "time" + pkgerrors "github.com/pkg/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/errors" @@ -62,7 +64,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon // Create the new, version-branched kubelet ComponentConfig ConfigMap if err := kubeletphase.CreateConfigMap(cfg, client); err != nil { - errs = append(errs, fmt.Errorf("error creating kubelet configuration ConfigMap: %v", err)) + errs = append(errs, pkgerrors.Wrap(err, "error creating kubelet configuration ConfigMap")) } // Write the new kubelet config down to disk and the env file if needed @@ -74,7 +76,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon // --cri-socket. // TODO: In the future we want to use something more official like NodeStatus or similar for detecting this properly if err := patchnodephase.AnnotateCRISocket(client, cfg.NodeRegistration.Name, cfg.NodeRegistration.CRISocket); err != nil { - errs = append(errs, fmt.Errorf("error uploading crisocket: %v", err)) + errs = append(errs, pkgerrors.Wrap(err, "error uploading crisocket")) } // Create/update RBAC rules that makes the bootstrap tokens able to post CSRs @@ -144,7 +146,7 @@ func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.InitConfiguration, return err } if dnsDeployment.Status.ReadyReplicas == 0 { - return fmt.Errorf("the DNS deployment isn't ready yet") + return pkgerrors.New("the DNS deployment isn't ready yet") } } @@ -166,7 +168,7 @@ func upgradeToSelfHosting(client clientset.Interface, cfg *kubeadmapi.InitConfig // kubeadm will now convert the static Pod-hosted control plane into a self-hosted one fmt.Println("[self-hosted] Creating self-hosted control plane.") if err := selfhosting.CreateSelfHostedControlPlane(kubeadmconstants.GetStaticPodDirectory(), kubeadmconstants.KubernetesDir, cfg, client, waiter, dryRun); err != nil { - return fmt.Errorf("error creating self hosted control plane: %v", err) + return pkgerrors.Wrap(err, "error creating self hosted control plane") } } return nil @@ -178,7 +180,7 @@ func BackupAPIServerCertIfNeeded(cfg *kubeadmapi.InitConfiguration, dryRun bool) shouldBackup, err := shouldBackupAPIServerCertAndKey(certAndKeyDir) if err != nil { // Don't fail the upgrade phase if failing to determine to backup kube-apiserver cert and key. - return fmt.Errorf("[postupgrade] WARNING: failed to determine to backup kube-apiserver cert and key: %v", err) + return pkgerrors.Wrap(err, "[postupgrade] WARNING: failed to determine to backup kube-apiserver cert and key") } if !shouldBackup { @@ -216,7 +218,7 @@ func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitCon // *would* post the new kubelet-config-1.X configmap that doesn't exist now when we're trying to download it // again. if !(apierrors.IsNotFound(err) && dryRun) { - errs = append(errs, fmt.Errorf("error downloading kubelet configuration from the ConfigMap: %v", err)) + errs = append(errs, pkgerrors.Wrap(err, "error downloading kubelet configuration from the ConfigMap")) } } @@ -230,7 +232,7 @@ func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitCon // as we handle that ourselves in the markmaster phase // TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase? if err := kubeletphase.WriteKubeletDynamicEnvFile(&cfg.NodeRegistration, cfg.FeatureGates, false, kubeletDir); err != nil { - errs = append(errs, fmt.Errorf("error writing a dynamic environment file for the kubelet: %v", err)) + errs = append(errs, pkgerrors.Wrap(err, "error writing a dynamic environment file for the kubelet")) } if dryRun { // Print what contents would be written @@ -262,7 +264,7 @@ func getKubeletDir(dryRun bool) (string, error) { func backupAPIServerCertAndKey(certAndKeyDir string) error { subDir := filepath.Join(certAndKeyDir, "expired") if err := os.Mkdir(subDir, 0766); err != nil { - return fmt.Errorf("failed to created backup directory %s: %v", subDir, err) + return pkgerrors.Wrapf(err, "failed to created backup directory %s", subDir) } filesToMove := map[string]string{ @@ -292,7 +294,7 @@ func rollbackFiles(files map[string]string, originalErr error) error { errs = append(errs, err) } } - return fmt.Errorf("couldn't move these files: %v. Got errors: %v", files, errors.NewAggregate(errs)) + return pkgerrors.Errorf("couldn't move these files: %v. Got errors: %v", files, errors.NewAggregate(errs)) } // shouldBackupAPIServerCertAndKey checks if the cert of kube-apiserver will be expired in 180 days. @@ -300,10 +302,10 @@ func shouldBackupAPIServerCertAndKey(certAndKeyDir string) (bool, error) { apiServerCert := filepath.Join(certAndKeyDir, kubeadmconstants.APIServerCertName) certs, err := certutil.CertsFromFile(apiServerCert) if err != nil { - return false, fmt.Errorf("couldn't load the certificate file %s: %v", apiServerCert, err) + return false, pkgerrors.Wrapf(err, "couldn't load the certificate file %s", apiServerCert) } if len(certs) == 0 { - return false, fmt.Errorf("no certificate data found") + return false, pkgerrors.New("no certificate data found") } if time.Now().Sub(certs[0].NotBefore) > expiry { diff --git a/cmd/kubeadm/app/phases/upgrade/prepull.go b/cmd/kubeadm/app/phases/upgrade/prepull.go index 63a2be77d8dcb..9ee08a33a006e 100644 --- a/cmd/kubeadm/app/phases/upgrade/prepull.go +++ b/cmd/kubeadm/app/phases/upgrade/prepull.go @@ -20,6 +20,8 @@ import ( "fmt" "time" + "github.com/pkg/errors" + apps "k8s.io/api/apps/v1" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -69,7 +71,7 @@ func (d *DaemonSetPrepuller) CreateFunc(component string) error { // Create the DaemonSet in the API Server if err := apiclient.CreateOrUpdateDaemonSet(d.client, ds); err != nil { - return fmt.Errorf("unable to create a DaemonSet for prepulling the component %q: %v", component, err) + return errors.Wrapf(err, "unable to create a DaemonSet for prepulling the component %q", component) } return nil } @@ -84,7 +86,7 @@ func (d *DaemonSetPrepuller) WaitFunc(component string) { func (d *DaemonSetPrepuller) DeleteFunc(component string) error { dsName := addPrepullPrefix(component) if err := apiclient.DeleteDaemonSetForeground(d.client, metav1.NamespaceSystem, dsName); err != nil { - return fmt.Errorf("unable to cleanup the DaemonSet used for prepulling %s: %v", component, err) + return errors.Wrapf(err, "unable to cleanup the DaemonSet used for prepulling %s", component) } fmt.Printf("[upgrade/prepull] Prepulled image for component %s.\n", component) return nil @@ -130,7 +132,7 @@ func waitForItemsFromChan(timeoutChan <-chan time.Time, stringChan chan string, for { select { case <-timeoutChan: - return fmt.Errorf("The prepull operation timed out") + return errors.New("The prepull operation timed out") case result := <-stringChan: i++ // If the cleanup function errors; error here as well diff --git a/cmd/kubeadm/app/phases/upgrade/prepull_test.go b/cmd/kubeadm/app/phases/upgrade/prepull_test.go index 559f71fa586ac..5eb4af98cd85e 100644 --- a/cmd/kubeadm/app/phases/upgrade/prepull_test.go +++ b/cmd/kubeadm/app/phases/upgrade/prepull_test.go @@ -17,10 +17,11 @@ limitations under the License. package upgrade import ( - "fmt" "testing" "time" + "github.com/pkg/errors" + "k8s.io/kubernetes/cmd/kubeadm/app/constants" //"k8s.io/apimachinery/pkg/util/version" ) @@ -34,7 +35,7 @@ func NewFailedCreatePrepuller() Prepuller { func (p *failedCreatePrepuller) CreateFunc(component string) error { if component == "kube-controller-manager" { - return fmt.Errorf("boo") + return errors.New("boo") } return nil } @@ -79,7 +80,7 @@ func (p *failedDeletePrepuller) WaitFunc(component string) {} func (p *failedDeletePrepuller) DeleteFunc(component string) error { if component == "kube-scheduler" { - return fmt.Errorf("boo") + return errors.New("boo") } return nil } diff --git a/cmd/kubeadm/app/phases/upgrade/selfhosted.go b/cmd/kubeadm/app/phases/upgrade/selfhosted.go index b92af6978c16f..21cddf8dd57df 100644 --- a/cmd/kubeadm/app/phases/upgrade/selfhosted.go +++ b/cmd/kubeadm/app/phases/upgrade/selfhosted.go @@ -20,6 +20,8 @@ import ( "fmt" "time" + "github.com/pkg/errors" + apps "k8s.io/api/apps/v1" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -120,7 +122,7 @@ func SelfHostedControlPlane(client clientset.Interface, waiter apiclient.Waiter, if err := apiclient.TryRunCommand(func() error { if _, err := client.AppsV1().DaemonSets(newDS.ObjectMeta.Namespace).Update(newDS); err != nil { - return fmt.Errorf("couldn't update self-hosted component's DaemonSet: %v", err) + return errors.Wrapf(err, "couldn't update self-hosted component's DaemonSet") } return nil }, selfHostingFailureThreshold); err != nil { @@ -248,7 +250,7 @@ func getCurrentControlPlaneComponentResources(client clientset.Interface) (map[s // Make sure that there are only one Pod with this label selector; otherwise unexpected things can happen if len(podList.Items) > 1 { - return nil, fmt.Errorf("too many pods with label selector %q found in the %s namespace", podLabelSelector, metav1.NamespaceSystem) + return nil, errors.Errorf("too many pods with label selector %q found in the %s namespace", podLabelSelector, metav1.NamespaceSystem) } // Get the component's DaemonSet object diff --git a/cmd/kubeadm/app/phases/upgrade/staticpods.go b/cmd/kubeadm/app/phases/upgrade/staticpods.go index 4129b6698caef..b5497bb496f8c 100644 --- a/cmd/kubeadm/app/phases/upgrade/staticpods.go +++ b/cmd/kubeadm/app/phases/upgrade/staticpods.go @@ -22,7 +22,9 @@ import ( "strings" "time" + "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/version" + clientset "k8s.io/client-go/kubernetes" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/constants" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" @@ -188,7 +190,7 @@ func upgradeComponent(component string, waiter apiclient.Waiter, pathMgr StaticP } if err := renewCerts(cfg, component); err != nil { - return fmt.Errorf("failed to renew certificates for component %q: %v", component, err) + return errors.Wrapf(err, "failed to renew certificates for component %q", component) } // The old manifest is here; in the /etc/kubernetes/manifests/ @@ -250,42 +252,50 @@ func upgradeComponent(component string, waiter apiclient.Waiter, pathMgr StaticP } // performEtcdStaticPodUpgrade performs upgrade of etcd, it returns bool which indicates fatal error or not and the actual error. -func performEtcdStaticPodUpgrade(waiter apiclient.Waiter, pathMgr StaticPodPathManager, cfg *kubeadmapi.InitConfiguration, recoverManifests map[string]string, isTLSUpgrade bool, oldEtcdClient, newEtcdClient etcdutil.ClusterInterrogator) (bool, error) { +func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Waiter, pathMgr StaticPodPathManager, cfg *kubeadmapi.InitConfiguration, recoverManifests map[string]string, isTLSUpgrade bool, oldEtcdClient, newEtcdClient etcdutil.ClusterInterrogator) (bool, error) { // Add etcd static pod spec only if external etcd is not configured if cfg.Etcd.External != nil { - return false, fmt.Errorf("external etcd detected, won't try to change any etcd state") + return false, errors.New("external etcd detected, won't try to change any etcd state") } // Checking health state of etcd before proceeding with the upgrade _, err := oldEtcdClient.GetClusterStatus() if err != nil { - return true, fmt.Errorf("etcd cluster is not healthy: %v", err) + return true, errors.Wrap(err, "etcd cluster is not healthy") } // Backing up etcd data store backupEtcdDir := pathMgr.BackupEtcdDir() runningEtcdDir := cfg.Etcd.Local.DataDir if err := util.CopyDir(runningEtcdDir, backupEtcdDir); err != nil { - return true, fmt.Errorf("failed to back up etcd data: %v", err) + return true, errors.Wrap(err, "failed to back up etcd data") } // Need to check currently used version and version from constants, if differs then upgrade desiredEtcdVersion, err := constants.EtcdSupportedVersion(cfg.KubernetesVersion) if err != nil { - return true, fmt.Errorf("failed to retrieve an etcd version for the target kubernetes version: %v", err) + return true, errors.Wrap(err, "failed to retrieve an etcd version for the target Kubernetes version") } - currentEtcdVersionStr, err := oldEtcdClient.GetVersion() + + // gets the etcd version of the local/stacked etcd member running on the current machine + currentEtcdVersions, err := oldEtcdClient.GetClusterVersions() if err != nil { - return true, fmt.Errorf("failed to retrieve the current etcd version: %v", err) + return true, errors.Wrap(err, "failed to retrieve the current etcd version") + } + currentEtcdVersionStr, ok := currentEtcdVersions[fmt.Sprintf("https://%s:%d", cfg.APIEndpoint.AdvertiseAddress, constants.EtcdListenClientPort)] + if !ok { + fmt.Println(currentEtcdVersions) + return true, errors.Wrap(err, "failed to retrieve the current etcd version") } + currentEtcdVersion, err := version.ParseSemantic(currentEtcdVersionStr) if err != nil { - return true, fmt.Errorf("failed to parse the current etcd version(%s): %v", currentEtcdVersionStr, err) + return true, errors.Wrapf(err, "failed to parse the current etcd version(%s)", currentEtcdVersionStr) } // Comparing current etcd version with desired to catch the same version or downgrade condition and fail on them. if desiredEtcdVersion.LessThan(currentEtcdVersion) { - return false, fmt.Errorf("the desired etcd version for this Kubernetes version %q is %q, but the current etcd version is %q. Won't downgrade etcd, instead just continue", cfg.KubernetesVersion, desiredEtcdVersion.String(), currentEtcdVersion.String()) + return false, errors.Errorf("the desired etcd version for this Kubernetes version %q is %q, but the current etcd version is %q. Won't downgrade etcd, instead just continue", cfg.KubernetesVersion, desiredEtcdVersion.String(), currentEtcdVersion.String()) } // For the case when desired etcd version is the same as current etcd version if strings.Compare(desiredEtcdVersion.String(), currentEtcdVersion.String()) == 0 { @@ -294,13 +304,13 @@ func performEtcdStaticPodUpgrade(waiter apiclient.Waiter, pathMgr StaticPodPathM beforeEtcdPodHash, err := waiter.WaitForStaticPodSingleHash(cfg.NodeRegistration.Name, constants.Etcd) if err != nil { - return true, fmt.Errorf("failed to get etcd pod's hash: %v", err) + return true, errors.Wrap(err, "failed to get etcd pod's hash") } // Write the updated etcd static Pod manifest into the temporary directory, at this point no etcd change // has occurred in any aspects. if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(pathMgr.TempManifestDir(), cfg); err != nil { - return true, fmt.Errorf("error creating local etcd static pod manifest file: %v", err) + return true, errors.Wrap(err, "error creating local etcd static pod manifest file") } // Waiter configurations for checking etcd status @@ -329,7 +339,7 @@ func performEtcdStaticPodUpgrade(waiter apiclient.Waiter, pathMgr StaticPodPathM fmt.Println("[upgrade/etcd] Rolling back etcd data") if err := rollbackEtcdData(cfg, pathMgr); err != nil { // Even copying back datastore failed, no options for recovery left, bailing out - return true, fmt.Errorf("fatal error rolling back local etcd cluster datadir: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir) + return true, errors.Errorf("fatal error rolling back local etcd cluster datadir: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir) } fmt.Println("[upgrade/etcd] Etcd data rollback successful") @@ -338,7 +348,7 @@ func performEtcdStaticPodUpgrade(waiter apiclient.Waiter, pathMgr StaticPodPathM if _, err := oldEtcdClient.WaitForClusterAvailable(noDelay, retries, retryInterval); err != nil { fmt.Printf("[upgrade/etcd] Failed to healthcheck previous etcd: %v\n", err) // Nothing else left to try to recover etcd cluster - return true, fmt.Errorf("fatal error rolling back local etcd cluster manifest: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir) + return true, errors.Wrapf(err, "fatal error rolling back local etcd cluster manifest, the backup of etcd database is stored here:(%s)", backupEtcdDir) } // We've recovered to the previous etcd from this case @@ -346,20 +356,16 @@ func performEtcdStaticPodUpgrade(waiter apiclient.Waiter, pathMgr StaticPodPathM fmt.Println("[upgrade/etcd] Etcd was rolled back and is now available") // Since etcd cluster came back up with the old manifest - return true, fmt.Errorf("fatal error when trying to upgrade the etcd cluster: %v, rolled the state back to pre-upgrade state", err) + return true, errors.Wrap(err, "fatal error when trying to upgrade the etcd cluster, rolled the state back to pre-upgrade state") } // Initialize the new etcd client if it wasn't pre-initialized if newEtcdClient == nil { - client, err := etcdutil.NewFromStaticPod( - []string{fmt.Sprintf("localhost:%d", constants.EtcdListenClientPort)}, - constants.GetStaticPodDirectory(), - cfg.CertificatesDir, - ) + etcdClient, err := etcdutil.NewFromCluster(client, cfg.CertificatesDir) if err != nil { - return true, fmt.Errorf("fatal error creating etcd client: %v", err) + return true, errors.Wrap(err, "fatal error creating etcd client") } - newEtcdClient = client + newEtcdClient = etcdClient } // Checking health state of etcd after the upgrade @@ -371,7 +377,7 @@ func performEtcdStaticPodUpgrade(waiter apiclient.Waiter, pathMgr StaticPodPathM fmt.Println("[upgrade/etcd] Rolling back etcd data") if err := rollbackEtcdData(cfg, pathMgr); err != nil { // Even copying back datastore failed, no options for recovery left, bailing out - return true, fmt.Errorf("fatal error rolling back local etcd cluster datadir: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir) + return true, errors.Wrapf(err, "fatal error rolling back local etcd cluster datadir, the backup of etcd database is stored here:(%s)", backupEtcdDir) } fmt.Println("[upgrade/etcd] Etcd data rollback successful") @@ -385,19 +391,19 @@ func performEtcdStaticPodUpgrade(waiter apiclient.Waiter, pathMgr StaticPodPathM if _, err := oldEtcdClient.WaitForClusterAvailable(noDelay, retries, retryInterval); err != nil { fmt.Printf("[upgrade/etcd] Failed to healthcheck previous etcd: %v\n", err) // Nothing else left to try to recover etcd cluster - return true, fmt.Errorf("fatal error rolling back local etcd cluster manifest: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir) + return true, errors.Wrapf(err, "fatal error rolling back local etcd cluster manifest, the backup of etcd database is stored here:(%s)", backupEtcdDir) } fmt.Println("[upgrade/etcd] Etcd was rolled back and is now available") // We've successfully rolled back etcd, and now return an error describing that the upgrade failed - return true, fmt.Errorf("fatal error upgrading local etcd cluster: %v, rolled the state back to pre-upgrade state", err) + return true, errors.Wrap(err, "fatal error upgrading local etcd cluster, rolled the state back to pre-upgrade state") } return false, nil } // StaticPodControlPlane upgrades a static pod-hosted control plane -func StaticPodControlPlane(waiter apiclient.Waiter, pathMgr StaticPodPathManager, cfg *kubeadmapi.InitConfiguration, etcdUpgrade bool, oldEtcdClient, newEtcdClient etcdutil.ClusterInterrogator) error { +func StaticPodControlPlane(client clientset.Interface, waiter apiclient.Waiter, pathMgr StaticPodPathManager, cfg *kubeadmapi.InitConfiguration, etcdUpgrade bool, oldEtcdClient, newEtcdClient etcdutil.ClusterInterrogator) error { recoverManifests := map[string]string{} var isTLSUpgrade bool var isExternalEtcd bool @@ -411,31 +417,27 @@ func StaticPodControlPlane(waiter apiclient.Waiter, pathMgr StaticPodPathManager if cfg.Etcd.External != nil { // External etcd isExternalEtcd = true - client, err := etcdutil.New( + etcdClient, err := etcdutil.New( cfg.Etcd.External.Endpoints, cfg.Etcd.External.CAFile, cfg.Etcd.External.CertFile, cfg.Etcd.External.KeyFile, ) if err != nil { - return fmt.Errorf("failed to create etcd client for external etcd: %v", err) + return errors.Wrap(err, "failed to create etcd client for external etcd") } - oldEtcdClient = client + oldEtcdClient = etcdClient // Since etcd is managed externally, the new etcd client will be the same as the old client if newEtcdClient == nil { - newEtcdClient = client + newEtcdClient = etcdClient } } else { // etcd Static Pod - client, err := etcdutil.NewFromStaticPod( - []string{fmt.Sprintf("localhost:%d", constants.EtcdListenClientPort)}, - constants.GetStaticPodDirectory(), - cfg.CertificatesDir, - ) + etcdClient, err := etcdutil.NewFromCluster(client, cfg.CertificatesDir) if err != nil { - return fmt.Errorf("failed to create etcd client: %v", err) + return errors.Wrap(err, "failed to create etcd client") } - oldEtcdClient = client + oldEtcdClient = etcdClient } } @@ -450,7 +452,7 @@ func StaticPodControlPlane(waiter apiclient.Waiter, pathMgr StaticPodPathManager } // Perform etcd upgrade using common to all control plane components function - fatal, err := performEtcdStaticPodUpgrade(waiter, pathMgr, cfg, recoverManifests, isTLSUpgrade, oldEtcdClient, newEtcdClient) + fatal, err := performEtcdStaticPodUpgrade(client, waiter, pathMgr, cfg, recoverManifests, isTLSUpgrade, oldEtcdClient, newEtcdClient) if err != nil { if fatal { return err @@ -463,7 +465,7 @@ func StaticPodControlPlane(waiter apiclient.Waiter, pathMgr StaticPodPathManager fmt.Printf("[upgrade/staticpods] Writing new Static Pod manifests to %q\n", pathMgr.TempManifestDir()) err = controlplanephase.CreateInitStaticPodManifestFiles(pathMgr.TempManifestDir(), cfg) if err != nil { - return fmt.Errorf("error creating init static pod manifest files: %v", err) + return errors.Wrap(err, "error creating init static pod manifest files") } for _, component := range constants.MasterComponents { @@ -497,7 +499,7 @@ func rollbackOldManifests(oldManifests map[string]string, origErr error, pathMgr } } // Let the user know there were problems, but we tried to recover - return fmt.Errorf("couldn't upgrade control plane. kubeadm has tried to recover everything into the earlier state. Errors faced: %v", errs) + return errors.New("couldn't upgrade control plane. kubeadm has tried to recover everything into the earlier state. Errors faced") } // rollbackEtcdData rolls back the content of etcd folder if something went wrong. @@ -508,7 +510,7 @@ func rollbackEtcdData(cfg *kubeadmapi.InitConfiguration, pathMgr StaticPodPathMa if err := util.CopyDir(backupEtcdDir, runningEtcdDir); err != nil { // Let the user know there we're problems, but we tried to reçover - return fmt.Errorf("couldn't recover etcd database with error: %v, the location of etcd backup: %s ", err, backupEtcdDir) + return errors.Wrapf(err, "couldn't recover etcd database with error, the location of etcd backup: %s ", backupEtcdDir) } return nil @@ -520,7 +522,7 @@ func renewCerts(cfg *kubeadmapi.InitConfiguration, component string) error { if component == constants.Etcd || component == constants.KubeAPIServer { caCert, caKey, err := certsphase.LoadCertificateAuthority(cfg.CertificatesDir, certsphase.KubeadmCertEtcdCA.BaseName) if err != nil { - return fmt.Errorf("failed to upgrade the %s CA certificate and key: %v", constants.Etcd, err) + return errors.Wrapf(err, "failed to upgrade the %s CA certificate and key", constants.Etcd) } renewer := renewal.NewFileRenewal(caCert, caKey) @@ -531,14 +533,14 @@ func renewCerts(cfg *kubeadmapi.InitConfiguration, component string) error { &certsphase.KubeadmCertEtcdHealthcheck, } { if err := renewal.RenewExistingCert(cfg.CertificatesDir, cert.BaseName, renewer); err != nil { - return fmt.Errorf("failed to renew %s certificate and key: %v", cert.Name, err) + return errors.Wrapf(err, "failed to renew %s certificate and key", cert.Name) } } } if component == constants.KubeAPIServer { cert := certsphase.KubeadmCertEtcdAPIClient if err := renewal.RenewExistingCert(cfg.CertificatesDir, cert.BaseName, renewer); err != nil { - return fmt.Errorf("failed to renew %s certificate and key: %v", cert.Name, err) + return errors.Wrapf(err, "failed to renew %s certificate and key", cert.Name) } } } diff --git a/cmd/kubeadm/app/phases/upgrade/staticpods_test.go b/cmd/kubeadm/app/phases/upgrade/staticpods_test.go index 7a01ba6c8d1bb..96ed5ff26217d 100644 --- a/cmd/kubeadm/app/phases/upgrade/staticpods_test.go +++ b/cmd/kubeadm/app/phases/upgrade/staticpods_test.go @@ -29,16 +29,18 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/pkg/transport" + "github.com/pkg/errors" + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/constants" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" testutil "k8s.io/kubernetes/cmd/kubeadm/test" certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs" ) @@ -54,14 +56,16 @@ kind: InitConfiguration nodeRegistration: name: foo criSocket: "" +apiEndpoint: + advertiseAddress: 1.2.3.4 + bindPort: 6443 --- apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -api: - advertiseAddress: 1.2.3.4 - bindPort: 6443 -apiServerCertSANs: null -apiServerExtraArgs: null + +apiServer: + certSANs: null + extraArgs: null certificatesDir: %s controllerManagerExtraArgs: null etcd: @@ -75,9 +79,6 @@ networking: dnsDomain: cluster.local podSubnet: "" serviceSubnet: 10.96.0.0/12 -nodeRegistration: - name: foo - criSocket: "" schedulerExtraArgs: null token: ce3aa5.5ec8455bb76b379f tokenTTL: 24h @@ -134,6 +135,11 @@ func (w *fakeWaiter) WaitForHealthyKubelet(_ time.Duration, _ string) error { return nil } +// WaitForKubeletAndFunc is a wrapper for WaitForHealthyKubelet that also blocks for a function +func (w *fakeWaiter) WaitForKubeletAndFunc(f func() error) error { + return nil +} + type fakeStaticPodPathManager struct { kubernetesDir string realManifestDir string @@ -146,22 +152,22 @@ type fakeStaticPodPathManager struct { func NewFakeStaticPodPathManager(moveFileFunc func(string, string) error) (StaticPodPathManager, error) { kubernetesDir, err := ioutil.TempDir("", "kubeadm-pathmanager-") if err != nil { - return nil, fmt.Errorf("couldn't create a temporary directory for the upgrade: %v", err) + return nil, errors.Wrapf(err, "couldn't create a temporary directory for the upgrade") } realManifestDir := filepath.Join(kubernetesDir, constants.ManifestsSubDirName) if err := os.Mkdir(realManifestDir, 0700); err != nil { - return nil, fmt.Errorf("couldn't create a realManifestDir for the upgrade: %v", err) + return nil, errors.Wrapf(err, "couldn't create a realManifestDir for the upgrade") } upgradedManifestDir := filepath.Join(kubernetesDir, "upgraded-manifests") if err := os.Mkdir(upgradedManifestDir, 0700); err != nil { - return nil, fmt.Errorf("couldn't create a upgradedManifestDir for the upgrade: %v", err) + return nil, errors.Wrapf(err, "couldn't create a upgradedManifestDir for the upgrade") } backupManifestDir := filepath.Join(kubernetesDir, "backup-manifests") if err := os.Mkdir(backupManifestDir, 0700); err != nil { - return nil, fmt.Errorf("couldn't create a backupManifestDir for the upgrade: %v", err) + return nil, errors.Wrap(err, "couldn't create a backupManifestDir for the upgrade") } backupEtcdDir := filepath.Join(kubernetesDir, "kubeadm-backup-etcd") @@ -236,14 +242,14 @@ func (c fakeTLSEtcdClient) WaitForClusterAvailable(delay time.Duration, retries func (c fakeTLSEtcdClient) GetClusterStatus() (map[string]*clientv3.StatusResponse, error) { return map[string]*clientv3.StatusResponse{ - "foo": { + "https://1.2.3.4:2379": { Version: "3.1.12", }}, nil } func (c fakeTLSEtcdClient) GetClusterVersions() (map[string]string, error) { return map[string]string{ - "foo": "3.1.12", + "https://1.2.3.4:2379": "3.1.12", }, nil } @@ -251,6 +257,12 @@ func (c fakeTLSEtcdClient) GetVersion() (string, error) { return "3.1.12", nil } +func (c fakeTLSEtcdClient) Sync() error { return nil } + +func (c fakeTLSEtcdClient) AddMember(name string, peerAddrs string) ([]etcdutil.Member, error) { + return []etcdutil.Member{}, nil +} + type fakePodManifestEtcdClient struct{ ManifestDir, CertificatesDir string } func (c fakePodManifestEtcdClient) HasTLS() bool { @@ -277,13 +289,13 @@ func (c fakePodManifestEtcdClient) GetClusterStatus() (map[string]*clientv3.Stat } return map[string]*clientv3.StatusResponse{ - "foo": {Version: "3.1.12"}, + "https://1.2.3.4:2379": {Version: "3.1.12"}, }, nil } func (c fakePodManifestEtcdClient) GetClusterVersions() (map[string]string, error) { return map[string]string{ - "foo": "3.1.12", + "https://1.2.3.4:2379": "3.1.12", }, nil } @@ -291,6 +303,12 @@ func (c fakePodManifestEtcdClient) GetVersion() (string, error) { return "3.1.12", nil } +func (c fakePodManifestEtcdClient) Sync() error { return nil } + +func (c fakePodManifestEtcdClient) AddMember(name string, peerAddrs string) ([]etcdutil.Member, error) { + return []etcdutil.Member{}, nil +} + func TestStaticPodControlPlane(t *testing.T) { tests := []struct { description string @@ -315,7 +333,7 @@ func TestStaticPodControlPlane(t *testing.T) { { description: "any wait error should result in a rollback and an abort", waitErrsToReturn: map[string]error{ - waitForHashes: fmt.Errorf("boo! failed"), + waitForHashes: errors.New("boo! failed"), waitForHashChange: nil, waitForPodsWithLabel: nil, }, @@ -329,7 +347,7 @@ func TestStaticPodControlPlane(t *testing.T) { description: "any wait error should result in a rollback and an abort", waitErrsToReturn: map[string]error{ waitForHashes: nil, - waitForHashChange: fmt.Errorf("boo! failed"), + waitForHashChange: errors.New("boo! failed"), waitForPodsWithLabel: nil, }, moveFileFunc: func(oldPath, newPath string) error { @@ -343,7 +361,7 @@ func TestStaticPodControlPlane(t *testing.T) { waitErrsToReturn: map[string]error{ waitForHashes: nil, waitForHashChange: nil, - waitForPodsWithLabel: fmt.Errorf("boo! failed"), + waitForPodsWithLabel: errors.New("boo! failed"), }, moveFileFunc: func(oldPath, newPath string) error { return os.Rename(oldPath, newPath) @@ -361,7 +379,7 @@ func TestStaticPodControlPlane(t *testing.T) { moveFileFunc: func(oldPath, newPath string) error { // fail for kube-apiserver move if strings.Contains(newPath, "kube-apiserver") { - return fmt.Errorf("moving the kube-apiserver file failed") + return errors.New("moving the kube-apiserver file failed") } return os.Rename(oldPath, newPath) }, @@ -378,7 +396,7 @@ func TestStaticPodControlPlane(t *testing.T) { moveFileFunc: func(oldPath, newPath string) error { // fail for kube-controller-manager move if strings.Contains(newPath, "kube-controller-manager") { - return fmt.Errorf("moving the kube-apiserver file failed") + return errors.New("moving the kube-apiserver file failed") } return os.Rename(oldPath, newPath) }, @@ -395,7 +413,7 @@ func TestStaticPodControlPlane(t *testing.T) { moveFileFunc: func(oldPath, newPath string) error { // fail for kube-scheduler move if strings.Contains(newPath, "kube-scheduler") { - return fmt.Errorf("moving the kube-apiserver file failed") + return errors.New("moving the kube-apiserver file failed") } return os.Rename(oldPath, newPath) }, @@ -477,6 +495,7 @@ func TestStaticPodControlPlane(t *testing.T) { } actualErr := StaticPodControlPlane( + nil, waiter, pathMgr, newcfg, diff --git a/cmd/kubeadm/app/phases/upgrade/versiongetter.go b/cmd/kubeadm/app/phases/upgrade/versiongetter.go index 27648056da46e..377f4a14b6fb5 100644 --- a/cmd/kubeadm/app/phases/upgrade/versiongetter.go +++ b/cmd/kubeadm/app/phases/upgrade/versiongetter.go @@ -20,6 +20,8 @@ import ( "fmt" "io" + "github.com/pkg/errors" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" versionutil "k8s.io/apimachinery/pkg/util/version" @@ -59,13 +61,13 @@ func NewKubeVersionGetter(client clientset.Interface, writer io.Writer) VersionG func (g *KubeVersionGetter) ClusterVersion() (string, *versionutil.Version, error) { clusterVersionInfo, err := g.client.Discovery().ServerVersion() if err != nil { - return "", nil, fmt.Errorf("Couldn't fetch cluster version from the API Server: %v", err) + return "", nil, errors.Wrap(err, "Couldn't fetch cluster version from the API Server") } fmt.Fprintf(g.w, "[upgrade/versions] Cluster version: %s\n", clusterVersionInfo.String()) clusterVersion, err := versionutil.ParseSemantic(clusterVersionInfo.String()) if err != nil { - return "", nil, fmt.Errorf("Couldn't parse cluster version: %v", err) + return "", nil, errors.Wrap(err, "Couldn't parse cluster version") } return clusterVersionInfo.String(), clusterVersion, nil } @@ -77,7 +79,7 @@ func (g *KubeVersionGetter) KubeadmVersion() (string, *versionutil.Version, erro kubeadmVersion, err := versionutil.ParseSemantic(kubeadmVersionInfo.String()) if err != nil { - return "", nil, fmt.Errorf("Couldn't parse kubeadm version: %v", err) + return "", nil, errors.Wrap(err, "Couldn't parse kubeadm version") } return kubeadmVersionInfo.String(), kubeadmVersion, nil } @@ -86,7 +88,7 @@ func (g *KubeVersionGetter) KubeadmVersion() (string, *versionutil.Version, erro func (g *KubeVersionGetter) VersionFromCILabel(ciVersionLabel, description string) (string, *versionutil.Version, error) { versionStr, err := kubeadmutil.KubernetesReleaseVersion(ciVersionLabel) if err != nil { - return "", nil, fmt.Errorf("Couldn't fetch latest %s from the internet: %v", description, err) + return "", nil, errors.Wrapf(err, "Couldn't fetch latest %s from the internet", description) } if description != "" { @@ -95,7 +97,7 @@ func (g *KubeVersionGetter) VersionFromCILabel(ciVersionLabel, description strin ver, err := versionutil.ParseSemantic(versionStr) if err != nil { - return "", nil, fmt.Errorf("Couldn't parse latest %s: %v", description, err) + return "", nil, errors.Wrapf(err, "Couldn't parse latest %s", description) } return versionStr, ver, nil } @@ -104,7 +106,7 @@ func (g *KubeVersionGetter) VersionFromCILabel(ciVersionLabel, description strin func (g *KubeVersionGetter) KubeletVersions() (map[string]uint16, error) { nodes, err := g.client.CoreV1().Nodes().List(metav1.ListOptions{}) if err != nil { - return nil, fmt.Errorf("couldn't list all nodes in cluster") + return nil, errors.New("couldn't list all nodes in cluster") } return computeKubeletVersions(nodes.Items), nil } @@ -145,7 +147,7 @@ func (o *OfflineVersionGetter) VersionFromCILabel(ciVersionLabel, description st } ver, err := versionutil.ParseSemantic(o.version) if err != nil { - return "", nil, fmt.Errorf("Couldn't parse version %s: %v", description, err) + return "", nil, errors.Wrapf(err, "Couldn't parse version %s", description) } return o.version, ver, nil } diff --git a/cmd/kubeadm/app/phases/uploadconfig/BUILD b/cmd/kubeadm/app/phases/uploadconfig/BUILD index b1991dd4b0038..3de81d5f1ff96 100644 --- a/cmd/kubeadm/app/phases/uploadconfig/BUILD +++ b/cmd/kubeadm/app/phases/uploadconfig/BUILD @@ -12,16 +12,13 @@ go_library( importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig", deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", - "//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", "//pkg/apis/rbac/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/rbac/v1: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:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", ], ) @@ -48,13 +45,10 @@ go_test( "//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", - "//cmd/kubeadm/app/util/apiclient:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", - "//staging/src/k8s.io/api/core/v1: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:go_default_library", - "//staging/src/k8s.io/client-go/kubernetes: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/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go index b7ac65ddaa2c4..963119b4481cc 100644 --- a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go +++ b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go @@ -21,12 +21,9 @@ import ( "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" clientset "k8s.io/client-go/kubernetes" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" @@ -59,7 +56,7 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int // Prepare the ClusterStatus for upload // Gets the current cluster status // TODO: use configmap locks on this object on the get before the update. - clusterStatus, err := getClusterStatus(client) + clusterStatus, err := configutil.GetClusterStatus(client) if err != nil { return err } @@ -129,22 +126,3 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int }, }) } - -func getClusterStatus(client clientset.Interface) (*kubeadmapi.ClusterStatus, error) { - obj := &kubeadmapi.ClusterStatus{} - - // Read the ConfigMap from the cluster - configMap, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(kubeadmconstants.KubeadmConfigConfigMap, metav1.GetOptions{}) - if apierrors.IsNotFound(err) { - return obj, nil - } - if err != nil { - return nil, err - } - - // Decode the file content using the componentconfig Codecs that knows about all APIs - if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(configMap.Data[kubeadmconstants.ClusterStatusConfigMapKey]), obj); err != nil { - return nil, err - } - return obj, nil -} diff --git a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go index d575e506541ed..7ef7191760afa 100644 --- a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go +++ b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go @@ -20,18 +20,15 @@ import ( "reflect" "testing" - "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - clientset "k8s.io/client-go/kubernetes" clientsetfake "k8s.io/client-go/kubernetes/fake" core "k8s.io/client-go/testing" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" ) @@ -158,62 +155,3 @@ func TestUploadConfiguration(t *testing.T) { }) } } - -func TestGetClusterStatus(t *testing.T) { - var tests = []struct { - name string - clusterStatus *kubeadmapi.ClusterStatus - expectedClusterEndpoints int - }{ - { - name: "return empty ClusterStatus if cluster kubeadm-config doesn't exist (e.g init)", - expectedClusterEndpoints: 0, - }, - { - name: "return ClusterStatus if cluster kubeadm-config exist (e.g upgrade)", - clusterStatus: &kubeadmapi.ClusterStatus{ - APIEndpoints: map[string]kubeadmapi.APIEndpoint{ - "dummy": {AdvertiseAddress: "1.2.3.4", BindPort: 1234}, - }, - }, - expectedClusterEndpoints: 1, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - client := clientsetfake.NewSimpleClientset() - - if tt.clusterStatus != nil { - createConfigMapWithStatus(tt.clusterStatus, client) - } - - actual, err := getClusterStatus(client) - if err != nil { - t.Error("GetClusterStatus returned unexpected error") - return - } - if tt.expectedClusterEndpoints != len(actual.APIEndpoints) { - t.Error("actual ClusterStatus doesn't return expected endpoints") - } - }) - } -} - -// createConfigMapWithStatus create a ConfigMap with ClusterStatus for TestGetClusterStatus -func createConfigMapWithStatus(statusToCreate *kubeadmapi.ClusterStatus, client clientset.Interface) error { - statusYaml, err := configutil.MarshalKubeadmConfigObject(statusToCreate) - if err != nil { - return err - } - - return apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: kubeadmconstants.KubeadmConfigConfigMap, - Namespace: metav1.NamespaceSystem, - }, - Data: map[string]string{ - kubeadmconstants.ClusterStatusConfigMapKey: string(statusYaml), - }, - }) -} diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go index 74162872af010..032e2b0426fea 100644 --- a/cmd/kubeadm/app/preflight/checks.go +++ b/cmd/kubeadm/app/preflight/checks.go @@ -557,7 +557,7 @@ func (sysver SystemVerificationCheck) Check() (warnings, errors []error) { return warns, nil } -// KubernetesVersionCheck validates kubernetes and kubeadm versions +// KubernetesVersionCheck validates Kubernetes and kubeadm versions type KubernetesVersionCheck struct { KubeadmVersion string KubernetesVersion string @@ -568,9 +568,9 @@ func (KubernetesVersionCheck) Name() string { return "KubernetesVersion" } -// Check validates kubernetes and kubeadm versions +// Check validates Kubernetes and kubeadm versions func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) { - glog.V(1).Infoln("validating kubernetes and kubeadm version") + glog.V(1).Infoln("validating Kubernetes and kubeadm version") // Skip this check for "super-custom builds", where apimachinery/the overall codebase version is not set. if strings.HasPrefix(kubever.KubeadmVersion, "v0.0.0") { return nil, nil @@ -583,7 +583,7 @@ func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) { k8sVersion, err := versionutil.ParseSemantic(kubever.KubernetesVersion) if err != nil { - return nil, []error{fmt.Errorf("couldn't parse kubernetes version %q: %v", kubever.KubernetesVersion, err)} + return nil, []error{fmt.Errorf("couldn't parse Kubernetes version %q: %v", kubever.KubernetesVersion, err)} } // Checks if k8sVersion greater or equal than the first unsupported versions by current version of kubeadm, @@ -592,7 +592,7 @@ func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) { // thus setting the value to x.y.0-0 we are defining the very first patch - prereleases within x.y minor release. firstUnsupportedVersion := versionutil.MustParseSemantic(fmt.Sprintf("%d.%d.%s", kadmVersion.Major(), kadmVersion.Minor()+1, "0-0")) if k8sVersion.AtLeast(firstUnsupportedVersion) { - return []error{fmt.Errorf("kubernetes version is greater than kubeadm version. Please consider to upgrade kubeadm. kubernetes version: %s. Kubeadm version: %d.%d.x", k8sVersion, kadmVersion.Components()[0], kadmVersion.Components()[1])}, nil + return []error{fmt.Errorf("Kubernetes version is greater than kubeadm version. Please consider to upgrade kubeadm. Kubernetes version: %s. Kubeadm version: %d.%d.x", k8sVersion, kadmVersion.Components()[0], kadmVersion.Components()[1])}, nil } return nil, nil @@ -623,7 +623,7 @@ func (kubever KubeletVersionCheck) Check() (warnings, errors []error) { if kubever.KubernetesVersion != "" { k8sVersion, err := versionutil.ParseSemantic(kubever.KubernetesVersion) if err != nil { - return nil, []error{fmt.Errorf("couldn't parse kubernetes version %q: %v", kubever.KubernetesVersion, err)} + return nil, []error{fmt.Errorf("couldn't parse Kubernetes version %q: %v", kubever.KubernetesVersion, err)} } if kubeletVersion.Major() > k8sVersion.Major() || kubeletVersion.Minor() > k8sVersion.Minor() { return nil, []error{fmt.Errorf("the kubelet version is higher than the control plane version. This is not a supported version skew and may lead to a malfunctional cluster. Kubelet version: %q Control plane version: %q", kubeletVersion, k8sVersion)} @@ -900,6 +900,7 @@ func RunInitMasterChecks(execer utilsexec.Interface, cfg *kubeadmapi.InitConfigu // Only do etcd related checks when no external endpoints were specified checks = append(checks, PortOpenCheck{port: kubeadmconstants.EtcdListenClientPort}, + PortOpenCheck{port: kubeadmconstants.EtcdListenPeerPort}, DirAvailableCheck{Path: cfg.Etcd.Local.DataDir}, ) } @@ -940,7 +941,6 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfigura DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)}, FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)}, FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletBootstrapKubeConfigFileName)}, - ipvsutil.RequiredIPVSKernelModulesAvailableCheck{Executor: execer}, } checks = addCommonChecks(execer, cfg, checks) if !cfg.ControlPlane { @@ -949,17 +949,15 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfigura addIPv6Checks := false if cfg.Discovery.BootstrapToken != nil { - for _, server := range cfg.Discovery.BootstrapToken.APIServerEndpoints { - ipstr, _, err := net.SplitHostPort(server) - if err == nil { - checks = append(checks, - HTTPProxyCheck{Proto: "https", Host: ipstr}, - ) - if !addIPv6Checks { - if ip := net.ParseIP(ipstr); ip != nil { - if ip.To4() == nil && ip.To16() != nil { - addIPv6Checks = true - } + ipstr, _, err := net.SplitHostPort(cfg.Discovery.BootstrapToken.APIServerEndpoint) + if err == nil { + checks = append(checks, + HTTPProxyCheck{Proto: "https", Host: ipstr}, + ) + if !addIPv6Checks { + if ip := net.ParseIP(ipstr); ip != nil { + if ip.To4() == nil && ip.To16() != nil { + addIPv6Checks = true } } } @@ -975,6 +973,20 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfigura return RunChecks(checks, os.Stderr, ignorePreflightErrors) } +// RunOptionalJoinNodeChecks executes all individual, applicable to node configuration dependant checks +func RunOptionalJoinNodeChecks(execer utilsexec.Interface, initCfg *kubeadmapi.InitConfiguration, ignorePreflightErrors sets.String) error { + checks := []Checker{} + + // Check ipvs required kernel module if we use ipvs kube-proxy mode + if initCfg.ComponentConfigs.KubeProxy != nil && initCfg.ComponentConfigs.KubeProxy.Mode == ipvsutil.IPVSProxyMode { + checks = append(checks, + ipvsutil.RequiredIPVSKernelModulesAvailableCheck{Executor: execer}, + ) + } + + return RunChecks(checks, os.Stderr, ignorePreflightErrors) +} + // addCommonChecks is a helper function to deplicate checks that are common between both the // kubeadm init and join commands func addCommonChecks(execer utilsexec.Interface, cfg kubeadmapi.CommonConfiguration, checks []Checker) []Checker { @@ -1027,7 +1039,7 @@ func RunRootCheckOnly(ignorePreflightErrors sets.String) error { return RunChecks(checks, os.Stderr, ignorePreflightErrors) } -// RunPullImagesCheck will pull images kubeadm needs if the are not found on the system +// RunPullImagesCheck will pull images kubeadm needs if they are not found on the system func RunPullImagesCheck(execer utilsexec.Interface, cfg *kubeadmapi.InitConfiguration, ignorePreflightErrors sets.String) error { containerRuntime, err := utilruntime.NewContainerRuntime(utilsexec.New(), cfg.GetCRISocket()) if err != nil { diff --git a/cmd/kubeadm/app/preflight/checks_test.go b/cmd/kubeadm/app/preflight/checks_test.go index 52abc2e56bbe2..3f1986d473495 100644 --- a/cmd/kubeadm/app/preflight/checks_test.go +++ b/cmd/kubeadm/app/preflight/checks_test.go @@ -256,7 +256,7 @@ func TestRunJoinNodeChecks(t *testing.T) { cfg: &kubeadmapi.JoinConfiguration{ Discovery: kubeadmapi.Discovery{ BootstrapToken: &kubeadmapi.BootstrapTokenDiscovery{ - APIServerEndpoints: []string{"192.168.1.15"}, + APIServerEndpoint: "192.168.1.15", }, }, }, @@ -266,7 +266,7 @@ func TestRunJoinNodeChecks(t *testing.T) { cfg: &kubeadmapi.JoinConfiguration{ Discovery: kubeadmapi.Discovery{ BootstrapToken: &kubeadmapi.BootstrapTokenDiscovery{ - APIServerEndpoints: []string{"2001:1234::1:15"}, + APIServerEndpoint: "2001:1234::1:15", }, }, }, @@ -673,13 +673,13 @@ func TestKubeletVersionCheck(t *testing.T) { switch { case warnings != nil && !tc.expectWarnings: - t.Errorf("KubeletVersionCheck: unexpected warnings for kubelet version %q and kubernetes version %q. Warnings: %v", tc.kubeletVersion, tc.k8sVersion, warnings) + t.Errorf("KubeletVersionCheck: unexpected warnings for kubelet version %q and Kubernetes version %q. Warnings: %v", tc.kubeletVersion, tc.k8sVersion, warnings) case warnings == nil && tc.expectWarnings: - t.Errorf("KubeletVersionCheck: expected warnings for kubelet version %q and kubernetes version %q but got nothing", tc.kubeletVersion, tc.k8sVersion) + t.Errorf("KubeletVersionCheck: expected warnings for kubelet version %q and Kubernetes version %q but got nothing", tc.kubeletVersion, tc.k8sVersion) case errors != nil && !tc.expectErrors: - t.Errorf("KubeletVersionCheck: unexpected errors for kubelet version %q and kubernetes version %q. errors: %v", tc.kubeletVersion, tc.k8sVersion, errors) + t.Errorf("KubeletVersionCheck: unexpected errors for kubelet version %q and Kubernetes version %q. errors: %v", tc.kubeletVersion, tc.k8sVersion, errors) case errors == nil && tc.expectErrors: - t.Errorf("KubeletVersionCheck: expected errors for kubelet version %q and kubernetes version %q but got nothing", tc.kubeletVersion, tc.k8sVersion) + t.Errorf("KubeletVersionCheck: expected errors for kubelet version %q and Kubernetes version %q but got nothing", tc.kubeletVersion, tc.k8sVersion) } } diff --git a/cmd/kubeadm/app/util/BUILD b/cmd/kubeadm/app/util/BUILD index 2d64651ee55ba..80aa1a8081da9 100644 --- a/cmd/kubeadm/app/util/BUILD +++ b/cmd/kubeadm/app/util/BUILD @@ -36,6 +36,7 @@ go_library( "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library", "//vendor/github.com/ghodss/yaml:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", ], ) @@ -62,6 +63,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -82,6 +84,7 @@ filegroup( "//cmd/kubeadm/app/util/dryrun:all-srcs", "//cmd/kubeadm/app/util/etcd:all-srcs", "//cmd/kubeadm/app/util/kubeconfig:all-srcs", + "//cmd/kubeadm/app/util/pkiutil:all-srcs", "//cmd/kubeadm/app/util/pubkeypin:all-srcs", "//cmd/kubeadm/app/util/runtime:all-srcs", "//cmd/kubeadm/app/util/staticpod:all-srcs", diff --git a/cmd/kubeadm/app/util/apiclient/BUILD b/cmd/kubeadm/app/util/apiclient/BUILD index 6afb368d01a09..17342168e1328 100644 --- a/cmd/kubeadm/app/util/apiclient/BUILD +++ b/cmd/kubeadm/app/util/apiclient/BUILD @@ -41,6 +41,7 @@ go_library( "//staging/src/k8s.io/client-go/rest:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/util/apiclient/clientbacked_dryrun.go b/cmd/kubeadm/app/util/apiclient/clientbacked_dryrun.go index 3841a715fce23..a79080ee45d7a 100644 --- a/cmd/kubeadm/app/util/apiclient/clientbacked_dryrun.go +++ b/cmd/kubeadm/app/util/apiclient/clientbacked_dryrun.go @@ -29,6 +29,8 @@ import ( "k8s.io/client-go/rest" core "k8s.io/client-go/testing" "k8s.io/client-go/tools/clientcmd" + + "github.com/pkg/errors" ) // ClientBackedDryRunGetter implements the DryRunGetter interface for use in NewDryRunClient() and proxies all GET and LIST requests to the backing API server reachable via rest.Config @@ -61,11 +63,11 @@ func NewClientBackedDryRunGetter(config *rest.Config) (*ClientBackedDryRunGetter func NewClientBackedDryRunGetterFromKubeconfig(file string) (*ClientBackedDryRunGetter, error) { config, err := clientcmd.LoadFromFile(file) if err != nil { - return nil, fmt.Errorf("failed to load kubeconfig: %v", err) + return nil, errors.Wrap(err, "failed to load kubeconfig") } clientConfig, err := clientcmd.NewDefaultClientConfig(*config, &clientcmd.ConfigOverrides{}).ClientConfig() if err != nil { - return nil, fmt.Errorf("failed to create API client configuration from kubeconfig: %v", err) + return nil, errors.Wrap(err, "failed to create API client configuration from kubeconfig") } return NewClientBackedDryRunGetter(clientConfig) } diff --git a/cmd/kubeadm/app/util/apiclient/dryrunclient.go b/cmd/kubeadm/app/util/apiclient/dryrunclient.go index 4d4a52d706a0e..a6c31e5fbe288 100644 --- a/cmd/kubeadm/app/util/apiclient/dryrunclient.go +++ b/cmd/kubeadm/app/util/apiclient/dryrunclient.go @@ -23,6 +23,7 @@ import ( "io" "strings" + "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" clientset "k8s.io/client-go/kubernetes" @@ -114,7 +115,7 @@ func NewDryRunClientWithOpts(opts DryRunClientOptions) clientset.Interface { getAction, ok := action.(core.GetAction) if !ok { // something's wrong, we can't handle this event - return true, nil, fmt.Errorf("can't cast get reactor event action object to GetAction interface") + return true, nil, errors.New("can't cast get reactor event action object to GetAction interface") } handled, obj, err := opts.Getter.HandleGetAction(getAction) @@ -139,7 +140,7 @@ func NewDryRunClientWithOpts(opts DryRunClientOptions) clientset.Interface { listAction, ok := action.(core.ListAction) if !ok { // something's wrong, we can't handle this event - return true, nil, fmt.Errorf("can't cast list reactor event action object to ListAction interface") + return true, nil, errors.New("can't cast list reactor event action object to ListAction interface") } handled, objs, err := opts.Getter.HandleListAction(listAction) diff --git a/cmd/kubeadm/app/util/apiclient/idempotency.go b/cmd/kubeadm/app/util/apiclient/idempotency.go index bc36f65ebdd4e..b5475080f15e1 100644 --- a/cmd/kubeadm/app/util/apiclient/idempotency.go +++ b/cmd/kubeadm/app/util/apiclient/idempotency.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" + "github.com/pkg/errors" apps "k8s.io/api/apps/v1" "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" @@ -40,11 +41,11 @@ import ( func CreateOrUpdateConfigMap(client clientset.Interface, cm *v1.ConfigMap) error { if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(cm); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create configmap: %v", err) + return errors.Wrap(err, "unable to create configmap") } if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Update(cm); err != nil { - return fmt.Errorf("unable to update configmap: %v", err) + return errors.Wrap(err, "unable to update configmap") } } return nil @@ -58,7 +59,7 @@ func CreateOrRetainConfigMap(client clientset.Interface, cm *v1.ConfigMap, confi } if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(cm); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create configmap: %v", err) + return errors.Wrap(err, "unable to create configmap") } } } @@ -69,11 +70,11 @@ func CreateOrRetainConfigMap(client clientset.Interface, cm *v1.ConfigMap, confi func CreateOrUpdateSecret(client clientset.Interface, secret *v1.Secret) error { if _, err := client.CoreV1().Secrets(secret.ObjectMeta.Namespace).Create(secret); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create secret: %v", err) + return errors.Wrap(err, "unable to create secret") } if _, err := client.CoreV1().Secrets(secret.ObjectMeta.Namespace).Update(secret); err != nil { - return fmt.Errorf("unable to update secret: %v", err) + return errors.Wrap(err, "unable to update secret") } } return nil @@ -85,7 +86,7 @@ func CreateOrUpdateServiceAccount(client clientset.Interface, sa *v1.ServiceAcco // Note: We don't run .Update here afterwards as that's probably not required // Only thing that could be updated is annotations/labels in .metadata, but we don't use that currently if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create serviceaccount: %v", err) + return errors.Wrap(err, "unable to create serviceaccount") } } return nil @@ -95,11 +96,11 @@ func CreateOrUpdateServiceAccount(client clientset.Interface, sa *v1.ServiceAcco func CreateOrUpdateDeployment(client clientset.Interface, deploy *apps.Deployment) error { if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Create(deploy); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create deployment: %v", err) + return errors.Wrap(err, "unable to create deployment") } if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Update(deploy); err != nil { - return fmt.Errorf("unable to update deployment: %v", err) + return errors.Wrap(err, "unable to update deployment") } } return nil @@ -109,11 +110,11 @@ func CreateOrUpdateDeployment(client clientset.Interface, deploy *apps.Deploymen func CreateOrUpdateDaemonSet(client clientset.Interface, ds *apps.DaemonSet) error { if _, err := client.AppsV1().DaemonSets(ds.ObjectMeta.Namespace).Create(ds); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create daemonset: %v", err) + return errors.Wrap(err, "unable to create daemonset") } if _, err := client.AppsV1().DaemonSets(ds.ObjectMeta.Namespace).Update(ds); err != nil { - return fmt.Errorf("unable to update daemonset: %v", err) + return errors.Wrap(err, "unable to update daemonset") } } return nil @@ -141,11 +142,11 @@ func DeleteDeploymentForeground(client clientset.Interface, namespace, name stri func CreateOrUpdateRole(client clientset.Interface, role *rbac.Role) error { if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Create(role); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create RBAC role: %v", err) + return errors.Wrap(err, "unable to create RBAC role") } if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Update(role); err != nil { - return fmt.Errorf("unable to update RBAC role: %v", err) + return errors.Wrap(err, "unable to update RBAC role") } } return nil @@ -155,11 +156,11 @@ func CreateOrUpdateRole(client clientset.Interface, role *rbac.Role) error { func CreateOrUpdateRoleBinding(client clientset.Interface, roleBinding *rbac.RoleBinding) error { if _, err := client.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Create(roleBinding); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create RBAC rolebinding: %v", err) + return errors.Wrap(err, "unable to create RBAC rolebinding") } if _, err := client.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Update(roleBinding); err != nil { - return fmt.Errorf("unable to update RBAC rolebinding: %v", err) + return errors.Wrap(err, "unable to update RBAC rolebinding") } } return nil @@ -169,11 +170,11 @@ func CreateOrUpdateRoleBinding(client clientset.Interface, roleBinding *rbac.Rol func CreateOrUpdateClusterRole(client clientset.Interface, clusterRole *rbac.ClusterRole) error { if _, err := client.RbacV1().ClusterRoles().Create(clusterRole); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create RBAC clusterrole: %v", err) + return errors.Wrap(err, "unable to create RBAC clusterrole") } if _, err := client.RbacV1().ClusterRoles().Update(clusterRole); err != nil { - return fmt.Errorf("unable to update RBAC clusterrole: %v", err) + return errors.Wrap(err, "unable to update RBAC clusterrole") } } return nil @@ -183,11 +184,11 @@ func CreateOrUpdateClusterRole(client clientset.Interface, clusterRole *rbac.Clu func CreateOrUpdateClusterRoleBinding(client clientset.Interface, clusterRoleBinding *rbac.ClusterRoleBinding) error { if _, err := client.RbacV1().ClusterRoleBindings().Create(clusterRoleBinding); err != nil { if !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("unable to create RBAC clusterrolebinding: %v", err) + return errors.Wrap(err, "unable to create RBAC clusterrolebinding") } if _, err := client.RbacV1().ClusterRoleBindings().Update(clusterRoleBinding); err != nil { - return fmt.Errorf("unable to update RBAC clusterrolebinding: %v", err) + return errors.Wrap(err, "unable to update RBAC clusterrolebinding") } } return nil diff --git a/cmd/kubeadm/app/util/apiclient/init_dryrun.go b/cmd/kubeadm/app/util/apiclient/init_dryrun.go index f4da31f8c3cf4..96566a56e350e 100644 --- a/cmd/kubeadm/app/util/apiclient/init_dryrun.go +++ b/cmd/kubeadm/app/util/apiclient/init_dryrun.go @@ -17,10 +17,11 @@ limitations under the License. package apiclient import ( - "fmt" "net" "strings" + "github.com/pkg/errors" + "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -79,7 +80,7 @@ func (idr *InitDryRunGetter) HandleListAction(action core.ListAction) (bool, run } // handleKubernetesService returns a faked Kubernetes service in order to be able to continue running kubeadm init. -// The kube-dns addon code GETs the kubernetes service in order to extract the service subnet +// The kube-dns addon code GETs the Kubernetes service in order to extract the service subnet func (idr *InitDryRunGetter) handleKubernetesService(action core.GetAction) (bool, runtime.Object, error) { if action.GetName() != "kubernetes" || action.GetNamespace() != metav1.NamespaceDefault || action.GetResource().Resource != "services" { // We can't handle this event @@ -88,12 +89,12 @@ func (idr *InitDryRunGetter) handleKubernetesService(action core.GetAction) (boo _, svcSubnet, err := net.ParseCIDR(idr.serviceSubnet) if err != nil { - return true, nil, fmt.Errorf("error parsing CIDR %q: %v", idr.serviceSubnet, err) + return true, nil, errors.Wrapf(err, "error parsing CIDR %q", idr.serviceSubnet) } internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(svcSubnet, 1) if err != nil { - return true, nil, fmt.Errorf("unable to get first IP address from the given CIDR (%s): %v", svcSubnet.String(), err) + return true, nil, errors.Wrapf(err, "unable to get first IP address from the given CIDR (%s)", svcSubnet.String()) } // The only used field of this Service object is the ClusterIP, which kube-dns uses to calculate its own IP diff --git a/cmd/kubeadm/app/util/apiclient/wait.go b/cmd/kubeadm/app/util/apiclient/wait.go index bb14533603839..b05d7b3dc035f 100644 --- a/cmd/kubeadm/app/util/apiclient/wait.go +++ b/cmd/kubeadm/app/util/apiclient/wait.go @@ -1,5 +1,5 @@ /* -Copyright 2017 The Kubernetes Authors. +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. @@ -22,6 +22,7 @@ import ( "net/http" "time" + "github.com/pkg/errors" "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -29,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/cmd/kubeadm/app/constants" + kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) @@ -49,6 +51,8 @@ type Waiter interface { WaitForStaticPodControlPlaneHashes(nodeName string) (map[string]string, error) // WaitForHealthyKubelet blocks until the kubelet /healthz endpoint returns 'ok' WaitForHealthyKubelet(initalTimeout time.Duration, healthzEndpoint string) error + // WaitForKubeletAndFunc is a wrapper for WaitForHealthyKubelet that also blocks for a function + WaitForKubeletAndFunc(f func() error) error // SetTimeout adjusts the timeout to the specified duration SetTimeout(timeout time.Duration) } @@ -131,24 +135,46 @@ func (w *KubeWaiter) WaitForPodToDisappear(podName string) error { // WaitForHealthyKubelet blocks until the kubelet /healthz endpoint returns 'ok' func (w *KubeWaiter) WaitForHealthyKubelet(initalTimeout time.Duration, healthzEndpoint string) error { time.Sleep(initalTimeout) + fmt.Printf("[kubelet-check] Initial timeout of %v passed.\n", initalTimeout) return TryRunCommand(func() error { client := &http.Client{Transport: netutil.SetOldTransportDefaults(&http.Transport{})} resp, err := client.Get(healthzEndpoint) if err != nil { - fmt.Printf("[kubelet-check] It seems like the kubelet isn't running or healthy.\n") + fmt.Println("[kubelet-check] It seems like the kubelet isn't running or healthy.") fmt.Printf("[kubelet-check] The HTTP call equal to 'curl -sSL %s' failed with error: %v.\n", healthzEndpoint, err) return err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - fmt.Printf("[kubelet-check] It seems like the kubelet isn't running or healthy.") + fmt.Println("[kubelet-check] It seems like the kubelet isn't running or healthy.") fmt.Printf("[kubelet-check] The HTTP call equal to 'curl -sSL %s' returned HTTP code %d\n", healthzEndpoint, resp.StatusCode) - return fmt.Errorf("the kubelet healthz endpoint is unhealthy") + return errors.New("the kubelet healthz endpoint is unhealthy") } return nil }, 5) // a failureThreshold of five means waiting for a total of 155 seconds } +// WaitForKubeletAndFunc waits primarily for the function f to execute, even though it might take some time. If that takes a long time, and the kubelet +// /healthz continuously are unhealthy, kubeadm will error out after a period of exponential backoff +func (w *KubeWaiter) WaitForKubeletAndFunc(f func() error) error { + errorChan := make(chan error) + + go func(errC chan error, waiter Waiter) { + if err := waiter.WaitForHealthyKubelet(40*time.Second, fmt.Sprintf("http://localhost:%d/healthz", kubeadmconstants.KubeletHealthzPort)); err != nil { + errC <- err + } + }(errorChan, w) + + go func(errC chan error, waiter Waiter) { + // This main goroutine sends whatever the f function returns (error or not) to the channel + // This in order to continue on success (nil error), or just fail if the function returns an error + errC <- f() + }(errorChan, w) + + // This call is blocking until one of the goroutines sends to errorChan + return <-errorChan +} + // SetTimeout adjusts the timeout to the specified duration func (w *KubeWaiter) SetTimeout(timeout time.Duration) { w.timeout = timeout diff --git a/cmd/kubeadm/app/util/arguments.go b/cmd/kubeadm/app/util/arguments.go index 60dfb6eac870c..619aba2eb4c34 100644 --- a/cmd/kubeadm/app/util/arguments.go +++ b/cmd/kubeadm/app/util/arguments.go @@ -20,6 +20,8 @@ import ( "fmt" "sort" "strings" + + "github.com/pkg/errors" ) // BuildArgumentListFromMap takes two string-string maps, one with the base arguments and one @@ -89,10 +91,10 @@ func ReplaceArgument(command []string, argMutateFunc func(map[string]string) map // parseArgument parses the argument "--foo=bar" to "foo" and "bar" func parseArgument(arg string) (string, string, error) { if !strings.HasPrefix(arg, "--") { - return "", "", fmt.Errorf("the argument should start with '--'") + return "", "", errors.New("the argument should start with '--'") } if !strings.Contains(arg, "=") { - return "", "", fmt.Errorf("the argument should have a '=' between the flag and the value") + return "", "", errors.New("the argument should have a '=' between the flag and the value") } // Remove the starting -- arg = strings.TrimPrefix(arg, "--") @@ -101,10 +103,10 @@ func parseArgument(arg string) (string, string, error) { // Make sure both a key and value is present if len(keyvalSlice) != 2 { - return "", "", fmt.Errorf("the argument must have both a key and a value") + return "", "", errors.New("the argument must have both a key and a value") } if len(keyvalSlice[0]) == 0 { - return "", "", fmt.Errorf("the argument must have a key") + return "", "", errors.New("the argument must have a key") } return keyvalSlice[0], keyvalSlice[1], nil diff --git a/cmd/kubeadm/app/util/audit/BUILD b/cmd/kubeadm/app/util/audit/BUILD index 142ab776624b9..7fb4d41d5e313 100644 --- a/cmd/kubeadm/app/util/audit/BUILD +++ b/cmd/kubeadm/app/util/audit/BUILD @@ -12,6 +12,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/audit/install:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/audit/v1:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/util/audit/utils.go b/cmd/kubeadm/app/util/audit/utils.go index dbe446aae22e1..cb0f0ee643071 100644 --- a/cmd/kubeadm/app/util/audit/utils.go +++ b/cmd/kubeadm/app/util/audit/utils.go @@ -17,11 +17,12 @@ limitations under the License. package audit import ( - "fmt" "io/ioutil" "os" "path/filepath" + "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -49,7 +50,7 @@ func CreateDefaultAuditLogPolicy(policyFile string) error { func writePolicyToDisk(policyFile string, policy *auditv1.Policy) error { // creates target folder if not already exists if err := os.MkdirAll(filepath.Dir(policyFile), 0700); err != nil { - return fmt.Errorf("failed to create directory %q: %v", filepath.Dir(policyFile), err) + return errors.Wrapf(err, "failed to create directory %q: ", filepath.Dir(policyFile)) } scheme := runtime.NewScheme() @@ -62,11 +63,11 @@ func writePolicyToDisk(policyFile string, policy *auditv1.Policy) error { serialized, err := util.MarshalToYamlForCodecs(policy, auditv1.SchemeGroupVersion, codecs) if err != nil { - return fmt.Errorf("failed to marshal audit policy to YAML: %v", err) + return errors.Wrap(err, "failed to marshal audit policy to YAML") } if err := ioutil.WriteFile(policyFile, serialized, 0600); err != nil { - return fmt.Errorf("failed to write audit policy to %v: %v", policyFile, err) + return errors.Wrapf(err, "failed to write audit policy to %v: ", policyFile) } return nil diff --git a/cmd/kubeadm/app/util/cgroupdriver.go b/cmd/kubeadm/app/util/cgroupdriver.go index b03a299126e06..2d1e45068980a 100644 --- a/cmd/kubeadm/app/util/cgroupdriver.go +++ b/cmd/kubeadm/app/util/cgroupdriver.go @@ -17,9 +17,10 @@ limitations under the License. package util import ( - "fmt" "strings" + "github.com/pkg/errors" + utilsexec "k8s.io/utils/exec" ) @@ -39,7 +40,7 @@ func GetCgroupDriverDocker(execer utilsexec.Interface) (string, error) { func validateCgroupDriver(driver string) error { if driver != "cgroupfs" && driver != "systemd" { - return fmt.Errorf("unknown cgroup driver %q", driver) + return errors.Errorf("unknown cgroup driver %q", driver) } return nil } @@ -51,7 +52,7 @@ func validateCgroupDriver(driver string) error { func callDockerInfo(execer utilsexec.Interface) (string, error) { out, err := execer.Command("docker", "info").Output() if err != nil { - return "", fmt.Errorf("cannot execute 'docker info': %v", err) + return "", errors.Wrap(err, "cannot execute 'docker info'") } return string(out), nil } @@ -71,5 +72,5 @@ func getCgroupDriverFromDockerInfo(info string) (string, error) { } return driver, nil } - return "", fmt.Errorf("cgroup driver is not defined in 'docker info'") + return "", errors.New("cgroup driver is not defined in 'docker info'") } diff --git a/cmd/kubeadm/app/util/chroot_unix.go b/cmd/kubeadm/app/util/chroot_unix.go index 098184e5e5556..b8b83c373f344 100644 --- a/cmd/kubeadm/app/util/chroot_unix.go +++ b/cmd/kubeadm/app/util/chroot_unix.go @@ -19,7 +19,7 @@ limitations under the License. package util import ( - "fmt" + "github.com/pkg/errors" "os" "path/filepath" "syscall" @@ -30,11 +30,11 @@ import ( // `rootfs` func Chroot(rootfs string) error { if err := syscall.Chroot(rootfs); err != nil { - return fmt.Errorf("unable to chroot to %s: %v", rootfs, err) + return errors.Wrapf(err, "unable to chroot to %s", rootfs) } root := filepath.FromSlash("/") if err := os.Chdir(root); err != nil { - return fmt.Errorf("unable to chdir to %s: %v", root, err) + return errors.Wrapf(err, "unable to chdir to %s", root) } return nil } diff --git a/cmd/kubeadm/app/util/chroot_windows.go b/cmd/kubeadm/app/util/chroot_windows.go index 1ddf41dc98fce..b7e434e08289e 100644 --- a/cmd/kubeadm/app/util/chroot_windows.go +++ b/cmd/kubeadm/app/util/chroot_windows.go @@ -19,12 +19,12 @@ limitations under the License. package util import ( - "fmt" + "github.com/pkg/errors" ) // Chroot chroot()s to the new path. // NB: All file paths after this call are effectively relative to // `rootfs` func Chroot(rootfs string) error { - return fmt.Errorf("chroot is not implemented on Windows") + return errors.New("chroot is not implemented on Windows") } diff --git a/cmd/kubeadm/app/util/config/BUILD b/cmd/kubeadm/app/util/config/BUILD index b16d3636c0c87..531318c4835b7 100644 --- a/cmd/kubeadm/app/util/config/BUILD +++ b/cmd/kubeadm/app/util/config/BUILD @@ -25,6 +25,7 @@ go_library( "//cmd/kubeadm/app/util:go_default_library", "//pkg/util/node:go_default_library", "//staging/src/k8s.io/api/core/v1: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:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", @@ -35,6 +36,7 @@ go_library( "//staging/src/k8s.io/client-go/util/cert:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/util/config/cluster.go b/cmd/kubeadm/app/util/config/cluster.go index b42207a72a679..e1b95f5e0b2fc 100644 --- a/cmd/kubeadm/app/util/config/cluster.go +++ b/cmd/kubeadm/app/util/config/cluster.go @@ -18,13 +18,16 @@ package config import ( "crypto/x509" - "errors" "fmt" "io" "io/ioutil" "path/filepath" "strings" + "github.com/pkg/errors" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/version" @@ -99,7 +102,7 @@ func getInitConfigurationFromCluster(kubeconfigDir string, client clientset.Inte // gets ClusterConfiguration from kubeadm-config clusterConfigurationData, ok := configMap.Data[constants.ClusterConfigurationConfigMapKey] if !ok { - return nil, fmt.Errorf("unexpected error when reading kubeadm-config ConfigMap: %s key value pair missing", constants.ClusterConfigurationConfigMapKey) + return nil, errors.Errorf("unexpected error when reading kubeadm-config ConfigMap: %s key value pair missing", constants.ClusterConfigurationConfigMapKey) } if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(clusterConfigurationData), &initcfg.ClusterConfiguration); err != nil { return nil, err @@ -142,7 +145,7 @@ func getNodeRegistration(kubeconfigDir string, client clientset.Interface, nodeR criSocket, ok := node.ObjectMeta.Annotations[constants.AnnotationKubeadmCRISocket] if !ok { - return fmt.Errorf("Node %s doesn't have %s annotation", nodeName, constants.AnnotationKubeadmCRISocket) + return errors.Errorf("node %s doesn't have %s annotation", nodeName, constants.AnnotationKubeadmCRISocket) } // returns the nodeRegistration attributes @@ -182,7 +185,7 @@ func getNodeNameFromKubeletConfig(kubeconfigDir string) (string, error) { return "", err } } else { - return "", errors.New("Invalid kubelet.conf. X509 certificate expected") + return "", errors.New("invalid kubelet.conf. X509 certificate expected") } // We are only putting one certificate in the certificate pem file, so it's safe to just pick the first one @@ -196,12 +199,8 @@ func getNodeNameFromKubeletConfig(kubeconfigDir string) (string, error) { // getAPIEndpoint returns the APIEndpoint for the current node func getAPIEndpoint(data map[string]string, nodeName string, apiEndpoint *kubeadmapi.APIEndpoint) error { // gets the ClusterStatus from kubeadm-config - clusterStatusData, ok := data[constants.ClusterStatusConfigMapKey] - if !ok { - return fmt.Errorf("unexpected error when reading kubeadm-config ConfigMap: %s key value pair missing", constants.ClusterStatusConfigMapKey) - } - clusterStatus := &kubeadmapi.ClusterStatus{} - if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(clusterStatusData), clusterStatus); err != nil { + clusterStatus, err := unmarshalClusterStatus(data) + if err != nil { return err } @@ -227,8 +226,39 @@ func getComponentConfigs(client clientset.Interface, clusterConfiguration *kubea } if ok := registration.SetToInternalConfig(obj, clusterConfiguration); !ok { - return fmt.Errorf("couldn't save componentconfig value for kind %q", string(kind)) + return errors.Errorf("couldn't save componentconfig value for kind %q", string(kind)) } } return nil } + +// GetClusterStatus returns the kubeadm cluster status read from the kubeadm-config ConfigMap +func GetClusterStatus(client clientset.Interface) (*kubeadmapi.ClusterStatus, error) { + configMap, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(constants.KubeadmConfigConfigMap, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + return &kubeadmapi.ClusterStatus{}, nil + } + if err != nil { + return nil, err + } + + clusterStatus, err := unmarshalClusterStatus(configMap.Data) + if err != nil { + return nil, err + } + + return clusterStatus, nil +} + +func unmarshalClusterStatus(data map[string]string) (*kubeadmapi.ClusterStatus, error) { + clusterStatusData, ok := data[constants.ClusterStatusConfigMapKey] + if !ok { + return nil, errors.Errorf("unexpected error when reading kubeadm-config ConfigMap: %s key value pair missing", constants.ClusterStatusConfigMapKey) + } + clusterStatus := &kubeadmapi.ClusterStatus{} + if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(clusterStatusData), clusterStatus); err != nil { + return nil, err + } + + return clusterStatus, nil +} diff --git a/cmd/kubeadm/app/util/config/cluster_test.go b/cmd/kubeadm/app/util/config/cluster_test.go index ba8c7841c901c..ecc6bae766152 100644 --- a/cmd/kubeadm/app/util/config/cluster_test.go +++ b/cmd/kubeadm/app/util/config/cluster_test.go @@ -770,6 +770,94 @@ func TestGetInitConfigurationFromCluster(t *testing.T) { } } +func TestGetGetClusterStatus(t *testing.T) { + var tests = []struct { + name string + configMaps []fakeConfigMap + expectedEndpoints int + expectedError bool + }{ + { + name: "invalid missing config map", + expectedEndpoints: 0, + }, + { + name: "valid v1beta1", + configMaps: []fakeConfigMap{ + { + name: kubeadmconstants.KubeadmConfigConfigMap, + data: map[string]string{ + kubeadmconstants.ClusterStatusConfigMapKey: string(cfgFiles["ClusterStatus_v1beta1"]), + }, + }, + }, + expectedEndpoints: 1, + }, + { + name: "valid v1alpha3", + configMaps: []fakeConfigMap{ + { + name: kubeadmconstants.KubeadmConfigConfigMap, + data: map[string]string{ + kubeadmconstants.ClusterStatusConfigMapKey: string(cfgFiles["ClusterStatus_v1alpha3"]), + }, + }, + }, + expectedEndpoints: 1, + }, + { + name: "invalid missing ClusterStatusConfigMapKey in the config map", + configMaps: []fakeConfigMap{ + { + name: kubeadmconstants.KubeadmConfigConfigMap, + data: map[string]string{}, + }, + }, + expectedError: true, + }, + { + name: "invalid wrong value in the config map", + configMaps: []fakeConfigMap{ + { + name: kubeadmconstants.KubeadmConfigConfigMap, + data: map[string]string{ + kubeadmconstants.ClusterStatusConfigMapKey: "not a kubeadm type", + }, + }, + }, + expectedError: true, + }, + } + + for _, rt := range tests { + t.Run(rt.name, func(t *testing.T) { + client := clientsetfake.NewSimpleClientset() + + for _, c := range rt.configMaps { + err := c.create(client) + if err != nil { + t.Errorf("couldn't create ConfigMap %s", c.name) + return + } + } + + clusterStatus, err := GetClusterStatus(client) + if rt.expectedError != (err != nil) { + t.Errorf("unexpected return err from GetClusterStatus: %v", err) + return + } + if rt.expectedError { + return + } + + // Test expected values in clusterStatus + if len(clusterStatus.APIEndpoints) != rt.expectedEndpoints { + t.Errorf("unexpected ClusterStatus return value") + } + }) + } +} + type fakeConfigMap struct { name string data map[string]string diff --git a/cmd/kubeadm/app/util/config/common.go b/cmd/kubeadm/app/util/config/common.go index fd9cdc954d25c..3dc712f7b06c0 100644 --- a/cmd/kubeadm/app/util/config/common.go +++ b/cmd/kubeadm/app/util/config/common.go @@ -17,12 +17,12 @@ limitations under the License. package config import ( - "fmt" "io/ioutil" "net" "strings" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" netutil "k8s.io/apimachinery/pkg/util/net" @@ -53,7 +53,7 @@ func AnyConfigFileAndDefaultsToInternal(cfgPath string) (runtime.Object, error) if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) { return JoinConfigFileAndDefaultsToInternalConfig(cfgPath, &kubeadmapiv1beta1.JoinConfiguration{}) } - return nil, fmt.Errorf("didn't recognize types with GroupVersionKind: %v", gvks) + return nil, errors.Errorf("didn't recognize types with GroupVersionKind: %v", gvks) } // MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a InitConfiguration or ClusterConfiguration, some extra logic is run @@ -89,7 +89,7 @@ func DetectUnsupportedVersion(b []byte) error { knownKinds := map[string]bool{} for _, gvk := range gvks { if useKubeadmVersion := oldKnownAPIVersions[gvk.GroupVersion().String()]; len(useKubeadmVersion) != 0 { - return fmt.Errorf("your configuration file uses an old API spec: %q. Please use kubeadm %s instead and run 'kubeadm config migrate --old-config old.yaml --new-config new.yaml', which will write the new, similar spec using a newer API version.", gvk.GroupVersion().String(), useKubeadmVersion) + return errors.Errorf("your configuration file uses an old API spec: %q. Please use kubeadm %s instead and run 'kubeadm config migrate --old-config old.yaml --new-config new.yaml', which will write the new, similar spec using a newer API version.", gvk.GroupVersion().String(), useKubeadmVersion) } knownKinds[gvk.Kind] = true } @@ -128,10 +128,10 @@ func NormalizeKubernetesVersion(cfg *kubeadmapi.ClusterConfiguration) error { // Parse the given kubernetes version and make sure it's higher than the lowest supported k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion) if err != nil { - return fmt.Errorf("couldn't parse kubernetes version %q: %v", cfg.KubernetesVersion, err) + return errors.Wrapf(err, "couldn't parse Kubernetes version %q", cfg.KubernetesVersion) } if k8sVersion.LessThan(constants.MinimumControlPlaneVersion) { - return fmt.Errorf("this version of kubeadm only supports deploying clusters with the control plane version >= %s. Current version: %s", constants.MinimumControlPlaneVersion.String(), cfg.KubernetesVersion) + return errors.Errorf("this version of kubeadm only supports deploying clusters with the control plane version >= %s. Current version: %s", constants.MinimumControlPlaneVersion.String(), cfg.KubernetesVersion) } return nil } @@ -152,10 +152,10 @@ func LowercaseSANs(sans []string) { func VerifyAPIServerBindAddress(address string) error { ip := net.ParseIP(address) if ip == nil { - return fmt.Errorf("cannot parse IP address: %s", address) + return errors.Errorf("cannot parse IP address: %s", address) } if !ip.IsGlobalUnicast() { - return fmt.Errorf("cannot use %q as the bind address for the API Server", address) + return errors.Errorf("cannot use %q as the bind address for the API Server", address) } return nil } @@ -169,7 +169,7 @@ func ChooseAPIServerBindAddress(bindAddress net.IP) (net.IP, error) { glog.Warningf("WARNING: could not obtain a bind address for the API Server: %v; using: %s", err, constants.DefaultAPIServerBindAddress) defaultIP := net.ParseIP(constants.DefaultAPIServerBindAddress) if defaultIP == nil { - return nil, fmt.Errorf("cannot parse default IP address: %s", constants.DefaultAPIServerBindAddress) + return nil, errors.Errorf("cannot parse default IP address: %s", constants.DefaultAPIServerBindAddress) } return defaultIP, nil } diff --git a/cmd/kubeadm/app/util/config/common_test.go b/cmd/kubeadm/app/util/config/common_test.go index 358cc483984ca..2aa4c44de379f 100644 --- a/cmd/kubeadm/app/util/config/common_test.go +++ b/cmd/kubeadm/app/util/config/common_test.go @@ -228,19 +228,21 @@ func TestLowercaseSANs(t *testing.T) { t.Run(test.name, func(t *testing.T) { cfg := &kubeadmapiv1beta1.InitConfiguration{ ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{ - APIServerCertSANs: test.in, + APIServer: kubeadmapiv1beta1.APIServer{ + CertSANs: test.in, + }, }, } - LowercaseSANs(cfg.APIServerCertSANs) + LowercaseSANs(cfg.APIServer.CertSANs) - if len(cfg.APIServerCertSANs) != len(test.out) { - t.Fatalf("expected %d elements, got %d", len(test.out), len(cfg.APIServerCertSANs)) + if len(cfg.APIServer.CertSANs) != len(test.out) { + t.Fatalf("expected %d elements, got %d", len(test.out), len(cfg.APIServer.CertSANs)) } for i, expected := range test.out { - if cfg.APIServerCertSANs[i] != expected { - t.Errorf("expected element %d to be %q, got %q", i, expected, cfg.APIServerCertSANs[i]) + if cfg.APIServer.CertSANs[i] != expected { + t.Errorf("expected element %d to be %q, got %q", i, expected, cfg.APIServer.CertSANs[i]) } } }) diff --git a/cmd/kubeadm/app/util/config/initconfiguration.go b/cmd/kubeadm/app/util/config/initconfiguration.go index 4fbf1fdbfebcf..4592a32c041a4 100644 --- a/cmd/kubeadm/app/util/config/initconfiguration.go +++ b/cmd/kubeadm/app/util/config/initconfiguration.go @@ -26,6 +26,7 @@ import ( "strconv" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" @@ -72,7 +73,7 @@ func SetBootstrapTokensDynamicDefaults(cfg *[]kubeadmapi.BootstrapToken) error { tokenStr, err := bootstraputil.GenerateBootstrapToken() if err != nil { - return fmt.Errorf("couldn't generate random token: %v", err) + return errors.Wrap(err, "couldn't generate random token") } token, err := kubeadmapi.NewBootstrapTokenString(tokenStr) if err != nil { @@ -105,7 +106,7 @@ func SetAPIEndpointDynamicDefaults(cfg *kubeadmapi.APIEndpoint) error { // validate cfg.API.AdvertiseAddress. addressIP := net.ParseIP(cfg.AdvertiseAddress) if addressIP == nil && cfg.AdvertiseAddress != "" { - return fmt.Errorf("couldn't use \"%s\" as \"apiserver-advertise-address\", must be ipv4 or ipv6 address", cfg.AdvertiseAddress) + return errors.Errorf("couldn't use \"%s\" as \"apiserver-advertise-address\", must be ipv4 or ipv6 address", cfg.AdvertiseAddress) } // This is the same logic as the API Server uses, except that if no interface is found the address is set to 0.0.0.0, which is invalid and cannot be used // for bootstrapping a cluster. @@ -149,7 +150,7 @@ func SetClusterDynamicDefaults(cfg *kubeadmapi.ClusterConfiguration, advertiseAd } // Downcase SANs. Some domain names (like ELBs) have capitals in them. - LowercaseSANs(cfg.APIServerCertSANs) + LowercaseSANs(cfg.APIServer.CertSANs) return nil } @@ -168,7 +169,7 @@ func ConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg * b, err := ioutil.ReadFile(cfgPath) if err != nil { - return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err) + return nil, errors.Wrapf(err, "unable to read config from %q ", cfgPath) } internalcfg, err = BytesToInternalConfig(b) if err != nil { @@ -249,7 +250,7 @@ func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) { // Enforce that InitConfiguration and/or ClusterConfiguration has to exist among the YAML documents if initcfg == nil && clustercfg == nil { - return nil, fmt.Errorf("no InitConfiguration or ClusterConfiguration kind was found in the YAML file") + return nil, errors.New("no InitConfiguration or ClusterConfiguration kind was found in the YAML file") } // If InitConfiguration wasn't given, default it by creating an external struct instance, default it and convert into the internal type @@ -270,7 +271,7 @@ func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) { registration, found := componentconfigs.Known[kind] if found { if ok := registration.SetToInternalConfig(obj, &initcfg.ClusterConfiguration); !ok { - return nil, fmt.Errorf("couldn't save componentconfig value for kind %q", string(kind)) + return nil, errors.Errorf("couldn't save componentconfig value for kind %q", string(kind)) } } else { // This should never happen in practice @@ -334,7 +335,7 @@ func MarshalClusterConfigurationToBytes(clustercfg *kubeadmapi.ClusterConfigurat defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg) // Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference if !ok { - return []byte{}, fmt.Errorf("couldn't create a default componentconfig object") + return []byte{}, errors.New("couldn't create a default componentconfig object") } // If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it diff --git a/cmd/kubeadm/app/util/config/joinconfiguration.go b/cmd/kubeadm/app/util/config/joinconfiguration.go index b4b414d06a668..278fa81c87e12 100644 --- a/cmd/kubeadm/app/util/config/joinconfiguration.go +++ b/cmd/kubeadm/app/util/config/joinconfiguration.go @@ -17,17 +17,17 @@ limitations under the License. package config import ( - "fmt" "io/ioutil" - "k8s.io/kubernetes/cmd/kubeadm/app/constants" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" + "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" ) @@ -45,7 +45,11 @@ func SetJoinDynamicDefaults(cfg *kubeadmapi.JoinConfiguration) error { return nil } -// JoinConfigFileAndDefaultsToInternalConfig +// JoinConfigFileAndDefaultsToInternalConfig takes a path to a config file and a versioned configuration that can serve as the default config +// If cfgPath is specified, defaultversionedcfg will always get overridden. Otherwise, the default config (often populated by flags) will be used. +// Then the external, versioned configuration is defaulted and converted to the internal type. +// Right thereafter, the configuration is defaulted again with dynamic values (like IP addresses of a machine, etc) +// Lastly, the internal config is validated and returned. func JoinConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg *kubeadmapiv1beta1.JoinConfiguration) (*kubeadmapi.JoinConfiguration, error) { internalcfg := &kubeadmapi.JoinConfiguration{} @@ -56,7 +60,7 @@ func JoinConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedc b, err := ioutil.ReadFile(cfgPath) if err != nil { - return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err) + return nil, errors.Wrapf(err, "unable to read config from %q ", cfgPath) } if err := DetectUnsupportedVersion(b); err != nil { @@ -76,7 +80,7 @@ func JoinConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedc } if len(joinBytes) == 0 { - return nil, fmt.Errorf("no %s found in config file %q", constants.JoinConfigurationKind, cfgPath) + return nil, errors.Errorf("no %s found in config file %q", constants.JoinConfigurationKind, cfgPath) } if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), joinBytes, internalcfg); err != nil { diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/master/internal.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/master/internal.yaml index 9ad61455ddc48..a94f6b1b84157 100644 --- a/cmd/kubeadm/app/util/config/testdata/conversion/master/internal.yaml +++ b/cmd/kubeadm/app/util/config/testdata/conversion/master/internal.yaml @@ -1,10 +1,22 @@ APIEndpoint: AdvertiseAddress: 192.168.2.2 BindPort: 6443 -APIServerCertSANs: null -APIServerExtraArgs: - authorization-mode: Node,RBAC,Webhook -APIServerExtraVolumes: null +APIServer: + CertSANs: null + ExtraArgs: + authorization-mode: Node,RBAC,Webhook + ExtraVolumes: + - HostPath: /host/read-only + MountPath: /mount/read-only + Name: ReadOnlyVolume + PathType: "" + ReadOnly: true + - HostPath: /host/writable + MountPath: /mount/writable + Name: WritableVolume + PathType: "" + ReadOnly: false + TimeoutForControlPlane: 4m0s AuditPolicyConfiguration: LogDir: /var/log/kubernetes/audit LogMaxAge: 2 @@ -159,8 +171,9 @@ ComponentConfigs: TLSPrivateKeyFile: "" VolumeStatsAggPeriod: 1m0s ControlPlaneEndpoint: "" -ControllerManagerExtraArgs: null -ControllerManagerExtraVolumes: null +ControllerManager: + ExtraArgs: null + ExtraVolumes: null Etcd: External: null Local: @@ -183,6 +196,7 @@ NodeRegistration: Taints: - effect: NoSchedule key: node-role.kubernetes.io/master -SchedulerExtraArgs: null -SchedulerExtraVolumes: null +Scheduler: + ExtraArgs: null + ExtraVolumes: null UnifiedControlPlaneImage: "" diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml index 4c9aadbd33657..9a47c24bd951c 100644 --- a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml +++ b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml @@ -20,6 +20,14 @@ nodeRegistration: --- apiServerExtraArgs: authorization-mode: Node,RBAC,Webhook +apiServerExtraVolumes: +- hostPath: /host/read-only + mountPath: /mount/read-only + name: ReadOnlyVolume +- hostPath: /host/writable + mountPath: /mount/writable + name: WritableVolume + writable: true apiVersion: kubeadm.k8s.io/v1alpha3 auditPolicy: logDir: /var/log/kubernetes/audit diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1beta1.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1beta1.yaml index 7f7106fedee2c..c15ea283fea52 100644 --- a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1beta1.yaml +++ b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1beta1.yaml @@ -18,8 +18,18 @@ nodeRegistration: - effect: NoSchedule key: node-role.kubernetes.io/master --- -apiServerExtraArgs: - authorization-mode: Node,RBAC,Webhook +apiServer: + extraArgs: + authorization-mode: Node,RBAC,Webhook + extraVolumes: + - hostPath: /host/read-only + mountPath: /mount/read-only + name: ReadOnlyVolume + readOnly: true + - hostPath: /host/writable + mountPath: /mount/writable + name: WritableVolume + timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta1 auditPolicy: logDir: /var/log/kubernetes/audit @@ -28,6 +38,7 @@ auditPolicy: certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controlPlaneEndpoint: "" +controllerManager: {} etcd: local: dataDir: /var/lib/etcd @@ -39,6 +50,7 @@ networking: dnsDomain: cluster.local podSubnet: "" serviceSubnet: 10.96.0.0/12 +scheduler: {} unifiedControlPlaneImage: "" --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/node/internal.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/node/internal.yaml index 9eaa51dd9a9b5..a1c6d4c537cd4 100644 --- a/cmd/kubeadm/app/util/config/testdata/conversion/node/internal.yaml +++ b/cmd/kubeadm/app/util/config/testdata/conversion/node/internal.yaml @@ -6,8 +6,7 @@ ClusterName: kubernetes ControlPlane: false Discovery: BootstrapToken: - APIServerEndpoints: - - kube-apiserver:6443 + APIServerEndpoint: kube-apiserver:6443 CACertHashes: null Token: abcdef.0123456789abcdef UnsafeSkipCAVerification: true diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/node/v1beta1.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/node/v1beta1.yaml index 064e9a9f9d2af..a6b1b45a8f679 100644 --- a/cmd/kubeadm/app/util/config/testdata/conversion/node/v1beta1.yaml +++ b/cmd/kubeadm/app/util/config/testdata/conversion/node/v1beta1.yaml @@ -6,8 +6,7 @@ caCertPath: /etc/kubernetes/pki/ca.crt clusterName: kubernetes discovery: bootstrapToken: - apiServerEndpoints: - - kube-apiserver:6443 + apiServerEndpoint: kube-apiserver:6443 token: abcdef.0123456789abcdef unsafeSkipCAVerification: true timeout: 5m0s diff --git a/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml b/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml index d9ff908f36c3c..520c9dfb99371 100644 --- a/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml +++ b/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml @@ -18,6 +18,8 @@ nodeRegistration: - effect: NoSchedule key: node-role.kubernetes.io/master --- +apiServer: + timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta1 auditPolicy: logDir: /var/log/kubernetes/audit @@ -26,6 +28,7 @@ auditPolicy: certificatesDir: /var/lib/kubernetes/pki clusterName: kubernetes controlPlaneEndpoint: "" +controllerManager: {} etcd: local: dataDir: /var/lib/etcd @@ -37,6 +40,7 @@ networking: dnsDomain: cluster.global podSubnet: 10.148.0.0/16 serviceSubnet: 10.196.0.0/12 +scheduler: {} unifiedControlPlaneImage: "" --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 diff --git a/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml b/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml index 0a18368a35f89..4de98d37a3c2a 100644 --- a/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml +++ b/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml @@ -6,8 +6,7 @@ caCertPath: /etc/kubernetes/pki/ca.crt clusterName: kubernetes discovery: bootstrapToken: - apiServerEndpoints: - - kube-apiserver:6443 + apiServerEndpoint: kube-apiserver:6443 token: abcdef.0123456789abcdef unsafeSkipCAVerification: true timeout: 5m0s diff --git a/cmd/kubeadm/app/util/dryrun/dryrun.go b/cmd/kubeadm/app/util/dryrun/dryrun.go index 7c18df0672a36..4f09f0a0bb148 100644 --- a/cmd/kubeadm/app/util/dryrun/dryrun.go +++ b/cmd/kubeadm/app/util/dryrun/dryrun.go @@ -111,6 +111,11 @@ func (w *Waiter) WaitForHealthyKubelet(_ time.Duration, healthzEndpoint string) return nil } +// WaitForKubeletAndFunc is a wrapper for WaitForHealthyKubelet that also blocks for a function +func (w *Waiter) WaitForKubeletAndFunc(f func() error) error { + return nil +} + // SetTimeout is a no-op; we don't wait in this implementation func (w *Waiter) SetTimeout(_ time.Duration) {} diff --git a/cmd/kubeadm/app/util/endpoint.go b/cmd/kubeadm/app/util/endpoint.go index a092e84d3d054..0f52a0b782af2 100644 --- a/cmd/kubeadm/app/util/endpoint.go +++ b/cmd/kubeadm/app/util/endpoint.go @@ -22,6 +22,8 @@ import ( "net/url" "strconv" + "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/util/validation" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" ) @@ -34,13 +36,13 @@ func GetMasterEndpoint(cfg *kubeadmapi.InitConfiguration) (string, error) { // parse the bind port bindPortString := strconv.Itoa(int(cfg.APIEndpoint.BindPort)) if _, err := ParsePort(bindPortString); err != nil { - return "", fmt.Errorf("invalid value %q given for api.bindPort: %s", cfg.APIEndpoint.BindPort, err) + return "", errors.Wrapf(err, "invalid value %q given for api.bindPort", cfg.APIEndpoint.BindPort) } // parse the AdvertiseAddress var ip = net.ParseIP(cfg.APIEndpoint.AdvertiseAddress) if ip == nil { - return "", fmt.Errorf("invalid value `%s` given for api.advertiseAddress", cfg.APIEndpoint.AdvertiseAddress) + return "", errors.Errorf("invalid value `%s` given for api.advertiseAddress", cfg.APIEndpoint.AdvertiseAddress) } // set the master url using cfg.API.AdvertiseAddress + the cfg.API.BindPort @@ -55,7 +57,7 @@ func GetMasterEndpoint(cfg *kubeadmapi.InitConfiguration) (string, error) { var host, port string var err error if host, port, err = ParseHostPort(cfg.ControlPlaneEndpoint); err != nil { - return "", fmt.Errorf("invalid value %q given for controlPlaneEndpoint: %s", cfg.ControlPlaneEndpoint, err) + return "", errors.Wrapf(err, "invalid value %q given for controlPlaneEndpoint", cfg.ControlPlaneEndpoint) } // if a port is provided within the controlPlaneAddress warn the users we are using it, else use the bindport @@ -93,7 +95,7 @@ func ParseHostPort(hostport string) (string, string, error) { // if port is defined, parse and validate it if port != "" { if _, err := ParsePort(port); err != nil { - return "", "", fmt.Errorf("port must be a valid number between 1 and 65535, inclusive") + return "", "", errors.New("port must be a valid number between 1 and 65535, inclusive") } } @@ -107,7 +109,7 @@ func ParseHostPort(hostport string) (string, string, error) { return host, port, nil } - return "", "", fmt.Errorf("host must be a valid IP address or a valid RFC-1123 DNS subdomain") + return "", "", errors.New("host must be a valid IP address or a valid RFC-1123 DNS subdomain") } // ParsePort parses a string representing a TCP port. @@ -118,5 +120,5 @@ func ParsePort(port string) (int, error) { return portInt, nil } - return 0, fmt.Errorf("port must be a valid number between 1 and 65535, inclusive") + return 0, errors.New("port must be a valid number between 1 and 65535, inclusive") } diff --git a/cmd/kubeadm/app/util/error_test.go b/cmd/kubeadm/app/util/error_test.go index 20c4fdb8fb394..2e19ffa46a2e5 100644 --- a/cmd/kubeadm/app/util/error_test.go +++ b/cmd/kubeadm/app/util/error_test.go @@ -17,7 +17,7 @@ limitations under the License. package util import ( - "fmt" + "github.com/pkg/errors" "testing" ) @@ -36,7 +36,7 @@ func TestCheckErr(t *testing.T) { expected int }{ {nil, 0}, - {fmt.Errorf(""), DefaultErrorExitCode}, + {errors.New(""), DefaultErrorExitCode}, {&pferror{}, PreFlightExitCode}, } @@ -63,14 +63,14 @@ func TestFormatErrMsg(t *testing.T) { }{ { errs: []error{ - fmt.Errorf(errMsg1), - fmt.Errorf(errMsg2), + errors.New(errMsg1), + errors.New(errMsg2), }, expect: "\t- " + errMsg1 + "\n" + "\t- " + errMsg2 + "\n", }, { errs: []error{ - fmt.Errorf(errMsg1), + errors.New(errMsg1), }, expect: "\t- " + errMsg1 + "\n", }, diff --git a/cmd/kubeadm/app/util/etcd/BUILD b/cmd/kubeadm/app/util/etcd/BUILD index 852e914f87f8f..b3792bb4aefdd 100644 --- a/cmd/kubeadm/app/util/etcd/BUILD +++ b/cmd/kubeadm/app/util/etcd/BUILD @@ -8,9 +8,13 @@ go_library( deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", + "//cmd/kubeadm/app/util/config:go_default_library", "//cmd/kubeadm/app/util/staticpod:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//vendor/github.com/coreos/etcd/clientv3:go_default_library", "//vendor/github.com/coreos/etcd/pkg/transport:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/util/etcd/etcd.go b/cmd/kubeadm/app/util/etcd/etcd.go index 4b11bcb42b833..a11bba3cfe0fc 100644 --- a/cmd/kubeadm/app/util/etcd/etcd.go +++ b/cmd/kubeadm/app/util/etcd/etcd.go @@ -26,8 +26,12 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/pkg/transport" + "github.com/golang/glog" + "github.com/pkg/errors" + clientset "k8s.io/client-go/kubernetes" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/cmd/kubeadm/app/util/config" "k8s.io/kubernetes/cmd/kubeadm/app/util/staticpod" ) @@ -39,6 +43,8 @@ type ClusterInterrogator interface { GetVersion() (string, error) HasTLS() bool WaitForClusterAvailable(delay time.Duration, retries int, retryInterval time.Duration) (bool, error) + Sync() error + AddMember(name string, peerAddrs string) ([]Member, error) } // Client provides connection parameters for an etcd cluster @@ -58,7 +64,7 @@ func PodManifestsHaveTLS(ManifestDir string) (bool, error) { etcdPodPath := constants.GetStaticPodFilepath(constants.Etcd, ManifestDir) etcdPod, err := staticpod.ReadStaticPodFromDisk(etcdPodPath) if err != nil { - return false, fmt.Errorf("failed to check if etcd pod implements TLS: %v", err) + return false, errors.Wrap(err, "failed to check if etcd pod implements TLS") } tlsFlags := []string{ @@ -111,7 +117,7 @@ func New(endpoints []string, ca, cert, key string) (*Client, error) { func NewFromStaticPod(endpoints []string, manifestDir string, certificatesDir string) (*Client, error) { hasTLS, err := PodManifestsHaveTLS(manifestDir) if err != nil { - return nil, fmt.Errorf("could not read manifests from: %s, error: %v", manifestDir, err) + return nil, errors.Wrapf(err, "could not read manifests from: %s, error", manifestDir) } if hasTLS { return New( @@ -124,6 +130,108 @@ func NewFromStaticPod(endpoints []string, manifestDir string, certificatesDir st return New(endpoints, "", "", "") } +// NewFromCluster creates an etcd client for the the etcd endpoints defined in the ClusterStatus value stored in +// the kubeadm-config ConfigMap in kube-system namespace. +// Once created, the client synchronizes client's endpoints with the known endpoints from the etcd membership API (reality check). +func NewFromCluster(client clientset.Interface, certificatesDir string) (*Client, error) { + // Gets the cluster status + clusterStatus, err := config.GetClusterStatus(client) + if err != nil { + return nil, err + } + + // Get the list of etcd endpoints from cluster status + endpoints := []string{} + for _, e := range clusterStatus.APIEndpoints { + endpoints = append(endpoints, fmt.Sprintf("https://%s:%d", e.AdvertiseAddress, constants.EtcdListenClientPort)) + } + glog.V(1).Infof("etcd endpoints read from pods: %s", strings.Join(endpoints, ",")) + + // Creates an etcd client + etcdClient, err := New( + endpoints, + filepath.Join(certificatesDir, constants.EtcdCACertName), + filepath.Join(certificatesDir, constants.EtcdHealthcheckClientCertName), + filepath.Join(certificatesDir, constants.EtcdHealthcheckClientKeyName), + ) + if err != nil { + return nil, err + } + + // synchronizes client's endpoints with the known endpoints from the etcd membership. + err = etcdClient.Sync() + if err != nil { + return nil, err + } + + return etcdClient, nil +} + +// Sync synchronizes client's endpoints with the known endpoints from the etcd membership. +func (c Client) Sync() error { + cli, err := clientv3.New(clientv3.Config{ + Endpoints: c.Endpoints, + DialTimeout: 20 * time.Second, + TLS: c.TLS, + }) + if err != nil { + return err + } + defer cli.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + err = cli.Sync(ctx) + cancel() + if err != nil { + return err + } + glog.V(1).Infof("etcd endpoints read from etcd: %s", strings.Join(cli.Endpoints(), ",")) + + c.Endpoints = cli.Endpoints() + return nil +} + +// Member struct defines an etcd member; it is used for avoiding to spread github.com/coreos/etcd dependency +// across kubeadm codebase +type Member struct { + Name string + PeerURL string +} + +// AddMember notifies an existing etcd cluster that a new member is joining +func (c Client) AddMember(name string, peerAddrs string) ([]Member, error) { + cli, err := clientv3.New(clientv3.Config{ + Endpoints: c.Endpoints, + DialTimeout: 20 * time.Second, + TLS: c.TLS, + }) + if err != nil { + return nil, err + } + defer cli.Close() + + // Adds a new member to the cluster + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + resp, err := cli.MemberAdd(ctx, []string{peerAddrs}) + cancel() + if err != nil { + return nil, err + } + + // Returns the updated list of etcd members + ret := []Member{} + for _, m := range resp.Members { + // fixes the entry for the joining member (that doesn't have a name set in the initialCluster returned by etcd) + if m.Name == "" { + ret = append(ret, Member{Name: name, PeerURL: m.PeerURLs[0]}) + } else { + ret = append(ret, Member{Name: m.Name, PeerURL: m.PeerURLs[0]}) + } + } + + return ret, nil +} + // GetVersion returns the etcd version of the cluster. // An error is returned if the version of all endpoints do not match func (c Client) GetVersion() (string, error) { @@ -135,12 +243,12 @@ func (c Client) GetVersion() (string, error) { } for _, v := range versions { if clusterVersion != "" && clusterVersion != v { - return "", fmt.Errorf("etcd cluster contains endpoints with mismatched versions: %v", versions) + return "", errors.Errorf("etcd cluster contains endpoints with mismatched versions: %v", versions) } clusterVersion = v } if clusterVersion == "" { - return "", fmt.Errorf("could not determine cluster etcd version") + return "", errors.New("could not determine cluster etcd version") } return clusterVersion, nil } @@ -215,7 +323,7 @@ func (c Client) WaitForClusterAvailable(delay time.Duration, retries int, retryI } return resp, nil } - return false, fmt.Errorf("timeout waiting for etcd cluster to be available") + return false, errors.New("timeout waiting for etcd cluster to be available") } // CheckConfigurationIsHA returns true if the given InitConfiguration etcd block appears to be an HA configuration. diff --git a/cmd/kubeadm/app/util/kubeconfig/BUILD b/cmd/kubeadm/app/util/kubeconfig/BUILD index c4c332c02883e..934cea1339bea 100644 --- a/cmd/kubeadm/app/util/kubeconfig/BUILD +++ b/cmd/kubeadm/app/util/kubeconfig/BUILD @@ -20,6 +20,7 @@ go_library( "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go b/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go index 1e5216d3819d7..867f4e67fb771 100644 --- a/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go +++ b/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go @@ -22,6 +22,8 @@ import ( clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + + "github.com/pkg/errors" ) // CreateBasic creates a basic, general KubeConfig object that then can be extended @@ -66,11 +68,11 @@ func CreateWithToken(serverURL, clusterName, userName string, caCert []byte, tok return config } -// ClientSetFromFile returns a ready-to-use client from a KubeConfig file +// ClientSetFromFile returns a ready-to-use client from a kubeconfig file func ClientSetFromFile(path string) (*clientset.Clientset, error) { config, err := clientcmd.LoadFromFile(path) if err != nil { - return nil, fmt.Errorf("failed to load admin kubeconfig [%v]", err) + return nil, errors.Wrap(err, "failed to load admin kubeconfig") } return ToClientSet(config) } @@ -79,12 +81,12 @@ func ClientSetFromFile(path string) (*clientset.Clientset, error) { func ToClientSet(config *clientcmdapi.Config) (*clientset.Clientset, error) { clientConfig, err := clientcmd.NewDefaultClientConfig(*config, &clientcmd.ConfigOverrides{}).ClientConfig() if err != nil { - return nil, fmt.Errorf("failed to create API client configuration from kubeconfig: %v", err) + return nil, errors.Wrap(err, "failed to create API client configuration from kubeconfig") } client, err := clientset.NewForConfig(clientConfig) if err != nil { - return nil, fmt.Errorf("failed to create API client: %v", err) + return nil, errors.Wrap(err, "failed to create API client") } return client, nil } diff --git a/cmd/kubeadm/app/util/marshal.go b/cmd/kubeadm/app/util/marshal.go index 5f74d4b8dd7b1..950855f945919 100644 --- a/cmd/kubeadm/app/util/marshal.go +++ b/cmd/kubeadm/app/util/marshal.go @@ -19,10 +19,10 @@ package util import ( "bufio" "bytes" - "fmt" "io" "github.com/ghodss/yaml" + pkgerrors "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -45,7 +45,7 @@ func MarshalToYamlForCodecs(obj runtime.Object, gv schema.GroupVersion, codecs s mediaType := "application/yaml" info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType) if !ok { - return []byte{}, fmt.Errorf("unsupported media type %q", mediaType) + return []byte{}, pkgerrors.Errorf("unsupported media type %q", mediaType) } encoder := codecs.EncoderForVersion(info.Serializer, gv) @@ -64,7 +64,7 @@ func UnmarshalFromYamlForCodecs(buffer []byte, gv schema.GroupVersion, codecs se mediaType := "application/yaml" info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType) if !ok { - return nil, fmt.Errorf("unsupported media type %q", mediaType) + return nil, pkgerrors.Errorf("unsupported media type %q", mediaType) } decoder := codecs.DecoderToVersion(info.Serializer, gv) @@ -97,12 +97,12 @@ func SplitYAMLDocuments(yamlBytes []byte) (map[schema.GroupVersionKind][]byte, e } // Require TypeMeta information to be present if len(typeMetaInfo.APIVersion) == 0 || len(typeMetaInfo.Kind) == 0 { - errs = append(errs, fmt.Errorf("invalid configuration: kind and apiVersion is mandatory information that needs to be specified in all YAML documents")) + errs = append(errs, pkgerrors.New("invalid configuration: kind and apiVersion is mandatory information that needs to be specified in all YAML documents")) continue } // Check whether the kind has been registered before. If it has, throw an error if known := knownKinds[typeMetaInfo.Kind]; known { - errs = append(errs, fmt.Errorf("invalid configuration: kind %q is specified twice in YAML file", typeMetaInfo.Kind)) + errs = append(errs, pkgerrors.Errorf("invalid configuration: kind %q is specified twice in YAML file", typeMetaInfo.Kind)) continue } knownKinds[typeMetaInfo.Kind] = true @@ -110,7 +110,7 @@ func SplitYAMLDocuments(yamlBytes []byte) (map[schema.GroupVersionKind][]byte, e // Build a GroupVersionKind object from the deserialized TypeMeta object gv, err := schema.ParseGroupVersion(typeMetaInfo.APIVersion) if err != nil { - errs = append(errs, fmt.Errorf("unable to parse apiVersion: %v", err)) + errs = append(errs, pkgerrors.Wrap(err, "unable to parse apiVersion")) continue } gvk := gv.WithKind(typeMetaInfo.Kind) diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/BUILD b/cmd/kubeadm/app/util/pkiutil/BUILD similarity index 89% rename from cmd/kubeadm/app/phases/certs/pkiutil/BUILD rename to cmd/kubeadm/app/util/pkiutil/BUILD index e8c69f55dfde1..08debfbecf2e9 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/BUILD +++ b/cmd/kubeadm/app/util/pkiutil/BUILD @@ -19,7 +19,7 @@ go_test( go_library( name = "go_default_library", srcs = ["pki_helpers.go"], - importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil", + importpath = "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil", deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", @@ -27,6 +27,7 @@ go_library( "//pkg/registry/core/service/ipallocator:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go b/cmd/kubeadm/app/util/pkiutil/pki_helpers.go similarity index 79% rename from cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go rename to cmd/kubeadm/app/util/pkiutil/pki_helpers.go index 25aac11659828..7872ccb72ace3 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go +++ b/cmd/kubeadm/app/util/pkiutil/pki_helpers.go @@ -25,6 +25,8 @@ import ( "path/filepath" "time" + "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/util/validation" certutil "k8s.io/client-go/util/cert" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" @@ -37,12 +39,12 @@ import ( func NewCertificateAuthority(config *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) { key, err := certutil.NewPrivateKey() if err != nil { - return nil, nil, fmt.Errorf("unable to create private key [%v]", err) + return nil, nil, errors.Wrap(err, "unable to create private key") } cert, err := certutil.NewSelfSignedCACert(*config, key) if err != nil { - return nil, nil, fmt.Errorf("unable to create self-signed certificate [%v]", err) + return nil, nil, errors.Wrap(err, "unable to create self-signed certificate") } return cert, key, nil @@ -52,12 +54,12 @@ func NewCertificateAuthority(config *certutil.Config) (*x509.Certificate, *rsa.P func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) { key, err := certutil.NewPrivateKey() if err != nil { - return nil, nil, fmt.Errorf("unable to create private key [%v]", err) + return nil, nil, errors.Wrap(err, "unable to create private key") } cert, err := certutil.NewSignedCert(*config, key, caCert, caKey) if err != nil { - return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err) + return nil, nil, errors.Wrap(err, "unable to sign certificate") } return cert, key, nil @@ -85,12 +87,12 @@ func WriteCertAndKey(pkiPath string, name string, cert *x509.Certificate, key *r // WriteCert stores the given certificate at the given location func WriteCert(pkiPath, name string, cert *x509.Certificate) error { if cert == nil { - return fmt.Errorf("certificate cannot be nil when writing to file") + return errors.New("certificate cannot be nil when writing to file") } certificatePath := pathForCert(pkiPath, name) if err := certutil.WriteCert(certificatePath, certutil.EncodeCertPEM(cert)); err != nil { - return fmt.Errorf("unable to write certificate to file %q: [%v]", certificatePath, err) + return errors.Wrapf(err, "unable to write certificate to file %s", certificatePath) } return nil @@ -99,12 +101,12 @@ func WriteCert(pkiPath, name string, cert *x509.Certificate) error { // WriteKey stores the given key at the given location func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error { if key == nil { - return fmt.Errorf("private key cannot be nil when writing to file") + return errors.New("private key cannot be nil when writing to file") } privateKeyPath := pathForKey(pkiPath, name) if err := certutil.WriteKey(privateKeyPath, certutil.EncodePrivateKeyPEM(key)); err != nil { - return fmt.Errorf("unable to write private key to file %q: [%v]", privateKeyPath, err) + return errors.Wrapf(err, "unable to write private key to file %s", privateKeyPath) } return nil @@ -113,7 +115,7 @@ func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error { // WritePublicKey stores the given public key at the given location func WritePublicKey(pkiPath, name string, key *rsa.PublicKey) error { if key == nil { - return fmt.Errorf("public key cannot be nil when writing to file") + return errors.New("public key cannot be nil when writing to file") } publicKeyBytes, err := certutil.EncodePublicKeyPEM(key) @@ -122,7 +124,7 @@ func WritePublicKey(pkiPath, name string, key *rsa.PublicKey) error { } publicKeyPath := pathForPublicKey(pkiPath, name) if err := certutil.WriteKey(publicKeyPath, publicKeyBytes); err != nil { - return fmt.Errorf("unable to write public key to file %q: [%v]", publicKeyPath, err) + return errors.Wrapf(err, "unable to write public key to file %s", publicKeyPath) } return nil @@ -164,7 +166,7 @@ func TryLoadCertFromDisk(pkiPath, name string) (*x509.Certificate, error) { certs, err := certutil.CertsFromFile(certificatePath) if err != nil { - return nil, fmt.Errorf("couldn't load the certificate file %s: %v", certificatePath, err) + return nil, errors.Wrapf(err, "couldn't load the certificate file %s", certificatePath) } // We are only putting one certificate in the certificate pem file, so it's safe to just pick the first one @@ -174,10 +176,10 @@ func TryLoadCertFromDisk(pkiPath, name string) (*x509.Certificate, error) { // Check so that the certificate is valid now now := time.Now() if now.Before(cert.NotBefore) { - return nil, fmt.Errorf("the certificate is not valid yet") + return nil, errors.New("the certificate is not valid yet") } if now.After(cert.NotAfter) { - return nil, fmt.Errorf("the certificate has expired") + return nil, errors.New("the certificate has expired") } return cert, nil @@ -190,7 +192,7 @@ func TryLoadKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, error) { // Parse the private key from a file privKey, err := certutil.PrivateKeyFromFile(privateKeyPath) if err != nil { - return nil, fmt.Errorf("couldn't load the private key file %s: %v", privateKeyPath, err) + return nil, errors.Wrapf(err, "couldn't load the private key file %s", privateKeyPath) } // Allow RSA format only @@ -199,7 +201,7 @@ func TryLoadKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, error) { case *rsa.PrivateKey: key = k default: - return nil, fmt.Errorf("the private key file %s isn't in RSA format", privateKeyPath) + return nil, errors.Errorf("the private key file %s isn't in RSA format", privateKeyPath) } return key, nil @@ -212,7 +214,7 @@ func TryLoadPrivatePublicKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, *rs // Parse the private key from a file privKey, err := certutil.PrivateKeyFromFile(privateKeyPath) if err != nil { - return nil, nil, fmt.Errorf("couldn't load the private key file %s: %v", privateKeyPath, err) + return nil, nil, errors.Wrapf(err, "couldn't load the private key file %s", privateKeyPath) } publicKeyPath := pathForPublicKey(pkiPath, name) @@ -220,13 +222,13 @@ func TryLoadPrivatePublicKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, *rs // Parse the public key from a file pubKeys, err := certutil.PublicKeysFromFile(publicKeyPath) if err != nil { - return nil, nil, fmt.Errorf("couldn't load the public key file %s: %v", publicKeyPath, err) + return nil, nil, errors.Wrapf(err, "couldn't load the public key file %s", publicKeyPath) } // Allow RSA format only k, ok := privKey.(*rsa.PrivateKey) if !ok { - return nil, nil, fmt.Errorf("the private key file %s isn't in RSA format", privateKeyPath) + return nil, nil, errors.Errorf("the private key file %s isn't in RSA format", privateKeyPath) } p := pubKeys[0].(*rsa.PublicKey) @@ -256,18 +258,19 @@ func GetAPIServerAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames // advertise address advertiseAddress := net.ParseIP(cfg.APIEndpoint.AdvertiseAddress) if advertiseAddress == nil { - return nil, fmt.Errorf("error parsing APIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address", cfg.APIEndpoint.AdvertiseAddress) + return nil, errors.Errorf("error parsing APIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address", + cfg.APIEndpoint.AdvertiseAddress) } // internal IP address for the API server _, svcSubnet, err := net.ParseCIDR(cfg.Networking.ServiceSubnet) if err != nil { - return nil, fmt.Errorf("error parsing CIDR %q: %v", cfg.Networking.ServiceSubnet, err) + return nil, errors.Wrapf(err, "error parsing CIDR %q", cfg.Networking.ServiceSubnet) } internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(svcSubnet, 1) if err != nil { - return nil, fmt.Errorf("unable to get first IP address from the given CIDR (%s): %v", svcSubnet.String(), err) + return nil, errors.Wrapf(err, "unable to get first IP address from the given CIDR (%s)", svcSubnet.String()) } // create AltNames with defaults DNSNames/IPs @@ -294,24 +297,29 @@ func GetAPIServerAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames altNames.DNSNames = append(altNames.DNSNames, host) } } else { - return nil, fmt.Errorf("error parsing cluster controlPlaneEndpoint %q: %s", cfg.ControlPlaneEndpoint, err) + return nil, errors.Wrapf(err, "error parsing cluster controlPlaneEndpoint %q", cfg.ControlPlaneEndpoint) } } - appendSANsToAltNames(altNames, cfg.APIServerCertSANs, kubeadmconstants.APIServerCertName) + appendSANsToAltNames(altNames, cfg.APIServer.CertSANs, kubeadmconstants.APIServerCertName) return altNames, nil } // GetEtcdAltNames builds an AltNames object for generating the etcd server certificate. -// `localhost` is included in the SAN since this is the interface the etcd static pod listens on. -// Hostname and `API.AdvertiseAddress` are excluded since etcd does not listen on this interface by default. +// `advertise address` and localhost are included in the SAN since this is the interfaces the etcd static pod listens on. // The user can override the listen address with `Etcd.ExtraArgs` and add SANs with `Etcd.ServerCertSANs`. func GetEtcdAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames, error) { + // advertise address + advertiseAddress := net.ParseIP(cfg.APIEndpoint.AdvertiseAddress) + if advertiseAddress == nil { + return nil, errors.Errorf("error parsing APIEndpoint AdvertiseAddress %q: is not a valid textual representation of an IP address", cfg.APIEndpoint.AdvertiseAddress) + } + // create AltNames with defaults DNSNames/IPs altNames := &certutil.AltNames{ DNSNames: []string{cfg.NodeRegistration.Name, "localhost"}, - IPs: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback}, + IPs: []net.IP{advertiseAddress, net.IPv4(127, 0, 0, 1), net.IPv6loopback}, } if cfg.Etcd.Local != nil { @@ -322,14 +330,14 @@ func GetEtcdAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames, err } // GetEtcdPeerAltNames builds an AltNames object for generating the etcd peer certificate. -// `localhost` is excluded from the SAN since etcd will not refer to itself as a peer. -// Hostname and `API.AdvertiseAddress` are included if the user chooses to promote the single node etcd cluster into a multi-node one. +// Hostname and `API.AdvertiseAddress` are included if the user chooses to promote the single node etcd cluster into a multi-node one (stacked etcd). // The user can override the listen address with `Etcd.ExtraArgs` and add SANs with `Etcd.PeerCertSANs`. func GetEtcdPeerAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames, error) { // advertise address advertiseAddress := net.ParseIP(cfg.APIEndpoint.AdvertiseAddress) if advertiseAddress == nil { - return nil, fmt.Errorf("error parsing APIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address", cfg.APIEndpoint.AdvertiseAddress) + return nil, errors.Errorf("error parsing APIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address", + cfg.APIEndpoint.AdvertiseAddress) } // create AltNames with defaults DNSNames/IPs diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go b/cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go similarity index 95% rename from cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go rename to cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go index 3fc3eee091be3..5905796b3ca9c 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go +++ b/cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go @@ -450,7 +450,9 @@ func TestGetAPIServerAltNames(t *testing.T) { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ ControlPlaneEndpoint: "api.k8s.io:6443", Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + APIServer: kubeadmapi.APIServer{ + CertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + }, }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, }, @@ -464,7 +466,9 @@ func TestGetAPIServerAltNames(t *testing.T) { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ ControlPlaneEndpoint: "4.5.6.7:6443", Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + APIServer: kubeadmapi.APIServer{ + CertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + }, }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, }, @@ -513,6 +517,12 @@ func TestGetEtcdAltNames(t *testing.T) { proxy := "user-etcd-proxy" proxyIP := "10.10.10.100" cfg := &kubeadmapi.InitConfiguration{ + APIEndpoint: kubeadmapi.APIEndpoint{ + AdvertiseAddress: "1.2.3.4", + }, + NodeRegistration: kubeadmapi.NodeRegistrationOptions{ + Name: "myNode", + }, ClusterConfiguration: kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ @@ -532,7 +542,7 @@ func TestGetEtcdAltNames(t *testing.T) { t.Fatalf("failed calling GetEtcdAltNames: %v", err) } - expectedDNSNames := []string{"localhost", proxy} + expectedDNSNames := []string{"myNode", "localhost", proxy} for _, DNSName := range expectedDNSNames { found := false for _, val := range altNames.DNSNames { @@ -547,7 +557,7 @@ func TestGetEtcdAltNames(t *testing.T) { } } - expectedIPAddresses := []string{"127.0.0.1", net.IPv6loopback.String(), proxyIP} + expectedIPAddresses := []string{"1.2.3.4", "127.0.0.1", net.IPv6loopback.String(), proxyIP} for _, IPAddress := range expectedIPAddresses { found := false for _, val := range altNames.IPs { diff --git a/cmd/kubeadm/app/util/pubkeypin/BUILD b/cmd/kubeadm/app/util/pubkeypin/BUILD index 36eab6deda585..65b88d8d9fe73 100644 --- a/cmd/kubeadm/app/util/pubkeypin/BUILD +++ b/cmd/kubeadm/app/util/pubkeypin/BUILD @@ -16,6 +16,7 @@ go_library( name = "go_default_library", srcs = ["pubkeypin.go"], importpath = "k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin", + deps = ["//vendor/github.com/pkg/errors:go_default_library"], ) filegroup( diff --git a/cmd/kubeadm/app/util/pubkeypin/pubkeypin.go b/cmd/kubeadm/app/util/pubkeypin/pubkeypin.go index 1766e95755525..16f74dee32970 100644 --- a/cmd/kubeadm/app/util/pubkeypin/pubkeypin.go +++ b/cmd/kubeadm/app/util/pubkeypin/pubkeypin.go @@ -22,8 +22,9 @@ import ( "crypto/sha256" "crypto/x509" "encoding/hex" - "fmt" "strings" + + "github.com/pkg/errors" ) const ( @@ -46,7 +47,7 @@ func (s *Set) Allow(pubKeyHashes ...string) error { for _, pubKeyHash := range pubKeyHashes { parts := strings.Split(pubKeyHash, ":") if len(parts) != 2 { - return fmt.Errorf("invalid public key hash, expected \"format:value\"") + return errors.New("invalid public key hash, expected \"format:value\"") } format, value := parts[0], parts[1] @@ -54,7 +55,7 @@ func (s *Set) Allow(pubKeyHashes ...string) error { case "sha256": return s.allowSHA256(value) default: - return fmt.Errorf("unknown hash format %q", format) + return errors.Errorf("unknown hash format %q", format) } } return nil @@ -65,7 +66,7 @@ func (s *Set) Check(certificate *x509.Certificate) error { if s.checkSHA256(certificate) { return nil } - return fmt.Errorf("public key %s not pinned", Hash(certificate)) + return errors.Errorf("public key %s not pinned", Hash(certificate)) } // Empty returns true if the Set contains no pinned public keys. @@ -86,7 +87,7 @@ func (s *Set) allowSHA256(hash string) error { // validate that the hash is the right length to be a full SHA-256 hash hashLength := hex.DecodedLen(len(hash)) if hashLength != sha256.Size { - return fmt.Errorf("expected a %d byte SHA-256 hash, found %d bytes", sha256.Size, hashLength) + return errors.Errorf("expected a %d byte SHA-256 hash, found %d bytes", sha256.Size, hashLength) } // validate that the hash is valid hex diff --git a/cmd/kubeadm/app/util/runtime/BUILD b/cmd/kubeadm/app/util/runtime/BUILD index 76770acfb2b5e..04ddf1dbe975b 100644 --- a/cmd/kubeadm/app/util/runtime/BUILD +++ b/cmd/kubeadm/app/util/runtime/BUILD @@ -8,6 +8,7 @@ go_library( deps = [ "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", ], ) @@ -18,6 +19,7 @@ go_test( embed = [":go_default_library"], deps = [ "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", "//vendor/k8s.io/utils/exec/testing:go_default_library", ], diff --git a/cmd/kubeadm/app/util/runtime/runtime.go b/cmd/kubeadm/app/util/runtime/runtime.go index 84d55e3d4ca7e..2b5915b307e10 100644 --- a/cmd/kubeadm/app/util/runtime/runtime.go +++ b/cmd/kubeadm/app/util/runtime/runtime.go @@ -17,11 +17,12 @@ limitations under the License. package util import ( - "fmt" "path/filepath" goruntime "runtime" "strings" + pkgerrors "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/util/errors" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" utilsexec "k8s.io/utils/exec" @@ -68,7 +69,7 @@ func NewContainerRuntime(execer utilsexec.Interface, criSocket string) (Containe } if _, err := execer.LookPath(toolName); err != nil { - return nil, fmt.Errorf("%s is required for container runtime: %v", toolName, err) + return nil, pkgerrors.Wrapf(err, "%s is required for container runtime", toolName) } return runtime, nil @@ -87,7 +88,7 @@ func (runtime *DockerRuntime) IsDocker() bool { // IsRunning checks if runtime is running func (runtime *CRIRuntime) IsRunning() error { if out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "info").CombinedOutput(); err != nil { - return fmt.Errorf("container runtime is not running: output: %s, error: %v", string(out), err) + return pkgerrors.Wrapf(err, "container runtime is not running: output: %s, error", string(out)) } return nil } @@ -95,7 +96,7 @@ func (runtime *CRIRuntime) IsRunning() error { // IsRunning checks if runtime is running func (runtime *DockerRuntime) IsRunning() error { if out, err := runtime.exec.Command("docker", "info").CombinedOutput(); err != nil { - return fmt.Errorf("container runtime is not running: output: %s, error: %v", string(out), err) + return pkgerrors.Wrapf(err, "container runtime is not running: output: %s, error", string(out)) } return nil } @@ -104,7 +105,7 @@ func (runtime *DockerRuntime) IsRunning() error { func (runtime *CRIRuntime) ListKubeContainers() ([]string, error) { out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "pods", "-q").CombinedOutput() if err != nil { - return nil, fmt.Errorf("output: %s, error: %v", string(out), err) + return nil, pkgerrors.Wrapf(err, "output: %s, error", string(out)) } pods := []string{} for _, pod := range strings.Fields(string(out)) { @@ -126,11 +127,11 @@ func (runtime *CRIRuntime) RemoveContainers(containers []string) error { out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "stopp", container).CombinedOutput() if err != nil { // don't stop on errors, try to remove as many containers as possible - errs = append(errs, fmt.Errorf("failed to stop running pod %s: output: %s, error: %v", container, string(out), err)) + errs = append(errs, pkgerrors.Wrapf(err, "failed to stop running pod %s: output: %s, error", container, string(out))) } else { out, err = runtime.exec.Command("crictl", "-r", runtime.criSocket, "rmp", container).CombinedOutput() if err != nil { - errs = append(errs, fmt.Errorf("failed to remove running container %s: output: %s, error: %v", container, string(out), err)) + errs = append(errs, pkgerrors.Wrapf(err, "failed to remove running container %s: output: %s, error", container, string(out))) } } } @@ -144,7 +145,7 @@ func (runtime *DockerRuntime) RemoveContainers(containers []string) error { out, err := runtime.exec.Command("docker", "rm", "--force", "--volumes", container).CombinedOutput() if err != nil { // don't stop on errors, try to remove as many containers as possible - errs = append(errs, fmt.Errorf("failed to remove running container %s: output: %s, error: %v", container, string(out), err)) + errs = append(errs, pkgerrors.Wrapf(err, "failed to remove running container %s: output: %s, error", container, string(out))) } } return errors.NewAggregate(errs) @@ -154,7 +155,7 @@ func (runtime *DockerRuntime) RemoveContainers(containers []string) error { func (runtime *CRIRuntime) PullImage(image string) error { out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "pull", image).CombinedOutput() if err != nil { - return fmt.Errorf("output: %s, error: %v", string(out), err) + return pkgerrors.Wrapf(err, "output: %s, error", string(out)) } return nil } @@ -163,7 +164,7 @@ func (runtime *CRIRuntime) PullImage(image string) error { func (runtime *DockerRuntime) PullImage(image string) error { out, err := runtime.exec.Command("docker", "pull", image).CombinedOutput() if err != nil { - return fmt.Errorf("output: %s, error: %v", string(out), err) + return pkgerrors.Wrapf(err, "output: %s, error", string(out)) } return nil } diff --git a/cmd/kubeadm/app/util/runtime/runtime_test.go b/cmd/kubeadm/app/util/runtime/runtime_test.go index 65f02e8003b18..2056d99d96a30 100644 --- a/cmd/kubeadm/app/util/runtime/runtime_test.go +++ b/cmd/kubeadm/app/util/runtime/runtime_test.go @@ -17,10 +17,11 @@ limitations under the License. package util import ( - "fmt" "reflect" "testing" + "github.com/pkg/errors" + kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/utils/exec" fakeexec "k8s.io/utils/exec/testing" @@ -31,7 +32,7 @@ func TestNewContainerRuntime(t *testing.T) { LookPathFunc: func(cmd string) (string, error) { return "/usr/bin/crictl", nil }, } execLookPathErr := fakeexec.FakeExec{ - LookPathFunc: func(cmd string) (string, error) { return "", fmt.Errorf("%s not found", cmd) }, + LookPathFunc: func(cmd string) (string, error) { return "", errors.Errorf("%s not found", cmd) }, } cases := []struct { name string diff --git a/cmd/kubeadm/app/util/staticpod/BUILD b/cmd/kubeadm/app/util/staticpod/BUILD index e1c3ed9db2db6..7ffdb4b1b7523 100644 --- a/cmd/kubeadm/app/util/staticpod/BUILD +++ b/cmd/kubeadm/app/util/staticpod/BUILD @@ -35,6 +35,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) diff --git a/cmd/kubeadm/app/util/staticpod/utils.go b/cmd/kubeadm/app/util/staticpod/utils.go index c35d864c0e8a5..0c23d40c245b6 100644 --- a/cmd/kubeadm/app/util/staticpod/utils.go +++ b/cmd/kubeadm/app/util/staticpod/utils.go @@ -26,8 +26,9 @@ import ( "sort" "strings" - "k8s.io/api/core/v1" + "github.com/pkg/errors" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -192,19 +193,19 @@ func WriteStaticPodToDisk(componentName, manifestDir string, pod v1.Pod) error { // creates target folder if not already exists if err := os.MkdirAll(manifestDir, 0700); err != nil { - return fmt.Errorf("failed to create directory %q: %v", manifestDir, err) + return errors.Wrapf(err, "failed to create directory %q", manifestDir) } // writes the pod to disk serialized, err := util.MarshalToYaml(&pod, v1.SchemeGroupVersion) if err != nil { - return fmt.Errorf("failed to marshal manifest for %q to YAML: %v", componentName, err) + return errors.Wrapf(err, "failed to marshal manifest for %q to YAML", componentName) } filename := kubeadmconstants.GetStaticPodFilepath(componentName, manifestDir) if err := ioutil.WriteFile(filename, serialized, 0600); err != nil { - return fmt.Errorf("failed to write static pod manifest file for %q (%q): %v", componentName, filename, err) + return errors.Wrapf(err, "failed to write static pod manifest file for %q (%q)", componentName, filename) } return nil @@ -214,12 +215,12 @@ func WriteStaticPodToDisk(componentName, manifestDir string, pod v1.Pod) error { func ReadStaticPodFromDisk(manifestPath string) (*v1.Pod, error) { buf, err := ioutil.ReadFile(manifestPath) if err != nil { - return &v1.Pod{}, fmt.Errorf("failed to read manifest for %q: %v", manifestPath, err) + return &v1.Pod{}, errors.Wrapf(err, "failed to read manifest for %q", manifestPath) } obj, err := util.UnmarshalFromYaml(buf, v1.SchemeGroupVersion) if err != nil { - return &v1.Pod{}, fmt.Errorf("failed to unmarshal manifest for %q from YAML: %v", manifestPath, err) + return &v1.Pod{}, errors.Errorf("failed to unmarshal manifest for %q from YAML: %v", manifestPath, err) } pod := obj.(*v1.Pod) @@ -245,11 +246,11 @@ func GetProbeAddress(cfg *kubeadmapi.InitConfiguration, componentName string) st return cfg.APIEndpoint.AdvertiseAddress } case componentName == kubeadmconstants.KubeControllerManager: - if addr, exists := cfg.ControllerManagerExtraArgs[kubeControllerManagerAddressArg]; exists { + if addr, exists := cfg.ControllerManager.ExtraArgs[kubeControllerManagerAddressArg]; exists { return addr } case componentName == kubeadmconstants.KubeScheduler: - if addr, exists := cfg.SchedulerExtraArgs[kubeSchedulerAddressArg]; exists { + if addr, exists := cfg.Scheduler.ExtraArgs[kubeSchedulerAddressArg]; exists { return addr } case componentName == kubeadmconstants.Etcd: diff --git a/cmd/kubeadm/app/util/staticpod/utils_test.go b/cmd/kubeadm/app/util/staticpod/utils_test.go index 8b3f87970a015..cd2a3d05707a3 100644 --- a/cmd/kubeadm/app/util/staticpod/utils_test.go +++ b/cmd/kubeadm/app/util/staticpod/utils_test.go @@ -128,7 +128,9 @@ func TestComponentProbe(t *testing.T) { name: "valid IPv4 controller-manager probe", cfg: &kubeadmapi.InitConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - ControllerManagerExtraArgs: map[string]string{"address": "1.2.3.4"}, + ControllerManager: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{"address": "1.2.3.4"}, + }, }, }, component: kubeadmconstants.KubeControllerManager, @@ -141,7 +143,9 @@ func TestComponentProbe(t *testing.T) { name: "valid IPv6 controller-manager probe", cfg: &kubeadmapi.InitConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - ControllerManagerExtraArgs: map[string]string{"address": "2001:db8::1"}, + ControllerManager: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{"address": "2001:db8::1"}, + }, }, }, component: kubeadmconstants.KubeControllerManager, @@ -154,7 +158,9 @@ func TestComponentProbe(t *testing.T) { name: "valid IPv4 scheduler probe", cfg: &kubeadmapi.InitConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - SchedulerExtraArgs: map[string]string{"address": "1.2.3.4"}, + Scheduler: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{"address": "1.2.3.4"}, + }, }, }, component: kubeadmconstants.KubeScheduler, @@ -167,7 +173,9 @@ func TestComponentProbe(t *testing.T) { name: "valid IPv6 scheduler probe", cfg: &kubeadmapi.InitConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - SchedulerExtraArgs: map[string]string{"address": "2001:db8::1"}, + Scheduler: kubeadmapi.ControlPlaneComponent{ + ExtraArgs: map[string]string{"address": "2001:db8::1"}, + }, }, }, component: kubeadmconstants.KubeScheduler, diff --git a/cmd/kubeadm/app/util/system/BUILD b/cmd/kubeadm/app/util/system/BUILD index 7dc1c6a62459d..4435ddfbe864d 100644 --- a/cmd/kubeadm/app/util/system/BUILD +++ b/cmd/kubeadm/app/util/system/BUILD @@ -28,6 +28,7 @@ go_library( "//vendor/github.com/docker/docker/api/types:go_default_library", "//vendor/github.com/docker/docker/client:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", ], ) @@ -44,6 +45,7 @@ go_test( tags = ["e2e"], deps = [ "//vendor/github.com/docker/docker/api/types:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", ], ) diff --git a/cmd/kubeadm/app/util/system/cgroup_validator.go b/cmd/kubeadm/app/util/system/cgroup_validator.go index dec67e8492d61..851884aff698e 100644 --- a/cmd/kubeadm/app/util/system/cgroup_validator.go +++ b/cmd/kubeadm/app/util/system/cgroup_validator.go @@ -18,9 +18,10 @@ package system import ( "bufio" - "fmt" "os" "strings" + + "github.com/pkg/errors" ) var _ Validator = &CgroupsValidator{} @@ -40,7 +41,7 @@ const ( func (c *CgroupsValidator) Validate(spec SysSpec) (error, error) { subsystems, err := c.getCgroupSubsystems() if err != nil { - return nil, fmt.Errorf("failed to get cgroup subsystems: %v", err) + return nil, errors.Wrap(err, "failed to get cgroup subsystems") } return nil, c.validateCgroupSubsystems(spec.Cgroups, subsystems) } @@ -64,7 +65,7 @@ func (c *CgroupsValidator) validateCgroupSubsystems(cgroupSpec, subsystems []str } } if len(missing) > 0 { - return fmt.Errorf("missing cgroups: %s", strings.Join(missing, " ")) + return errors.Errorf("missing cgroups: %s", strings.Join(missing, " ")) } return nil diff --git a/cmd/kubeadm/app/util/system/docker_validator.go b/cmd/kubeadm/app/util/system/docker_validator.go index b31bacd208b70..75ebf8b4330d3 100644 --- a/cmd/kubeadm/app/util/system/docker_validator.go +++ b/cmd/kubeadm/app/util/system/docker_validator.go @@ -18,11 +18,11 @@ package system import ( "context" - "fmt" "regexp" "github.com/docker/docker/api/types" "github.com/docker/docker/client" + "github.com/pkg/errors" ) var _ Validator = &DockerValidator{} @@ -51,11 +51,11 @@ func (d *DockerValidator) Validate(spec SysSpec) (error, error) { c, err := client.NewClient(dockerEndpoint, "", nil, nil) if err != nil { - return nil, fmt.Errorf("failed to create docker client: %v", err) + return nil, errors.Wrap(err, "failed to create docker client") } info, err := c.Info(context.Background()) if err != nil { - return nil, fmt.Errorf("failed to get docker info: %v", err) + return nil, errors.Wrap(err, "failed to get docker info") } return d.validateDockerInfo(spec.RuntimeSpec.DockerSpec, info) } @@ -77,7 +77,7 @@ func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info) r := regexp.MustCompile(ver) if r.MatchString(info.ServerVersion) { d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, good) - w := fmt.Errorf( + w := errors.Errorf( "this Docker version is not on the list of validated versions: %s. Latest validated version: %s", info.ServerVersion, latestValidatedDockerVersion, @@ -85,7 +85,7 @@ func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info) return w, nil } d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, bad) - return nil, fmt.Errorf("unsupported docker version: %s", info.ServerVersion) + return nil, errors.Errorf("unsupported docker version: %s", info.ServerVersion) } // Validate graph driver. item := dockerConfigPrefix + "GRAPH_DRIVER" @@ -96,5 +96,5 @@ func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info) } } d.Reporter.Report(item, info.Driver, bad) - return nil, fmt.Errorf("unsupported graph driver: %s", info.Driver) + return nil, errors.Errorf("unsupported graph driver: %s", info.Driver) } diff --git a/cmd/kubeadm/app/util/system/kernel_validator.go b/cmd/kubeadm/app/util/system/kernel_validator.go index 36176fae19c29..5add3190f18c5 100644 --- a/cmd/kubeadm/app/util/system/kernel_validator.go +++ b/cmd/kubeadm/app/util/system/kernel_validator.go @@ -30,6 +30,8 @@ import ( "strings" "github.com/golang/glog" + pkgerrors "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/util/errors" ) @@ -64,7 +66,7 @@ func (k *KernelValidator) Validate(spec SysSpec) (error, error) { helper := KernelValidatorHelperImpl{} release, err := helper.GetKernelReleaseVersion() if err != nil { - return nil, fmt.Errorf("failed to get kernel release: %v", err) + return nil, pkgerrors.Wrap(err, "failed to get kernel release") } k.kernelRelease = release var errs []error @@ -87,14 +89,14 @@ func (k *KernelValidator) validateKernelVersion(kSpec KernelSpec) error { } } k.Reporter.Report("KERNEL_VERSION", k.kernelRelease, bad) - return fmt.Errorf("unsupported kernel release: %s", k.kernelRelease) + return pkgerrors.Errorf("unsupported kernel release: %s", k.kernelRelease) } // validateKernelConfig validates the kernel configurations. func (k *KernelValidator) validateKernelConfig(kSpec KernelSpec) error { allConfig, err := k.getKernelConfig() if err != nil { - return fmt.Errorf("failed to parse kernel config: %v", err) + return pkgerrors.Wrap(err, "failed to parse kernel config") } return k.validateCachedKernelConfig(allConfig, kSpec) } @@ -163,7 +165,7 @@ func (k *KernelValidator) validateCachedKernelConfig(allConfig map[string]kConfi validateOpt(config, forbidden) } if len(badConfigs) > 0 { - return fmt.Errorf("unexpected kernel config: %s", strings.Join(badConfigs, " ")) + return pkgerrors.Errorf("unexpected kernel config: %s", strings.Join(badConfigs, " ")) } return nil } @@ -218,14 +220,14 @@ func (k *KernelValidator) getKernelConfigReader() (io.Reader, error) { // config module and check again. output, err := exec.Command(modprobeCmd, configsModule).CombinedOutput() if err != nil { - return nil, fmt.Errorf("unable to load kernel module %q: output - %q, err - %v", - configsModule, output, err) + return nil, pkgerrors.Wrapf(err, "unable to load kernel module: %q, output: %q, err", + configsModule, output) } // Unload the kernel config module to make sure the validation have no side effect. defer exec.Command(modprobeCmd, "-r", configsModule).Run() loadModule = true } - return nil, fmt.Errorf("no config path in %v is available", possibePaths) + return nil, pkgerrors.Errorf("no config path in %v is available", possibePaths) } // getKernelConfig gets kernel config from kernel config file and convert kernel config to internal type. diff --git a/cmd/kubeadm/app/util/system/os_validator.go b/cmd/kubeadm/app/util/system/os_validator.go index 76326559daa28..50cfb82ed8868 100644 --- a/cmd/kubeadm/app/util/system/os_validator.go +++ b/cmd/kubeadm/app/util/system/os_validator.go @@ -17,9 +17,10 @@ limitations under the License. package system import ( - "fmt" "os/exec" "strings" + + "github.com/pkg/errors" ) var _ Validator = &OSValidator{} @@ -35,7 +36,7 @@ func (o *OSValidator) Name() string { func (o *OSValidator) Validate(spec SysSpec) (error, error) { os, err := exec.Command("uname").CombinedOutput() if err != nil { - return nil, fmt.Errorf("failed to get os name: %v", err) + return nil, errors.Wrap(err, "failed to get os name") } return nil, o.validateOS(strings.TrimSpace(string(os)), spec.OS) } @@ -43,7 +44,7 @@ func (o *OSValidator) Validate(spec SysSpec) (error, error) { func (o *OSValidator) validateOS(os, specOS string) error { if os != specOS { o.Reporter.Report("OS", os, bad) - return fmt.Errorf("unsupported operating system: %s", os) + return errors.Errorf("unsupported operating system: %s", os) } o.Reporter.Report("OS", os, good) return nil diff --git a/cmd/kubeadm/app/util/system/package_validator.go b/cmd/kubeadm/app/util/system/package_validator.go index a7d0bd9d2c92c..3c9fa9c319299 100644 --- a/cmd/kubeadm/app/util/system/package_validator.go +++ b/cmd/kubeadm/app/util/system/package_validator.go @@ -26,6 +26,7 @@ import ( "github.com/blang/semver" "github.com/golang/glog" + pkgerrors "github.com/pkg/errors" ) // semVerDotsCount is the number of dots in a valid semantic version. @@ -45,7 +46,7 @@ func newPackageManager() (packageManager, error) { if m, ok := newDPKG(); ok { return m, nil } - return nil, fmt.Errorf("failed to find package manager") + return nil, pkgerrors.New("failed to find package manager") } // dpkg implements packageManager. It uses "dpkg-query" to retrieve package @@ -67,11 +68,11 @@ func newDPKG() (packageManager, bool) { func (_ dpkg) getPackageVersion(packageName string) (string, error) { output, err := exec.Command("dpkg-query", "--show", "--showformat='${Version}'", packageName).Output() if err != nil { - return "", fmt.Errorf("dpkg-query failed: %s", err) + return "", pkgerrors.Wrap(err, "dpkg-query failed") } version := extractUpstreamVersion(string(output)) if version == "" { - return "", fmt.Errorf("no version information") + return "", pkgerrors.New("no version information") } return version, nil } @@ -153,7 +154,7 @@ func (self *packageValidator) validate(packageSpecs []PackageSpec, manager packa if versionRange(sv) { self.reporter.Report(nameWithVerRange, version, good) } else { - errs = append(errs, fmt.Errorf("package \"%s %s\" does not meet the spec \"%s (%s)\"", packageName, sv, packageName, spec.VersionRange)) + errs = append(errs, pkgerrors.Errorf("package \"%s %s\" does not meet the spec \"%s (%s)\"", packageName, sv, packageName, spec.VersionRange)) self.reporter.Report(nameWithVerRange, version, bad) } } @@ -164,7 +165,7 @@ func (self *packageValidator) validate(packageSpecs []PackageSpec, manager packa func getKernelRelease() (string, error) { output, err := exec.Command("uname", "-r").Output() if err != nil { - return "", fmt.Errorf("failed to get kernel release: %s", err) + return "", pkgerrors.Wrap(err, "failed to get kernel release") } return strings.TrimSpace(string(output)), nil } @@ -174,7 +175,7 @@ func getOSDistro() (string, error) { f := "/etc/lsb-release" b, err := ioutil.ReadFile(f) if err != nil { - return "", fmt.Errorf("failed to read %q: %s", f, err) + return "", pkgerrors.Wrapf(err, "failed to read %q", f) } content := string(b) switch { @@ -185,7 +186,7 @@ func getOSDistro() (string, error) { case strings.Contains(content, "CoreOS"): return "coreos", nil default: - return "", fmt.Errorf("failed to get OS distro: %s", content) + return "", pkgerrors.Errorf("failed to get OS distro: %s", content) } } diff --git a/cmd/kubeadm/app/util/system/package_validator_test.go b/cmd/kubeadm/app/util/system/package_validator_test.go index 0e57fb5086515..3387a454a687e 100644 --- a/cmd/kubeadm/app/util/system/package_validator_test.go +++ b/cmd/kubeadm/app/util/system/package_validator_test.go @@ -17,10 +17,10 @@ limitations under the License. package system import ( - "errors" - "fmt" "reflect" "testing" + + "github.com/pkg/errors" ) func TestExtractUpstreamVersion(t *testing.T) { @@ -159,7 +159,7 @@ func (m testPackageManager) getPackageVersion(packageName string) (string, error if v, ok := m.packageVersions[packageName]; ok { return v, nil } - return "", fmt.Errorf("package %q does not exist", packageName) + return "", errors.Errorf("package %q does not exist", packageName) } func TestValidatePackageVersion(t *testing.T) { diff --git a/cmd/kubeadm/app/util/system/report.go b/cmd/kubeadm/app/util/system/report.go index 6ece3e8158610..dfeb445ea6239 100644 --- a/cmd/kubeadm/app/util/system/report.go +++ b/cmd/kubeadm/app/util/system/report.go @@ -18,6 +18,7 @@ package system import ( "fmt" + "github.com/pkg/errors" "io" "os" ) @@ -65,7 +66,7 @@ func (dr *StreamReporter) Report(key, value string, resultType ValidationResultT c = white } if dr.WriteStream == nil { - return fmt.Errorf("WriteStream has to be defined for this reporter") + return errors.New("WriteStream has to be defined for this reporter") } fmt.Fprintf(dr.WriteStream, "%s: %s\n", colorize(key, white), colorize(value, c)) diff --git a/cmd/kubeadm/app/util/system/types_windows.go b/cmd/kubeadm/app/util/system/types_windows.go index fb85049cdd726..34d89f2bd903c 100644 --- a/cmd/kubeadm/app/util/system/types_windows.go +++ b/cmd/kubeadm/app/util/system/types_windows.go @@ -49,7 +49,7 @@ type KernelValidatorHelperImpl struct{} var _ KernelValidatorHelper = &KernelValidatorHelperImpl{} -// GetKernelRelease returns the windows release version (ex. 10.0.14393) as a string +// GetKernelReleaseVersion returns the windows release version (ex. 10.0.14393) as a string func (o *KernelValidatorHelperImpl) GetKernelReleaseVersion() (string, error) { args := []string{"(Get-CimInstance Win32_OperatingSystem).Version"} releaseVersion, err := exec.Command("powershell", args...).Output() diff --git a/cmd/kubeadm/app/util/template.go b/cmd/kubeadm/app/util/template.go index 0dad0d0afbe3b..5951f8c8297a3 100644 --- a/cmd/kubeadm/app/util/template.go +++ b/cmd/kubeadm/app/util/template.go @@ -18,8 +18,9 @@ package util import ( "bytes" - "fmt" "text/template" + + "github.com/pkg/errors" ) // ParseTemplate validates and parses passed as argument template @@ -27,11 +28,11 @@ func ParseTemplate(strtmpl string, obj interface{}) ([]byte, error) { var buf bytes.Buffer tmpl, err := template.New("template").Parse(strtmpl) if err != nil { - return nil, fmt.Errorf("error when parsing template: %v", err) + return nil, errors.Wrap(err, "error when parsing template") } err = tmpl.Execute(&buf, obj) if err != nil { - return nil, fmt.Errorf("error when executing template: %v", err) + return nil, errors.Wrap(err, "error when executing template") } return buf.Bytes(), nil } diff --git a/cmd/kubeadm/app/util/version.go b/cmd/kubeadm/app/util/version.go index c9246484d5576..3830ed1a08a6d 100644 --- a/cmd/kubeadm/app/util/version.go +++ b/cmd/kubeadm/app/util/version.go @@ -26,6 +26,7 @@ import ( "time" "github.com/golang/glog" + pkgerrors "github.com/pkg/errors" netutil "k8s.io/apimachinery/pkg/util/net" versionutil "k8s.io/apimachinery/pkg/util/version" pkgversion "k8s.io/kubernetes/pkg/version" @@ -102,7 +103,7 @@ func KubernetesReleaseVersion(version string) (string, error) { // Re-validate received version and return. return KubernetesReleaseVersion(body) } - return "", fmt.Errorf("version %q doesn't match patterns for neither semantic version nor labels (stable, latest, ...)", version) + return "", pkgerrors.Errorf("version %q doesn't match patterns for neither semantic version nor labels (stable, latest, ...)", version) } // KubernetesVersionToImageTag is helper function that replaces all @@ -143,7 +144,7 @@ func splitVersion(version string) (string, string, error) { var urlSuffix string subs := kubeBucketPrefixes.FindAllStringSubmatch(version, 1) if len(subs) != 1 || len(subs[0]) != 4 { - return "", "", fmt.Errorf("invalid version %q", version) + return "", "", pkgerrors.Errorf("invalid version %q", version) } switch { @@ -163,12 +164,12 @@ func fetchFromURL(url string, timeout time.Duration) (string, error) { client := &http.Client{Timeout: timeout, Transport: netutil.SetOldTransportDefaults(&http.Transport{})} resp, err := client.Get(url) if err != nil { - return "", fmt.Errorf("unable to get URL %q: %s", url, err.Error()) + return "", pkgerrors.Errorf("unable to get URL %q: %s", url, err.Error()) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { - return "", fmt.Errorf("unable to read content of URL %q: %s", url, err.Error()) + return "", pkgerrors.Errorf("unable to read content of URL %q: %s", url, err.Error()) } bodyString := strings.TrimSpace(string(body)) @@ -183,7 +184,7 @@ func fetchFromURL(url string, timeout time.Duration) (string, error) { func kubeadmVersion(info string) (string, error) { v, err := versionutil.ParseSemantic(info) if err != nil { - return "", fmt.Errorf("kubeadm version error: %v", err) + return "", pkgerrors.Wrap(err, "kubeadm version error") } // There is no utility in versionutil to get the version without the metadata, // so this needs some manual formatting. @@ -222,11 +223,11 @@ func validateStableVersion(remoteVersion, clientVersion string) (string, error) verRemote, err := versionutil.ParseGeneric(remoteVersion) if err != nil { - return "", fmt.Errorf("remote version error: %v", err) + return "", pkgerrors.Wrap(err, "remote version error") } verClient, err := versionutil.ParseGeneric(clientVersion) if err != nil { - return "", fmt.Errorf("client version error: %v", err) + return "", pkgerrors.Wrap(err, "client version error") } // If the remote Major version is bigger or if the Major versions are the same, // but the remote Minor is bigger use the client version release. This handles Major bumps too. diff --git a/cmd/kubeadm/test/BUILD b/cmd/kubeadm/test/BUILD index d9316357c3390..2c6fc05940ac4 100644 --- a/cmd/kubeadm/test/BUILD +++ b/cmd/kubeadm/test/BUILD @@ -13,8 +13,8 @@ go_library( "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//cmd/kubeadm/test/certs:go_default_library", "//vendor/github.com/renstrom/dedent:go_default_library", ], diff --git a/cmd/kubeadm/test/certs/BUILD b/cmd/kubeadm/test/certs/BUILD index 1211e655317e8..2bd48fc0e105d 100644 --- a/cmd/kubeadm/test/certs/BUILD +++ b/cmd/kubeadm/test/certs/BUILD @@ -10,7 +10,7 @@ go_library( srcs = ["util.go"], importpath = "k8s.io/kubernetes/cmd/kubeadm/test/certs", deps = [ - "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", + "//cmd/kubeadm/app/util/pkiutil:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", ], ) diff --git a/cmd/kubeadm/test/certs/util.go b/cmd/kubeadm/test/certs/util.go index 1cd8be17db688..f22a3056a228a 100644 --- a/cmd/kubeadm/test/certs/util.go +++ b/cmd/kubeadm/test/certs/util.go @@ -23,7 +23,7 @@ import ( "testing" certutil "k8s.io/client-go/util/cert" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" ) // SetupCertificateAuthorithy is a utility function for kubeadm testing that creates a diff --git a/cmd/kubeadm/test/cmd/BUILD b/cmd/kubeadm/test/cmd/BUILD index 2fb31fdde83e4..94771cffe00d0 100644 --- a/cmd/kubeadm/test/cmd/BUILD +++ b/cmd/kubeadm/test/cmd/BUILD @@ -10,7 +10,10 @@ go_library( name = "go_default_library", srcs = ["util.go"], importpath = "k8s.io/kubernetes/cmd/kubeadm/test/cmd", - deps = ["//vendor/github.com/spf13/cobra:go_default_library"], + deps = [ + "//vendor/github.com/pkg/errors:go_default_library", + "//vendor/github.com/spf13/cobra:go_default_library", + ], ) go_test( diff --git a/cmd/kubeadm/test/cmd/util.go b/cmd/kubeadm/test/cmd/util.go index 38c8d5c90dd13..5bed6d35782ca 100644 --- a/cmd/kubeadm/test/cmd/util.go +++ b/cmd/kubeadm/test/cmd/util.go @@ -18,7 +18,7 @@ package kubeadm import ( "bytes" - "fmt" + "github.com/pkg/errors" "os/exec" "testing" @@ -37,8 +37,8 @@ func RunCmd(command string, args ...string) (string, string, error) { err := cmd.Run() stdout, stderr := bout.String(), berr.String() if err != nil { - return "", "", fmt.Errorf("error running %s %v; \ngot error %v, \nstdout %q, \nstderr %q", - command, args, err, stdout, stderr) + return "", "", errors.Wrapf(err, "error running %s %v; \nstdout %q, \nstderr %q, \ngot error", + command, args, stdout, stderr) } return stdout, stderr, nil } diff --git a/cmd/kubeadm/test/util.go b/cmd/kubeadm/test/util.go index d275645a88df2..0346a451f2688 100644 --- a/cmd/kubeadm/test/util.go +++ b/cmd/kubeadm/test/util.go @@ -28,8 +28,8 @@ import ( kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" + "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" certtestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs" ) diff --git a/cmd/kubelet/app/options/options.go b/cmd/kubelet/app/options/options.go index 9dca28b9548dc..ff8dccde72cfe 100644 --- a/cmd/kubelet/app/options/options.go +++ b/cmd/kubelet/app/options/options.go @@ -368,7 +368,7 @@ func (f *KubeletFlags) AddFlags(mainfs *pflag.FlagSet) { fs.Var(&f.DynamicConfigDir, "dynamic-config-dir", "The Kubelet will use this directory for checkpointing downloaded configurations and tracking configuration health. The Kubelet will create this directory if it does not already exist. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Providing this flag enables dynamic Kubelet configuration. The DynamicKubeletConfig feature gate must be enabled to pass this flag; this gate currently defaults to true because the feature is beta.") - fs.BoolVar(&f.RegisterNode, "register-node", f.RegisterNode, "Register the node with the apiserver. If --kubeconfig is not provided, this flag is irrelevant, as the Kubelet won't have an apiserver to register with. Default=true.") + fs.BoolVar(&f.RegisterNode, "register-node", f.RegisterNode, "Register the node with the apiserver. If --kubeconfig is not provided, this flag is irrelevant, as the Kubelet won't have an apiserver to register with.") fs.Var(utiltaints.NewTaintsVar(&f.RegisterWithTaints), "register-with-taints", "Register the node with the given list of taints (comma separated \"=:\"). No-op if register-node is false.") fs.BoolVar(&f.Containerized, "containerized", f.Containerized, "Running kubelet in a container.") @@ -387,7 +387,7 @@ func (f *KubeletFlags) AddFlags(mainfs *pflag.FlagSet) { fs.BoolVar(&f.ExitOnLockContention, "exit-on-lock-contention", f.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.") fs.StringVar(&f.SeccompProfileRoot, "seccomp-profile-root", f.SeccompProfileRoot, " Directory path for seccomp profiles.") fs.StringVar(&f.BootstrapCheckpointPath, "bootstrap-checkpoint-path", f.BootstrapCheckpointPath, " Path to the directory where the checkpoints are stored") - fs.Int32Var(&f.NodeStatusMaxImages, "node-status-max-images", f.NodeStatusMaxImages, " The maximum number of images to report in Node.Status.Images. If -1 is specified, no cap will be applied. Default: 50") + fs.Int32Var(&f.NodeStatusMaxImages, "node-status-max-images", f.NodeStatusMaxImages, " The maximum number of images to report in Node.Status.Images. If -1 is specified, no cap will be applied.") // DEPRECATED FLAGS fs.StringVar(&f.BootstrapKubeconfig, "experimental-bootstrap-kubeconfig", f.BootstrapKubeconfig, "") diff --git a/docs/.generated_docs b/docs/.generated_docs index fd8a3adc7f7fa..9639f6c0db90a 100644 --- a/docs/.generated_docs +++ b/docs/.generated_docs @@ -6,6 +6,22 @@ docs/admin/kube-proxy.md docs/admin/kube-scheduler.md docs/admin/kubeadm.md docs/admin/kubeadm_alpha.md +docs/admin/kubeadm_alpha_certs.md +docs/admin/kubeadm_alpha_certs_renew.md +docs/admin/kubeadm_alpha_certs_renew_all.md +docs/admin/kubeadm_alpha_certs_renew_apiserver-etcd-client.md +docs/admin/kubeadm_alpha_certs_renew_apiserver-kubelet-client.md +docs/admin/kubeadm_alpha_certs_renew_apiserver.md +docs/admin/kubeadm_alpha_certs_renew_etcd-healthcheck-client.md +docs/admin/kubeadm_alpha_certs_renew_etcd-peer.md +docs/admin/kubeadm_alpha_certs_renew_etcd-server.md +docs/admin/kubeadm_alpha_certs_renew_front-proxy-client.md +docs/admin/kubeadm_alpha_kubeconfig.md +docs/admin/kubeadm_alpha_kubeconfig_user.md +docs/admin/kubeadm_alpha_kubelet.md +docs/admin/kubeadm_alpha_kubelet_config.md +docs/admin/kubeadm_alpha_kubelet_config_download.md +docs/admin/kubeadm_alpha_kubelet_config_enable-dynamic.md docs/admin/kubeadm_alpha_phase.md docs/admin/kubeadm_alpha_phase_addon.md docs/admin/kubeadm_alpha_phase_addon_all.md @@ -18,56 +34,11 @@ docs/admin/kubeadm_alpha_phase_bootstrap-token_create.md docs/admin/kubeadm_alpha_phase_bootstrap-token_node.md docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md -docs/admin/kubeadm_alpha_phase_certs.md -docs/admin/kubeadm_alpha_phase_certs_all.md -docs/admin/kubeadm_alpha_phase_certs_apiserver-etcd-client.md -docs/admin/kubeadm_alpha_phase_certs_apiserver-kubelet-client.md -docs/admin/kubeadm_alpha_phase_certs_apiserver.md -docs/admin/kubeadm_alpha_phase_certs_ca.md -docs/admin/kubeadm_alpha_phase_certs_etcd-ca.md -docs/admin/kubeadm_alpha_phase_certs_etcd-healthcheck-client.md -docs/admin/kubeadm_alpha_phase_certs_etcd-peer.md -docs/admin/kubeadm_alpha_phase_certs_etcd-server.md -docs/admin/kubeadm_alpha_phase_certs_front-proxy-ca.md -docs/admin/kubeadm_alpha_phase_certs_front-proxy-client.md -docs/admin/kubeadm_alpha_phase_certs_renew.md -docs/admin/kubeadm_alpha_phase_certs_renew_all.md -docs/admin/kubeadm_alpha_phase_certs_renew_apiserver-etcd-client.md -docs/admin/kubeadm_alpha_phase_certs_renew_apiserver-kubelet-client.md -docs/admin/kubeadm_alpha_phase_certs_renew_apiserver.md -docs/admin/kubeadm_alpha_phase_certs_renew_etcd-healthcheck-client.md -docs/admin/kubeadm_alpha_phase_certs_renew_etcd-peer.md -docs/admin/kubeadm_alpha_phase_certs_renew_etcd-server.md -docs/admin/kubeadm_alpha_phase_certs_renew_front-proxy-client.md -docs/admin/kubeadm_alpha_phase_certs_sa.md -docs/admin/kubeadm_alpha_phase_controlplane.md -docs/admin/kubeadm_alpha_phase_controlplane_all.md -docs/admin/kubeadm_alpha_phase_controlplane_apiserver.md -docs/admin/kubeadm_alpha_phase_controlplane_controller-manager.md -docs/admin/kubeadm_alpha_phase_controlplane_scheduler.md -docs/admin/kubeadm_alpha_phase_etcd.md -docs/admin/kubeadm_alpha_phase_etcd_local.md -docs/admin/kubeadm_alpha_phase_kubeconfig.md -docs/admin/kubeadm_alpha_phase_kubeconfig_admin.md -docs/admin/kubeadm_alpha_phase_kubeconfig_all.md -docs/admin/kubeadm_alpha_phase_kubeconfig_controller-manager.md -docs/admin/kubeadm_alpha_phase_kubeconfig_kubelet.md -docs/admin/kubeadm_alpha_phase_kubeconfig_scheduler.md -docs/admin/kubeadm_alpha_phase_kubeconfig_user.md -docs/admin/kubeadm_alpha_phase_kubelet.md -docs/admin/kubeadm_alpha_phase_kubelet_config.md -docs/admin/kubeadm_alpha_phase_kubelet_config_annotate-cri.md -docs/admin/kubeadm_alpha_phase_kubelet_config_download.md -docs/admin/kubeadm_alpha_phase_kubelet_config_enable-dynamic.md -docs/admin/kubeadm_alpha_phase_kubelet_config_upload.md -docs/admin/kubeadm_alpha_phase_kubelet_config_write-to-disk.md -docs/admin/kubeadm_alpha_phase_kubelet_write-env-file.md docs/admin/kubeadm_alpha_phase_mark-master.md -docs/admin/kubeadm_alpha_phase_preflight.md -docs/admin/kubeadm_alpha_phase_preflight_node.md docs/admin/kubeadm_alpha_phase_selfhosting.md docs/admin/kubeadm_alpha_phase_selfhosting_convert-from-staticpods.md -docs/admin/kubeadm_alpha_phase_upload-config.md +docs/admin/kubeadm_alpha_preflight.md +docs/admin/kubeadm_alpha_preflight_node.md docs/admin/kubeadm_completion.md docs/admin/kubeadm_config.md docs/admin/kubeadm_config_images.md @@ -83,7 +54,34 @@ docs/admin/kubeadm_config_upload_from-flags.md docs/admin/kubeadm_config_view.md docs/admin/kubeadm_init.md docs/admin/kubeadm_init_phase.md +docs/admin/kubeadm_init_phase_certs.md +docs/admin/kubeadm_init_phase_certs_apiserver-etcd-client.md +docs/admin/kubeadm_init_phase_certs_apiserver-kubelet-client.md +docs/admin/kubeadm_init_phase_certs_apiserver.md +docs/admin/kubeadm_init_phase_certs_ca.md +docs/admin/kubeadm_init_phase_certs_etcd-ca.md +docs/admin/kubeadm_init_phase_certs_etcd-healthcheck-client.md +docs/admin/kubeadm_init_phase_certs_etcd-peer.md +docs/admin/kubeadm_init_phase_certs_etcd-server.md +docs/admin/kubeadm_init_phase_certs_front-proxy-ca.md +docs/admin/kubeadm_init_phase_certs_front-proxy-client.md +docs/admin/kubeadm_init_phase_certs_sa.md +docs/admin/kubeadm_init_phase_control-plane.md +docs/admin/kubeadm_init_phase_control-plane_apiserver.md +docs/admin/kubeadm_init_phase_control-plane_controller-manager.md +docs/admin/kubeadm_init_phase_control-plane_scheduler.md +docs/admin/kubeadm_init_phase_etcd.md +docs/admin/kubeadm_init_phase_etcd_local.md +docs/admin/kubeadm_init_phase_kubeconfig.md +docs/admin/kubeadm_init_phase_kubeconfig_admin.md +docs/admin/kubeadm_init_phase_kubeconfig_controller-manager.md +docs/admin/kubeadm_init_phase_kubeconfig_kubelet.md +docs/admin/kubeadm_init_phase_kubeconfig_scheduler.md +docs/admin/kubeadm_init_phase_kubelet-start.md docs/admin/kubeadm_init_phase_preflight.md +docs/admin/kubeadm_init_phase_upload-config.md +docs/admin/kubeadm_init_phase_upload-config_kubeadm.md +docs/admin/kubeadm_init_phase_upload-config_kubelet.md docs/admin/kubeadm_join.md docs/admin/kubeadm_reset.md docs/admin/kubeadm_token.md @@ -105,6 +103,22 @@ docs/man/man1/kube-apiserver.1 docs/man/man1/kube-controller-manager.1 docs/man/man1/kube-proxy.1 docs/man/man1/kube-scheduler.1 +docs/man/man1/kubeadm-alpha-certs-renew-all.1 +docs/man/man1/kubeadm-alpha-certs-renew-apiserver-etcd-client.1 +docs/man/man1/kubeadm-alpha-certs-renew-apiserver-kubelet-client.1 +docs/man/man1/kubeadm-alpha-certs-renew-apiserver.1 +docs/man/man1/kubeadm-alpha-certs-renew-etcd-healthcheck-client.1 +docs/man/man1/kubeadm-alpha-certs-renew-etcd-peer.1 +docs/man/man1/kubeadm-alpha-certs-renew-etcd-server.1 +docs/man/man1/kubeadm-alpha-certs-renew-front-proxy-client.1 +docs/man/man1/kubeadm-alpha-certs-renew.1 +docs/man/man1/kubeadm-alpha-certs.1 +docs/man/man1/kubeadm-alpha-kubeconfig-user.1 +docs/man/man1/kubeadm-alpha-kubeconfig.1 +docs/man/man1/kubeadm-alpha-kubelet-config-download.1 +docs/man/man1/kubeadm-alpha-kubelet-config-enable-dynamic.1 +docs/man/man1/kubeadm-alpha-kubelet-config.1 +docs/man/man1/kubeadm-alpha-kubelet.1 docs/man/man1/kubeadm-alpha-phase-addon-all.1 docs/man/man1/kubeadm-alpha-phase-addon-coredns.1 docs/man/man1/kubeadm-alpha-phase-addon-kube-proxy.1 @@ -116,57 +130,12 @@ docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node-allow-auto-approve.1 docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node-allow-post-csrs.1 docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node.1 docs/man/man1/kubeadm-alpha-phase-bootstrap-token.1 -docs/man/man1/kubeadm-alpha-phase-certs-all.1 -docs/man/man1/kubeadm-alpha-phase-certs-apiserver-etcd-client.1 -docs/man/man1/kubeadm-alpha-phase-certs-apiserver-kubelet-client.1 -docs/man/man1/kubeadm-alpha-phase-certs-apiserver.1 -docs/man/man1/kubeadm-alpha-phase-certs-ca.1 -docs/man/man1/kubeadm-alpha-phase-certs-etcd-ca.1 -docs/man/man1/kubeadm-alpha-phase-certs-etcd-healthcheck-client.1 -docs/man/man1/kubeadm-alpha-phase-certs-etcd-peer.1 -docs/man/man1/kubeadm-alpha-phase-certs-etcd-server.1 -docs/man/man1/kubeadm-alpha-phase-certs-front-proxy-ca.1 -docs/man/man1/kubeadm-alpha-phase-certs-front-proxy-client.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew-all.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-etcd-client.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-kubelet-client.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-healthcheck-client.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-peer.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-server.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew-front-proxy-client.1 -docs/man/man1/kubeadm-alpha-phase-certs-renew.1 -docs/man/man1/kubeadm-alpha-phase-certs-sa.1 -docs/man/man1/kubeadm-alpha-phase-certs.1 -docs/man/man1/kubeadm-alpha-phase-controlplane-all.1 -docs/man/man1/kubeadm-alpha-phase-controlplane-apiserver.1 -docs/man/man1/kubeadm-alpha-phase-controlplane-controller-manager.1 -docs/man/man1/kubeadm-alpha-phase-controlplane-scheduler.1 -docs/man/man1/kubeadm-alpha-phase-controlplane.1 -docs/man/man1/kubeadm-alpha-phase-etcd-local.1 -docs/man/man1/kubeadm-alpha-phase-etcd.1 -docs/man/man1/kubeadm-alpha-phase-kubeconfig-admin.1 -docs/man/man1/kubeadm-alpha-phase-kubeconfig-all.1 -docs/man/man1/kubeadm-alpha-phase-kubeconfig-controller-manager.1 -docs/man/man1/kubeadm-alpha-phase-kubeconfig-kubelet.1 -docs/man/man1/kubeadm-alpha-phase-kubeconfig-scheduler.1 -docs/man/man1/kubeadm-alpha-phase-kubeconfig-user.1 -docs/man/man1/kubeadm-alpha-phase-kubeconfig.1 -docs/man/man1/kubeadm-alpha-phase-kubelet-config-annotate-cri.1 -docs/man/man1/kubeadm-alpha-phase-kubelet-config-download.1 -docs/man/man1/kubeadm-alpha-phase-kubelet-config-enable-dynamic.1 -docs/man/man1/kubeadm-alpha-phase-kubelet-config-upload.1 -docs/man/man1/kubeadm-alpha-phase-kubelet-config-write-to-disk.1 -docs/man/man1/kubeadm-alpha-phase-kubelet-config.1 -docs/man/man1/kubeadm-alpha-phase-kubelet-write-env-file.1 -docs/man/man1/kubeadm-alpha-phase-kubelet.1 docs/man/man1/kubeadm-alpha-phase-mark-master.1 -docs/man/man1/kubeadm-alpha-phase-preflight-node.1 -docs/man/man1/kubeadm-alpha-phase-preflight.1 docs/man/man1/kubeadm-alpha-phase-selfhosting-convert-from-staticpods.1 docs/man/man1/kubeadm-alpha-phase-selfhosting.1 -docs/man/man1/kubeadm-alpha-phase-upload-config.1 docs/man/man1/kubeadm-alpha-phase.1 +docs/man/man1/kubeadm-alpha-preflight-node.1 +docs/man/man1/kubeadm-alpha-preflight.1 docs/man/man1/kubeadm-alpha.1 docs/man/man1/kubeadm-completion.1 docs/man/man1/kubeadm-config-images-list.1 @@ -182,7 +151,34 @@ docs/man/man1/kubeadm-config-upload-from-flags.1 docs/man/man1/kubeadm-config-upload.1 docs/man/man1/kubeadm-config-view.1 docs/man/man1/kubeadm-config.1 +docs/man/man1/kubeadm-init-phase-certs-apiserver-etcd-client.1 +docs/man/man1/kubeadm-init-phase-certs-apiserver-kubelet-client.1 +docs/man/man1/kubeadm-init-phase-certs-apiserver.1 +docs/man/man1/kubeadm-init-phase-certs-ca.1 +docs/man/man1/kubeadm-init-phase-certs-etcd-ca.1 +docs/man/man1/kubeadm-init-phase-certs-etcd-healthcheck-client.1 +docs/man/man1/kubeadm-init-phase-certs-etcd-peer.1 +docs/man/man1/kubeadm-init-phase-certs-etcd-server.1 +docs/man/man1/kubeadm-init-phase-certs-front-proxy-ca.1 +docs/man/man1/kubeadm-init-phase-certs-front-proxy-client.1 +docs/man/man1/kubeadm-init-phase-certs-sa.1 +docs/man/man1/kubeadm-init-phase-certs.1 +docs/man/man1/kubeadm-init-phase-control-plane-apiserver.1 +docs/man/man1/kubeadm-init-phase-control-plane-controller-manager.1 +docs/man/man1/kubeadm-init-phase-control-plane-scheduler.1 +docs/man/man1/kubeadm-init-phase-control-plane.1 +docs/man/man1/kubeadm-init-phase-etcd-local.1 +docs/man/man1/kubeadm-init-phase-etcd.1 +docs/man/man1/kubeadm-init-phase-kubeconfig-admin.1 +docs/man/man1/kubeadm-init-phase-kubeconfig-controller-manager.1 +docs/man/man1/kubeadm-init-phase-kubeconfig-kubelet.1 +docs/man/man1/kubeadm-init-phase-kubeconfig-scheduler.1 +docs/man/man1/kubeadm-init-phase-kubeconfig.1 +docs/man/man1/kubeadm-init-phase-kubelet-start.1 docs/man/man1/kubeadm-init-phase-preflight.1 +docs/man/man1/kubeadm-init-phase-upload-config-kubeadm.1 +docs/man/man1/kubeadm-init-phase-upload-config-kubelet.1 +docs/man/man1/kubeadm-init-phase-upload-config.1 docs/man/man1/kubeadm-init-phase.1 docs/man/man1/kubeadm-init.1 docs/man/man1/kubeadm-join.1 diff --git a/docs/admin/kubeadm_alpha_phase_certs.md b/docs/admin/kubeadm_alpha_certs.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs.md rename to docs/admin/kubeadm_alpha_certs.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_all.md b/docs/admin/kubeadm_alpha_certs_renew.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_all.md rename to docs/admin/kubeadm_alpha_certs_renew.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_apiserver-etcd-client.md b/docs/admin/kubeadm_alpha_certs_renew_all.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_apiserver-etcd-client.md rename to docs/admin/kubeadm_alpha_certs_renew_all.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_apiserver-kubelet-client.md b/docs/admin/kubeadm_alpha_certs_renew_apiserver-etcd-client.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_apiserver-kubelet-client.md rename to docs/admin/kubeadm_alpha_certs_renew_apiserver-etcd-client.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_apiserver.md b/docs/admin/kubeadm_alpha_certs_renew_apiserver-kubelet-client.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_apiserver.md rename to docs/admin/kubeadm_alpha_certs_renew_apiserver-kubelet-client.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_ca.md b/docs/admin/kubeadm_alpha_certs_renew_apiserver.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_ca.md rename to docs/admin/kubeadm_alpha_certs_renew_apiserver.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_etcd-ca.md b/docs/admin/kubeadm_alpha_certs_renew_etcd-healthcheck-client.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_etcd-ca.md rename to docs/admin/kubeadm_alpha_certs_renew_etcd-healthcheck-client.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_etcd-healthcheck-client.md b/docs/admin/kubeadm_alpha_certs_renew_etcd-peer.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_etcd-healthcheck-client.md rename to docs/admin/kubeadm_alpha_certs_renew_etcd-peer.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_etcd-peer.md b/docs/admin/kubeadm_alpha_certs_renew_etcd-server.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_etcd-peer.md rename to docs/admin/kubeadm_alpha_certs_renew_etcd-server.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_etcd-server.md b/docs/admin/kubeadm_alpha_certs_renew_front-proxy-client.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_etcd-server.md rename to docs/admin/kubeadm_alpha_certs_renew_front-proxy-client.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_front-proxy-ca.md b/docs/admin/kubeadm_alpha_kubeconfig.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_front-proxy-ca.md rename to docs/admin/kubeadm_alpha_kubeconfig.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_front-proxy-client.md b/docs/admin/kubeadm_alpha_kubeconfig_user.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_front-proxy-client.md rename to docs/admin/kubeadm_alpha_kubeconfig_user.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew.md b/docs/admin/kubeadm_alpha_kubelet.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew.md rename to docs/admin/kubeadm_alpha_kubelet.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew_all.md b/docs/admin/kubeadm_alpha_kubelet_config.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew_all.md rename to docs/admin/kubeadm_alpha_kubelet_config.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew_apiserver-etcd-client.md b/docs/admin/kubeadm_alpha_kubelet_config_download.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew_apiserver-etcd-client.md rename to docs/admin/kubeadm_alpha_kubelet_config_download.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew_apiserver-kubelet-client.md b/docs/admin/kubeadm_alpha_kubelet_config_enable-dynamic.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew_apiserver-kubelet-client.md rename to docs/admin/kubeadm_alpha_kubelet_config_enable-dynamic.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew_apiserver.md b/docs/admin/kubeadm_alpha_preflight.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew_apiserver.md rename to docs/admin/kubeadm_alpha_preflight.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew_etcd-healthcheck-client.md b/docs/admin/kubeadm_alpha_preflight_node.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew_etcd-healthcheck-client.md rename to docs/admin/kubeadm_alpha_preflight_node.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew_etcd-peer.md b/docs/admin/kubeadm_init_phase_certs.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew_etcd-peer.md rename to docs/admin/kubeadm_init_phase_certs.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew_etcd-server.md b/docs/admin/kubeadm_init_phase_certs_apiserver-etcd-client.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew_etcd-server.md rename to docs/admin/kubeadm_init_phase_certs_apiserver-etcd-client.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_renew_front-proxy-client.md b/docs/admin/kubeadm_init_phase_certs_apiserver-kubelet-client.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_renew_front-proxy-client.md rename to docs/admin/kubeadm_init_phase_certs_apiserver-kubelet-client.md diff --git a/docs/admin/kubeadm_alpha_phase_certs_sa.md b/docs/admin/kubeadm_init_phase_certs_apiserver.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_certs_sa.md rename to docs/admin/kubeadm_init_phase_certs_apiserver.md diff --git a/docs/admin/kubeadm_alpha_phase_controlplane.md b/docs/admin/kubeadm_init_phase_certs_ca.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_controlplane.md rename to docs/admin/kubeadm_init_phase_certs_ca.md diff --git a/docs/admin/kubeadm_alpha_phase_controlplane_all.md b/docs/admin/kubeadm_init_phase_certs_etcd-ca.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_controlplane_all.md rename to docs/admin/kubeadm_init_phase_certs_etcd-ca.md diff --git a/docs/admin/kubeadm_alpha_phase_controlplane_apiserver.md b/docs/admin/kubeadm_init_phase_certs_etcd-healthcheck-client.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_controlplane_apiserver.md rename to docs/admin/kubeadm_init_phase_certs_etcd-healthcheck-client.md diff --git a/docs/admin/kubeadm_alpha_phase_controlplane_controller-manager.md b/docs/admin/kubeadm_init_phase_certs_etcd-peer.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_controlplane_controller-manager.md rename to docs/admin/kubeadm_init_phase_certs_etcd-peer.md diff --git a/docs/admin/kubeadm_alpha_phase_controlplane_scheduler.md b/docs/admin/kubeadm_init_phase_certs_etcd-server.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_controlplane_scheduler.md rename to docs/admin/kubeadm_init_phase_certs_etcd-server.md diff --git a/docs/admin/kubeadm_alpha_phase_etcd.md b/docs/admin/kubeadm_init_phase_certs_front-proxy-ca.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_etcd.md rename to docs/admin/kubeadm_init_phase_certs_front-proxy-ca.md diff --git a/docs/admin/kubeadm_alpha_phase_etcd_local.md b/docs/admin/kubeadm_init_phase_certs_front-proxy-client.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_etcd_local.md rename to docs/admin/kubeadm_init_phase_certs_front-proxy-client.md diff --git a/docs/admin/kubeadm_alpha_phase_kubeconfig.md b/docs/admin/kubeadm_init_phase_certs_sa.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubeconfig.md rename to docs/admin/kubeadm_init_phase_certs_sa.md diff --git a/docs/admin/kubeadm_alpha_phase_kubeconfig_admin.md b/docs/admin/kubeadm_init_phase_control-plane.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubeconfig_admin.md rename to docs/admin/kubeadm_init_phase_control-plane.md diff --git a/docs/admin/kubeadm_alpha_phase_kubeconfig_all.md b/docs/admin/kubeadm_init_phase_control-plane_apiserver.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubeconfig_all.md rename to docs/admin/kubeadm_init_phase_control-plane_apiserver.md diff --git a/docs/admin/kubeadm_alpha_phase_kubeconfig_controller-manager.md b/docs/admin/kubeadm_init_phase_control-plane_controller-manager.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubeconfig_controller-manager.md rename to docs/admin/kubeadm_init_phase_control-plane_controller-manager.md diff --git a/docs/admin/kubeadm_alpha_phase_kubeconfig_kubelet.md b/docs/admin/kubeadm_init_phase_control-plane_scheduler.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubeconfig_kubelet.md rename to docs/admin/kubeadm_init_phase_control-plane_scheduler.md diff --git a/docs/admin/kubeadm_alpha_phase_kubeconfig_scheduler.md b/docs/admin/kubeadm_init_phase_etcd.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubeconfig_scheduler.md rename to docs/admin/kubeadm_init_phase_etcd.md diff --git a/docs/admin/kubeadm_alpha_phase_kubeconfig_user.md b/docs/admin/kubeadm_init_phase_etcd_local.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubeconfig_user.md rename to docs/admin/kubeadm_init_phase_etcd_local.md diff --git a/docs/admin/kubeadm_alpha_phase_kubelet.md b/docs/admin/kubeadm_init_phase_kubeconfig.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubelet.md rename to docs/admin/kubeadm_init_phase_kubeconfig.md diff --git a/docs/admin/kubeadm_alpha_phase_kubelet_config.md b/docs/admin/kubeadm_init_phase_kubeconfig_admin.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubelet_config.md rename to docs/admin/kubeadm_init_phase_kubeconfig_admin.md diff --git a/docs/admin/kubeadm_alpha_phase_kubelet_config_annotate-cri.md b/docs/admin/kubeadm_init_phase_kubeconfig_controller-manager.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubelet_config_annotate-cri.md rename to docs/admin/kubeadm_init_phase_kubeconfig_controller-manager.md diff --git a/docs/admin/kubeadm_alpha_phase_kubelet_config_download.md b/docs/admin/kubeadm_init_phase_kubeconfig_kubelet.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubelet_config_download.md rename to docs/admin/kubeadm_init_phase_kubeconfig_kubelet.md diff --git a/docs/admin/kubeadm_alpha_phase_kubelet_config_enable-dynamic.md b/docs/admin/kubeadm_init_phase_kubeconfig_scheduler.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubelet_config_enable-dynamic.md rename to docs/admin/kubeadm_init_phase_kubeconfig_scheduler.md diff --git a/docs/admin/kubeadm_alpha_phase_kubelet_config_upload.md b/docs/admin/kubeadm_init_phase_kubelet-start.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubelet_config_upload.md rename to docs/admin/kubeadm_init_phase_kubelet-start.md diff --git a/docs/admin/kubeadm_alpha_phase_kubelet_config_write-to-disk.md b/docs/admin/kubeadm_init_phase_upload-config.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubelet_config_write-to-disk.md rename to docs/admin/kubeadm_init_phase_upload-config.md diff --git a/docs/admin/kubeadm_alpha_phase_kubelet_write-env-file.md b/docs/admin/kubeadm_init_phase_upload-config_kubeadm.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_kubelet_write-env-file.md rename to docs/admin/kubeadm_init_phase_upload-config_kubeadm.md diff --git a/docs/admin/kubeadm_alpha_phase_preflight.md b/docs/admin/kubeadm_init_phase_upload-config_kubelet.md similarity index 100% rename from docs/admin/kubeadm_alpha_phase_preflight.md rename to docs/admin/kubeadm_init_phase_upload-config_kubelet.md diff --git a/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html b/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html index 3fd1d4de0a36a..4946519869398 100755 --- a/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html +++ b/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html @@ -1078,7 +1078,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

diff --git a/docs/api-reference/admissionregistration.k8s.io/v1alpha1/operations.html b/docs/api-reference/admissionregistration.k8s.io/v1alpha1/operations.html index 7fe652156f1c2..cec8d6646acd5 100755 --- a/docs/api-reference/admissionregistration.k8s.io/v1alpha1/operations.html +++ b/docs/api-reference/admissionregistration.k8s.io/v1alpha1/operations.html @@ -1223,7 +1223,7 @@

Parameters

- + diff --git a/docs/api-reference/admissionregistration.k8s.io/v1beta1/definitions.html b/docs/api-reference/admissionregistration.k8s.io/v1beta1/definitions.html index 2b6ea0060b61d..54c45a2ee44b5 100755 --- a/docs/api-reference/admissionregistration.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/admissionregistration.k8s.io/v1beta1/definitions.html @@ -1345,7 +1345,7 @@

v1.Initializer

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

@@ -1591,7 +1591,7 @@

v1beta1.WebhookClientConfig

- - + @@ -2252,7 +2252,7 @@

Parameters

- + diff --git a/docs/api-reference/apps/v1/definitions.html b/docs/api-reference/apps/v1/definitions.html index c010da959382b..3488071d26678 100755 --- a/docs/api-reference/apps/v1/definitions.html +++ b/docs/api-reference/apps/v1/definitions.html @@ -5974,7 +5974,7 @@

v1.PodReadinessGate

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

url

url gives the location of the webhook, in standard URL form ([scheme://]host:port/path). Exactly one of url or service must be specified.
+

url gives the location of the webhook, in standard URL form (scheme://host:port/path). Exactly one of url or service must be specified.

The host should not refer to a service running in the cluster; use the service field instead. The host might be resolved via external DNS in some apiservers (e.g., kube-apiserver cannot resolve in-cluster DNS as that would be a layering violation). host may also be an IP address.

diff --git a/docs/api-reference/admissionregistration.k8s.io/v1beta1/operations.html b/docs/api-reference/admissionregistration.k8s.io/v1beta1/operations.html index 62e7f4a9db8a6..591710d0eacc8 100755 --- a/docs/api-reference/admissionregistration.k8s.io/v1beta1/operations.html +++ b/docs/api-reference/admissionregistration.k8s.io/v1beta1/operations.html @@ -1223,7 +1223,7 @@

Parameters

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/apps/v1/operations.html b/docs/api-reference/apps/v1/operations.html index f68040ab78ffc..83da59a198934 100755 --- a/docs/api-reference/apps/v1/operations.html +++ b/docs/api-reference/apps/v1/operations.html @@ -1788,7 +1788,7 @@

Parameters

- + @@ -2873,7 +2873,7 @@

Parameters

- + @@ -4358,7 +4358,7 @@

Parameters

- + @@ -6243,7 +6243,7 @@

Parameters

- + @@ -8128,7 +8128,7 @@

Parameters

- + diff --git a/docs/api-reference/apps/v1beta1/definitions.html b/docs/api-reference/apps/v1beta1/definitions.html index c887d75b7c601..cd1c758201748 100755 --- a/docs/api-reference/apps/v1beta1/definitions.html +++ b/docs/api-reference/apps/v1beta1/definitions.html @@ -6047,7 +6047,7 @@

v1.PodReadinessGate

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/apps/v1beta1/operations.html b/docs/api-reference/apps/v1beta1/operations.html index 4ad46d29510c4..735d5c492476d 100755 --- a/docs/api-reference/apps/v1beta1/operations.html +++ b/docs/api-reference/apps/v1beta1/operations.html @@ -1613,7 +1613,7 @@

Parameters

- + @@ -2698,7 +2698,7 @@

Parameters

- + @@ -4736,7 +4736,7 @@

Parameters

- + diff --git a/docs/api-reference/apps/v1beta2/definitions.html b/docs/api-reference/apps/v1beta2/definitions.html index a257ca7121ac7..b092861a42350 100755 --- a/docs/api-reference/apps/v1beta2/definitions.html +++ b/docs/api-reference/apps/v1beta2/definitions.html @@ -6381,7 +6381,7 @@

v1.PodReadinessGate

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/apps/v1beta2/operations.html b/docs/api-reference/apps/v1beta2/operations.html index b2eb766649011..8caa44b12939e 100755 --- a/docs/api-reference/apps/v1beta2/operations.html +++ b/docs/api-reference/apps/v1beta2/operations.html @@ -1788,7 +1788,7 @@

Parameters

- + @@ -2873,7 +2873,7 @@

Parameters

- + @@ -4358,7 +4358,7 @@

Parameters

- + @@ -6243,7 +6243,7 @@

Parameters

- + @@ -8128,7 +8128,7 @@

Parameters

- + diff --git a/docs/api-reference/auditregistration.k8s.io/v1alpha1/definitions.html b/docs/api-reference/auditregistration.k8s.io/v1alpha1/definitions.html index c2b69930434c5..f3327ccb04ae9 100755 --- a/docs/api-reference/auditregistration.k8s.io/v1alpha1/definitions.html +++ b/docs/api-reference/auditregistration.k8s.io/v1alpha1/definitions.html @@ -503,7 +503,7 @@

v1alpha1.WebhookClientConfig

-

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

url

url gives the location of the webhook, in standard URL form ([scheme://]host:port/path). Exactly one of url or service must be specified.
+

url gives the location of the webhook, in standard URL form (scheme://host:port/path). Exactly one of url or service must be specified.

The host should not refer to a service running in the cluster; use the service field instead. The host might be resolved via external DNS in some apiservers (e.g., kube-apiserver cannot resolve in-cluster DNS as that would be a layering violation). host may also be an IP address.

@@ -1165,7 +1165,7 @@

v1alpha1.Stage

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

diff --git a/docs/api-reference/auditregistration.k8s.io/v1alpha1/operations.html b/docs/api-reference/auditregistration.k8s.io/v1alpha1/operations.html index 3296aa210e579..a987f30320900 100755 --- a/docs/api-reference/auditregistration.k8s.io/v1alpha1/operations.html +++ b/docs/api-reference/auditregistration.k8s.io/v1alpha1/operations.html @@ -1223,7 +1223,7 @@

Parameters

- + diff --git a/docs/api-reference/authentication.k8s.io/v1/definitions.html b/docs/api-reference/authentication.k8s.io/v1/definitions.html index 7ed0885ea8aa7..f7cf09b9e698e 100755 --- a/docs/api-reference/authentication.k8s.io/v1/definitions.html +++ b/docs/api-reference/authentication.k8s.io/v1/definitions.html @@ -867,7 +867,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html b/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html index 0d356adb8a176..4ab7aadb51c8d 100755 --- a/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html @@ -956,7 +956,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

diff --git a/docs/api-reference/authorization.k8s.io/v1/definitions.html b/docs/api-reference/authorization.k8s.io/v1/definitions.html index 8768c703458a3..d011c7bd4cb10 100755 --- a/docs/api-reference/authorization.k8s.io/v1/definitions.html +++ b/docs/api-reference/authorization.k8s.io/v1/definitions.html @@ -1079,7 +1079,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

diff --git a/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html b/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html index a9374e6011bdf..1b616d05e42a1 100755 --- a/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html @@ -1282,7 +1282,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

diff --git a/docs/api-reference/autoscaling/v1/definitions.html b/docs/api-reference/autoscaling/v1/definitions.html index 20bd4561a4450..38a8d527341ab 100755 --- a/docs/api-reference/autoscaling/v1/definitions.html +++ b/docs/api-reference/autoscaling/v1/definitions.html @@ -1306,7 +1306,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

diff --git a/docs/api-reference/autoscaling/v1/operations.html b/docs/api-reference/autoscaling/v1/operations.html index 0f6615fda0ca9..d42859fe3eb0f 100755 --- a/docs/api-reference/autoscaling/v1/operations.html +++ b/docs/api-reference/autoscaling/v1/operations.html @@ -1438,7 +1438,7 @@

Parameters

- + diff --git a/docs/api-reference/autoscaling/v2beta1/definitions.html b/docs/api-reference/autoscaling/v2beta1/definitions.html index af9c371bad831..12250efe7de72 100755 --- a/docs/api-reference/autoscaling/v2beta1/definitions.html +++ b/docs/api-reference/autoscaling/v2beta1/definitions.html @@ -1512,7 +1512,7 @@

v1.Initializer

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/autoscaling/v2beta1/operations.html b/docs/api-reference/autoscaling/v2beta1/operations.html index dd1ff9dce9913..2191f08257059 100755 --- a/docs/api-reference/autoscaling/v2beta1/operations.html +++ b/docs/api-reference/autoscaling/v2beta1/operations.html @@ -1438,7 +1438,7 @@

Parameters

- + diff --git a/docs/api-reference/autoscaling/v2beta2/definitions.html b/docs/api-reference/autoscaling/v2beta2/definitions.html index 28559ba3536d9..a5f1a12df7f05 100755 --- a/docs/api-reference/autoscaling/v2beta2/definitions.html +++ b/docs/api-reference/autoscaling/v2beta2/definitions.html @@ -1580,7 +1580,7 @@

v2beta2.ResourceMetricStatus

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/autoscaling/v2beta2/operations.html b/docs/api-reference/autoscaling/v2beta2/operations.html index 89b9ae34159e5..06de82acf6e6a 100755 --- a/docs/api-reference/autoscaling/v2beta2/operations.html +++ b/docs/api-reference/autoscaling/v2beta2/operations.html @@ -1438,7 +1438,7 @@

Parameters

- + diff --git a/docs/api-reference/batch/v1/definitions.html b/docs/api-reference/batch/v1/definitions.html index 281542dd3c9cc..86722b4d38dab 100755 --- a/docs/api-reference/batch/v1/definitions.html +++ b/docs/api-reference/batch/v1/definitions.html @@ -4873,7 +4873,7 @@

v1.PodReadinessGate

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/batch/v1/operations.html b/docs/api-reference/batch/v1/operations.html index 927d146b00ffa..1e3399f62200b 100755 --- a/docs/api-reference/batch/v1/operations.html +++ b/docs/api-reference/batch/v1/operations.html @@ -1438,7 +1438,7 @@

Parameters

- + diff --git a/docs/api-reference/batch/v1beta1/definitions.html b/docs/api-reference/batch/v1beta1/definitions.html index e2e95df2c58f0..edf9e64a1ac1b 100755 --- a/docs/api-reference/batch/v1beta1/definitions.html +++ b/docs/api-reference/batch/v1beta1/definitions.html @@ -4955,7 +4955,7 @@

v1.PodReadinessGate

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/batch/v1beta1/operations.html b/docs/api-reference/batch/v1beta1/operations.html index f57fcbc43129a..05ce546c269bc 100755 --- a/docs/api-reference/batch/v1beta1/operations.html +++ b/docs/api-reference/batch/v1beta1/operations.html @@ -1438,7 +1438,7 @@

Parameters

- + diff --git a/docs/api-reference/batch/v2alpha1/definitions.html b/docs/api-reference/batch/v2alpha1/definitions.html index af02d331c6716..ae28550531e27 100755 --- a/docs/api-reference/batch/v2alpha1/definitions.html +++ b/docs/api-reference/batch/v2alpha1/definitions.html @@ -4811,7 +4811,7 @@

v1.PodReadinessGate

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/batch/v2alpha1/operations.html b/docs/api-reference/batch/v2alpha1/operations.html index a9ee470fa10b7..168eb2799ce10 100755 --- a/docs/api-reference/batch/v2alpha1/operations.html +++ b/docs/api-reference/batch/v2alpha1/operations.html @@ -1438,7 +1438,7 @@

Parameters

- + diff --git a/docs/api-reference/certificates.k8s.io/v1beta1/definitions.html b/docs/api-reference/certificates.k8s.io/v1beta1/definitions.html index 36018f1b0c646..028dd499ac7f7 100755 --- a/docs/api-reference/certificates.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/certificates.k8s.io/v1beta1/definitions.html @@ -1208,7 +1208,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/certificates.k8s.io/v1beta1/operations.html b/docs/api-reference/certificates.k8s.io/v1beta1/operations.html index eaf732045d3f5..af2861d8a6ac6 100755 --- a/docs/api-reference/certificates.k8s.io/v1beta1/operations.html +++ b/docs/api-reference/certificates.k8s.io/v1beta1/operations.html @@ -1223,7 +1223,7 @@

Parameters

- + diff --git a/docs/api-reference/coordination.k8s.io/v1beta1/definitions.html b/docs/api-reference/coordination.k8s.io/v1beta1/definitions.html index 614bb8306a395..f2c34f19ae4f2 100755 --- a/docs/api-reference/coordination.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/coordination.k8s.io/v1beta1/definitions.html @@ -1134,7 +1134,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/coordination.k8s.io/v1beta1/operations.html b/docs/api-reference/coordination.k8s.io/v1beta1/operations.html index a5d163ba04cae..60a415b046b2f 100755 --- a/docs/api-reference/coordination.k8s.io/v1beta1/operations.html +++ b/docs/api-reference/coordination.k8s.io/v1beta1/operations.html @@ -1438,7 +1438,7 @@

Parameters

- + diff --git a/docs/api-reference/events.k8s.io/v1beta1/definitions.html b/docs/api-reference/events.k8s.io/v1beta1/definitions.html index ca20c10e2a1ec..eb262127cbe88 100755 --- a/docs/api-reference/events.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/events.k8s.io/v1beta1/definitions.html @@ -1294,7 +1294,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/events.k8s.io/v1beta1/operations.html b/docs/api-reference/events.k8s.io/v1beta1/operations.html index 1df793c059633..917cb38b85f58 100755 --- a/docs/api-reference/events.k8s.io/v1beta1/operations.html +++ b/docs/api-reference/events.k8s.io/v1beta1/operations.html @@ -1438,7 +1438,7 @@

Parameters

- + diff --git a/docs/api-reference/extensions/v1beta1/definitions.html b/docs/api-reference/extensions/v1beta1/definitions.html index 350f6c7c444ac..8b9523a3cfac6 100755 --- a/docs/api-reference/extensions/v1beta1/definitions.html +++ b/docs/api-reference/extensions/v1beta1/definitions.html @@ -6800,7 +6800,7 @@

v1.PodReadinessGate

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/extensions/v1beta1/operations.html b/docs/api-reference/extensions/v1beta1/operations.html index 0c3f97427517e..5c2b8b33d0bf1 100755 --- a/docs/api-reference/extensions/v1beta1/operations.html +++ b/docs/api-reference/extensions/v1beta1/operations.html @@ -1788,7 +1788,7 @@

Parameters

- + @@ -3273,7 +3273,7 @@

Parameters

- + @@ -5311,7 +5311,7 @@

Parameters

- + @@ -6796,7 +6796,7 @@

Parameters

- + @@ -7881,7 +7881,7 @@

Parameters

- + @@ -10301,7 +10301,7 @@

Parameters

- + diff --git a/docs/api-reference/networking.k8s.io/v1/definitions.html b/docs/api-reference/networking.k8s.io/v1/definitions.html index 8e3d012b6c71a..3531be57311b1 100755 --- a/docs/api-reference/networking.k8s.io/v1/definitions.html +++ b/docs/api-reference/networking.k8s.io/v1/definitions.html @@ -1255,7 +1255,7 @@

v1.NetworkPolicySpec

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/networking.k8s.io/v1/operations.html b/docs/api-reference/networking.k8s.io/v1/operations.html index 7e13d8285e47f..c173cfca0bb59 100755 --- a/docs/api-reference/networking.k8s.io/v1/operations.html +++ b/docs/api-reference/networking.k8s.io/v1/operations.html @@ -1263,7 +1263,7 @@

Parameters

- + diff --git a/docs/api-reference/policy/v1beta1/definitions.html b/docs/api-reference/policy/v1beta1/definitions.html index 639b5d79d2a8e..5ebd79b003e51 100755 --- a/docs/api-reference/policy/v1beta1/definitions.html +++ b/docs/api-reference/policy/v1beta1/definitions.html @@ -1842,7 +1842,7 @@

v1beta1.IDRange

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/policy/v1beta1/operations.html b/docs/api-reference/policy/v1beta1/operations.html index 8b9ac25b3d18c..8b0e4e305efdf 100755 --- a/docs/api-reference/policy/v1beta1/operations.html +++ b/docs/api-reference/policy/v1beta1/operations.html @@ -1263,7 +1263,7 @@

Parameters

- + @@ -2883,7 +2883,7 @@

Parameters

- + diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1/definitions.html b/docs/api-reference/rbac.authorization.k8s.io/v1/definitions.html index 662d503f8cad9..cdf478d80b470 100755 --- a/docs/api-reference/rbac.authorization.k8s.io/v1/definitions.html +++ b/docs/api-reference/rbac.authorization.k8s.io/v1/definitions.html @@ -1468,7 +1468,7 @@

v1.RoleBinding

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1/operations.html b/docs/api-reference/rbac.authorization.k8s.io/v1/operations.html index 3666dd40baeef..6fd8313d76bd2 100755 --- a/docs/api-reference/rbac.authorization.k8s.io/v1/operations.html +++ b/docs/api-reference/rbac.authorization.k8s.io/v1/operations.html @@ -1207,7 +1207,7 @@

Parameters

- + @@ -2220,7 +2220,7 @@

Parameters

- + @@ -3273,7 +3273,7 @@

Parameters

- + @@ -4342,7 +4342,7 @@

Parameters

- + diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/definitions.html b/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/definitions.html index f9e046f2fd2f7..97c67862fa058 100755 --- a/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/definitions.html +++ b/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/definitions.html @@ -1530,7 +1530,7 @@

v1alpha1.ClusterRole

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/operations.html b/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/operations.html index b7da0ae227dc1..362be5f366458 100755 --- a/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/operations.html +++ b/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/operations.html @@ -1207,7 +1207,7 @@

Parameters

- + @@ -2220,7 +2220,7 @@

Parameters

- + @@ -3273,7 +3273,7 @@

Parameters

- + @@ -4342,7 +4342,7 @@

Parameters

- + diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html b/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html index 2e1ebc6faeb9e..4df0542571936 100755 --- a/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html @@ -1468,7 +1468,7 @@

v1beta1.RoleList

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1beta1/operations.html b/docs/api-reference/rbac.authorization.k8s.io/v1beta1/operations.html index 3497beac99fcd..7f663d2955c8e 100755 --- a/docs/api-reference/rbac.authorization.k8s.io/v1beta1/operations.html +++ b/docs/api-reference/rbac.authorization.k8s.io/v1beta1/operations.html @@ -1207,7 +1207,7 @@

Parameters

- + @@ -2220,7 +2220,7 @@

Parameters

- + @@ -3273,7 +3273,7 @@

Parameters

- + @@ -4342,7 +4342,7 @@

Parameters

- + diff --git a/docs/api-reference/scheduling.k8s.io/v1alpha1/definitions.html b/docs/api-reference/scheduling.k8s.io/v1alpha1/definitions.html index 52410f0691e09..66119b6e03422 100755 --- a/docs/api-reference/scheduling.k8s.io/v1alpha1/definitions.html +++ b/docs/api-reference/scheduling.k8s.io/v1alpha1/definitions.html @@ -1024,7 +1024,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/scheduling.k8s.io/v1alpha1/operations.html b/docs/api-reference/scheduling.k8s.io/v1alpha1/operations.html index 0b622f63805ad..6d853cf39808e 100755 --- a/docs/api-reference/scheduling.k8s.io/v1alpha1/operations.html +++ b/docs/api-reference/scheduling.k8s.io/v1alpha1/operations.html @@ -1223,7 +1223,7 @@

Parameters

- + diff --git a/docs/api-reference/scheduling.k8s.io/v1beta1/definitions.html b/docs/api-reference/scheduling.k8s.io/v1beta1/definitions.html index c8a6741907d09..7be6ff6600f82 100755 --- a/docs/api-reference/scheduling.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/scheduling.k8s.io/v1beta1/definitions.html @@ -1093,7 +1093,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/scheduling.k8s.io/v1beta1/operations.html b/docs/api-reference/scheduling.k8s.io/v1beta1/operations.html index 3f1026a1f1e34..41c2853ace8c5 100755 --- a/docs/api-reference/scheduling.k8s.io/v1beta1/operations.html +++ b/docs/api-reference/scheduling.k8s.io/v1beta1/operations.html @@ -1223,7 +1223,7 @@

Parameters

- + diff --git a/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html b/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html index 84807c8819b1e..756be1175777c 100755 --- a/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html +++ b/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html @@ -1892,7 +1892,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/settings.k8s.io/v1alpha1/operations.html b/docs/api-reference/settings.k8s.io/v1alpha1/operations.html index e2e297f6b3141..2e98a7ea7912d 100755 --- a/docs/api-reference/settings.k8s.io/v1alpha1/operations.html +++ b/docs/api-reference/settings.k8s.io/v1alpha1/operations.html @@ -1263,7 +1263,7 @@

Parameters

- + diff --git a/docs/api-reference/storage.k8s.io/v1/definitions.html b/docs/api-reference/storage.k8s.io/v1/definitions.html index 784ba14943298..8b8becbae0253 100755 --- a/docs/api-reference/storage.k8s.io/v1/definitions.html +++ b/docs/api-reference/storage.k8s.io/v1/definitions.html @@ -1220,7 +1220,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/storage.k8s.io/v1/operations.html b/docs/api-reference/storage.k8s.io/v1/operations.html index d3f55607203f6..15ad8bb7119f0 100755 --- a/docs/api-reference/storage.k8s.io/v1/operations.html +++ b/docs/api-reference/storage.k8s.io/v1/operations.html @@ -1223,7 +1223,7 @@

Parameters

- + diff --git a/docs/api-reference/storage.k8s.io/v1alpha1/definitions.html b/docs/api-reference/storage.k8s.io/v1alpha1/definitions.html index 07c72e39fca94..b2e678d8ab01c 100755 --- a/docs/api-reference/storage.k8s.io/v1alpha1/definitions.html +++ b/docs/api-reference/storage.k8s.io/v1alpha1/definitions.html @@ -1113,7 +1113,7 @@

v1.ObjectMeta

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/storage.k8s.io/v1alpha1/operations.html b/docs/api-reference/storage.k8s.io/v1alpha1/operations.html index 31855a9015bfb..300715e598abd 100755 --- a/docs/api-reference/storage.k8s.io/v1alpha1/operations.html +++ b/docs/api-reference/storage.k8s.io/v1alpha1/operations.html @@ -1223,7 +1223,7 @@

Parameters

- + diff --git a/docs/api-reference/storage.k8s.io/v1beta1/definitions.html b/docs/api-reference/storage.k8s.io/v1beta1/definitions.html index 6e0585570978b..c8f95f8fbd9e5 100755 --- a/docs/api-reference/storage.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/storage.k8s.io/v1beta1/definitions.html @@ -1302,7 +1302,7 @@

v1beta1.StorageClass

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/storage.k8s.io/v1beta1/operations.html b/docs/api-reference/storage.k8s.io/v1beta1/operations.html index 9cab5a7848b91..0d48d92ca4b12 100755 --- a/docs/api-reference/storage.k8s.io/v1beta1/operations.html +++ b/docs/api-reference/storage.k8s.io/v1beta1/operations.html @@ -1223,7 +1223,7 @@

Parameters

- + @@ -2252,7 +2252,7 @@

Parameters

- + diff --git a/docs/api-reference/v1/definitions.html b/docs/api-reference/v1/definitions.html index 04527c20854af..92d31c760e2fd 100755 --- a/docs/api-reference/v1/definitions.html +++ b/docs/api-reference/v1/definitions.html @@ -10780,7 +10780,7 @@

v1.ComponentCondition

v1.OwnerReference

-

OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.

+

OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

diff --git a/docs/api-reference/v1/operations.html b/docs/api-reference/v1/operations.html index 24bead93080e9..da2acd1777ef5 100755 --- a/docs/api-reference/v1/operations.html +++ b/docs/api-reference/v1/operations.html @@ -2706,7 +2706,7 @@

Parameters

- + @@ -3791,7 +3791,7 @@

Parameters

- + @@ -4876,7 +4876,7 @@

Parameters

- + @@ -5961,7 +5961,7 @@

Parameters

- + @@ -7046,7 +7046,7 @@

Parameters

- + @@ -8531,7 +8531,7 @@

Parameters

- + @@ -12492,7 +12492,7 @@

Parameters

- + @@ -13577,7 +13577,7 @@

Parameters

- + @@ -15462,7 +15462,7 @@

Parameters

- + @@ -16947,7 +16947,7 @@

Parameters

- + @@ -18032,7 +18032,7 @@

Parameters

- + @@ -18940,7 +18940,7 @@

Parameters

- + @@ -21074,7 +21074,7 @@

Parameters

- + @@ -22611,7 +22611,7 @@

Parameters

- + @@ -25281,7 +25281,7 @@

Parameters

- + diff --git a/docs/admin/kubeadm_alpha_phase_preflight_node.md b/docs/man/man1/kubeadm-alpha-certs-renew-all.1 similarity index 100% rename from docs/admin/kubeadm_alpha_phase_preflight_node.md rename to docs/man/man1/kubeadm-alpha-certs-renew-all.1 diff --git a/docs/admin/kubeadm_alpha_phase_upload-config.md b/docs/man/man1/kubeadm-alpha-certs-renew-apiserver-etcd-client.1 similarity index 100% rename from docs/admin/kubeadm_alpha_phase_upload-config.md rename to docs/man/man1/kubeadm-alpha-certs-renew-apiserver-etcd-client.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-all.1 b/docs/man/man1/kubeadm-alpha-certs-renew-apiserver-kubelet-client.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-all.1 rename to docs/man/man1/kubeadm-alpha-certs-renew-apiserver-kubelet-client.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-apiserver-etcd-client.1 b/docs/man/man1/kubeadm-alpha-certs-renew-apiserver.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-apiserver-etcd-client.1 rename to docs/man/man1/kubeadm-alpha-certs-renew-apiserver.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-apiserver-kubelet-client.1 b/docs/man/man1/kubeadm-alpha-certs-renew-etcd-healthcheck-client.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-apiserver-kubelet-client.1 rename to docs/man/man1/kubeadm-alpha-certs-renew-etcd-healthcheck-client.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-apiserver.1 b/docs/man/man1/kubeadm-alpha-certs-renew-etcd-peer.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-apiserver.1 rename to docs/man/man1/kubeadm-alpha-certs-renew-etcd-peer.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-ca.1 b/docs/man/man1/kubeadm-alpha-certs-renew-etcd-server.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-ca.1 rename to docs/man/man1/kubeadm-alpha-certs-renew-etcd-server.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-etcd-ca.1 b/docs/man/man1/kubeadm-alpha-certs-renew-front-proxy-client.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-etcd-ca.1 rename to docs/man/man1/kubeadm-alpha-certs-renew-front-proxy-client.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-etcd-healthcheck-client.1 b/docs/man/man1/kubeadm-alpha-certs-renew.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-etcd-healthcheck-client.1 rename to docs/man/man1/kubeadm-alpha-certs-renew.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-etcd-peer.1 b/docs/man/man1/kubeadm-alpha-certs.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-etcd-peer.1 rename to docs/man/man1/kubeadm-alpha-certs.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-etcd-server.1 b/docs/man/man1/kubeadm-alpha-kubeconfig-user.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-etcd-server.1 rename to docs/man/man1/kubeadm-alpha-kubeconfig-user.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-front-proxy-ca.1 b/docs/man/man1/kubeadm-alpha-kubeconfig.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-front-proxy-ca.1 rename to docs/man/man1/kubeadm-alpha-kubeconfig.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-front-proxy-client.1 b/docs/man/man1/kubeadm-alpha-kubelet-config-download.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-front-proxy-client.1 rename to docs/man/man1/kubeadm-alpha-kubelet-config-download.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew-all.1 b/docs/man/man1/kubeadm-alpha-kubelet-config-enable-dynamic.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew-all.1 rename to docs/man/man1/kubeadm-alpha-kubelet-config-enable-dynamic.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-etcd-client.1 b/docs/man/man1/kubeadm-alpha-kubelet-config.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-etcd-client.1 rename to docs/man/man1/kubeadm-alpha-kubelet-config.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-kubelet-client.1 b/docs/man/man1/kubeadm-alpha-kubelet.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-kubelet-client.1 rename to docs/man/man1/kubeadm-alpha-kubelet.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubelet.1 b/docs/man/man1/kubeadm-alpha-phase-kubelet.1 deleted file mode 100644 index b6fd7a0f9896b..0000000000000 --- a/docs/man/man1/kubeadm-alpha-phase-kubelet.1 +++ /dev/null @@ -1,3 +0,0 @@ -This file is autogenerated, but we've stopped checking such files into the -repository to reduce the need for rebases. Please run hack/generate-docs.sh to -populate this file. diff --git a/docs/man/man1/kubeadm-alpha-phase-preflight-node.1 b/docs/man/man1/kubeadm-alpha-phase-preflight-node.1 deleted file mode 100644 index b6fd7a0f9896b..0000000000000 --- a/docs/man/man1/kubeadm-alpha-phase-preflight-node.1 +++ /dev/null @@ -1,3 +0,0 @@ -This file is autogenerated, but we've stopped checking such files into the -repository to reduce the need for rebases. Please run hack/generate-docs.sh to -populate this file. diff --git a/docs/man/man1/kubeadm-alpha-phase-preflight.1 b/docs/man/man1/kubeadm-alpha-phase-preflight.1 deleted file mode 100644 index b6fd7a0f9896b..0000000000000 --- a/docs/man/man1/kubeadm-alpha-phase-preflight.1 +++ /dev/null @@ -1,3 +0,0 @@ -This file is autogenerated, but we've stopped checking such files into the -repository to reduce the need for rebases. Please run hack/generate-docs.sh to -populate this file. diff --git a/docs/man/man1/kubeadm-alpha-phase-upload-config.1 b/docs/man/man1/kubeadm-alpha-phase-upload-config.1 deleted file mode 100644 index b6fd7a0f9896b..0000000000000 --- a/docs/man/man1/kubeadm-alpha-phase-upload-config.1 +++ /dev/null @@ -1,3 +0,0 @@ -This file is autogenerated, but we've stopped checking such files into the -repository to reduce the need for rebases. Please run hack/generate-docs.sh to -populate this file. diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver.1 b/docs/man/man1/kubeadm-alpha-preflight-node.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver.1 rename to docs/man/man1/kubeadm-alpha-preflight-node.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-healthcheck-client.1 b/docs/man/man1/kubeadm-alpha-preflight.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-healthcheck-client.1 rename to docs/man/man1/kubeadm-alpha-preflight.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-peer.1 b/docs/man/man1/kubeadm-init-phase-certs-apiserver-etcd-client.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-peer.1 rename to docs/man/man1/kubeadm-init-phase-certs-apiserver-etcd-client.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-server.1 b/docs/man/man1/kubeadm-init-phase-certs-apiserver-kubelet-client.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-server.1 rename to docs/man/man1/kubeadm-init-phase-certs-apiserver-kubelet-client.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew-front-proxy-client.1 b/docs/man/man1/kubeadm-init-phase-certs-apiserver.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew-front-proxy-client.1 rename to docs/man/man1/kubeadm-init-phase-certs-apiserver.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-renew.1 b/docs/man/man1/kubeadm-init-phase-certs-ca.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-renew.1 rename to docs/man/man1/kubeadm-init-phase-certs-ca.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs-sa.1 b/docs/man/man1/kubeadm-init-phase-certs-etcd-ca.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs-sa.1 rename to docs/man/man1/kubeadm-init-phase-certs-etcd-ca.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-certs.1 b/docs/man/man1/kubeadm-init-phase-certs-etcd-healthcheck-client.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-certs.1 rename to docs/man/man1/kubeadm-init-phase-certs-etcd-healthcheck-client.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-controlplane-all.1 b/docs/man/man1/kubeadm-init-phase-certs-etcd-peer.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-controlplane-all.1 rename to docs/man/man1/kubeadm-init-phase-certs-etcd-peer.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-controlplane-apiserver.1 b/docs/man/man1/kubeadm-init-phase-certs-etcd-server.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-controlplane-apiserver.1 rename to docs/man/man1/kubeadm-init-phase-certs-etcd-server.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-controlplane-controller-manager.1 b/docs/man/man1/kubeadm-init-phase-certs-front-proxy-ca.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-controlplane-controller-manager.1 rename to docs/man/man1/kubeadm-init-phase-certs-front-proxy-ca.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-controlplane-scheduler.1 b/docs/man/man1/kubeadm-init-phase-certs-front-proxy-client.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-controlplane-scheduler.1 rename to docs/man/man1/kubeadm-init-phase-certs-front-proxy-client.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-controlplane.1 b/docs/man/man1/kubeadm-init-phase-certs-sa.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-controlplane.1 rename to docs/man/man1/kubeadm-init-phase-certs-sa.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-etcd-local.1 b/docs/man/man1/kubeadm-init-phase-certs.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-etcd-local.1 rename to docs/man/man1/kubeadm-init-phase-certs.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-etcd.1 b/docs/man/man1/kubeadm-init-phase-control-plane-apiserver.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-etcd.1 rename to docs/man/man1/kubeadm-init-phase-control-plane-apiserver.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubeconfig-admin.1 b/docs/man/man1/kubeadm-init-phase-control-plane-controller-manager.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubeconfig-admin.1 rename to docs/man/man1/kubeadm-init-phase-control-plane-controller-manager.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubeconfig-all.1 b/docs/man/man1/kubeadm-init-phase-control-plane-scheduler.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubeconfig-all.1 rename to docs/man/man1/kubeadm-init-phase-control-plane-scheduler.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubeconfig-controller-manager.1 b/docs/man/man1/kubeadm-init-phase-control-plane.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubeconfig-controller-manager.1 rename to docs/man/man1/kubeadm-init-phase-control-plane.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubeconfig-kubelet.1 b/docs/man/man1/kubeadm-init-phase-etcd-local.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubeconfig-kubelet.1 rename to docs/man/man1/kubeadm-init-phase-etcd-local.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubeconfig-scheduler.1 b/docs/man/man1/kubeadm-init-phase-etcd.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubeconfig-scheduler.1 rename to docs/man/man1/kubeadm-init-phase-etcd.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubeconfig-user.1 b/docs/man/man1/kubeadm-init-phase-kubeconfig-admin.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubeconfig-user.1 rename to docs/man/man1/kubeadm-init-phase-kubeconfig-admin.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubeconfig.1 b/docs/man/man1/kubeadm-init-phase-kubeconfig-controller-manager.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubeconfig.1 rename to docs/man/man1/kubeadm-init-phase-kubeconfig-controller-manager.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubelet-config-annotate-cri.1 b/docs/man/man1/kubeadm-init-phase-kubeconfig-kubelet.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubelet-config-annotate-cri.1 rename to docs/man/man1/kubeadm-init-phase-kubeconfig-kubelet.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubelet-config-download.1 b/docs/man/man1/kubeadm-init-phase-kubeconfig-scheduler.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubelet-config-download.1 rename to docs/man/man1/kubeadm-init-phase-kubeconfig-scheduler.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubelet-config-enable-dynamic.1 b/docs/man/man1/kubeadm-init-phase-kubeconfig.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubelet-config-enable-dynamic.1 rename to docs/man/man1/kubeadm-init-phase-kubeconfig.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubelet-config-upload.1 b/docs/man/man1/kubeadm-init-phase-kubelet-start.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubelet-config-upload.1 rename to docs/man/man1/kubeadm-init-phase-kubelet-start.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubelet-config-write-to-disk.1 b/docs/man/man1/kubeadm-init-phase-upload-config-kubeadm.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubelet-config-write-to-disk.1 rename to docs/man/man1/kubeadm-init-phase-upload-config-kubeadm.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubelet-config.1 b/docs/man/man1/kubeadm-init-phase-upload-config-kubelet.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubelet-config.1 rename to docs/man/man1/kubeadm-init-phase-upload-config-kubelet.1 diff --git a/docs/man/man1/kubeadm-alpha-phase-kubelet-write-env-file.1 b/docs/man/man1/kubeadm-init-phase-upload-config.1 similarity index 100% rename from docs/man/man1/kubeadm-alpha-phase-kubelet-write-env-file.1 rename to docs/man/man1/kubeadm-init-phase-upload-config.1 diff --git a/hack/.golint_failures b/hack/.golint_failures index ce739fc56b4a2..61342e2cf4e81 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -88,7 +88,6 @@ pkg/apis/storage/v1beta1/util pkg/auth/authorizer/abac pkg/capabilities pkg/cloudprovider/providers/fake -pkg/cloudprovider/providers/gce pkg/cloudprovider/providers/gce/cloud pkg/cloudprovider/providers/ovirt pkg/cloudprovider/providers/photon @@ -135,14 +134,9 @@ pkg/credentialprovider/gcp pkg/credentialprovider/rancher pkg/features pkg/kubeapiserver -pkg/kubeapiserver/admission -pkg/kubeapiserver/authenticator -pkg/kubeapiserver/authorizer -pkg/kubeapiserver/authorizer/modes pkg/kubeapiserver/options pkg/kubectl pkg/kubectl/apps -pkg/kubectl/cmd pkg/kubectl/cmd/annotate pkg/kubectl/cmd/apiresources pkg/kubectl/cmd/apply @@ -190,8 +184,6 @@ pkg/kubectl/cmd/wait pkg/kubectl/generate pkg/kubectl/generate/versioned pkg/kubectl/metricsutil -pkg/kubectl/util -pkg/kubectl/util/slice pkg/kubectl/util/templates pkg/kubelet pkg/kubelet/apis @@ -380,7 +372,6 @@ pkg/util/env pkg/util/file pkg/util/goroutinemap/exponentialbackoff pkg/util/initsystem -pkg/util/ipconfig pkg/util/iptables pkg/util/iptables/testing pkg/util/labels @@ -391,7 +382,6 @@ pkg/util/oom pkg/util/parsers pkg/util/procfs pkg/util/removeall -pkg/util/resourcecontainer pkg/util/rlimit pkg/util/selinux pkg/util/sysctl @@ -403,8 +393,6 @@ pkg/version/verflag pkg/volume pkg/volume/azure_dd pkg/volume/azure_file -pkg/volume/cephfs -pkg/volume/configmap pkg/volume/csi/fake pkg/volume/git_repo pkg/volume/host_path @@ -415,7 +403,6 @@ pkg/volume/photon_pd pkg/volume/portworx pkg/volume/rbd pkg/volume/scaleio -pkg/volume/secret pkg/volume/storageos pkg/volume/testing pkg/volume/util/fs @@ -777,6 +764,4 @@ test/integration/replicationcontroller test/integration/scheduler test/integration/scheduler_perf test/integration/volume -test/list test/utils -test/utils/image diff --git a/hack/ginkgo-e2e.sh b/hack/ginkgo-e2e.sh index 0cac8afc6baba..6354966a2cc90 100755 --- a/hack/ginkgo-e2e.sh +++ b/hack/ginkgo-e2e.sh @@ -161,6 +161,7 @@ export PATH=$(dirname "${e2e_test}"):"${PATH}" --master-tag="${MASTER_TAG:-}" \ --cluster-monitoring-mode="${KUBE_ENABLE_CLUSTER_MONITORING:-standalone}" \ --prometheus-monitoring="${KUBE_ENABLE_PROMETHEUS_MONITORING:-false}" \ + --dns-domain="${KUBE_DNS_DOMAIN:-cluster.local}" \ ${KUBE_CONTAINER_RUNTIME:+"--container-runtime=${KUBE_CONTAINER_RUNTIME}"} \ ${MASTER_OS_DISTRIBUTION:+"--master-os-distro=${MASTER_OS_DISTRIBUTION}"} \ ${NODE_OS_DISTRIBUTION:+"--node-os-distro=${NODE_OS_DISTRIBUTION}"} \ diff --git a/hack/import-restrictions.yaml b/hack/import-restrictions.yaml index 4507c8305cb72..12f53d659d3dd 100644 --- a/hack/import-restrictions.yaml +++ b/hack/import-restrictions.yaml @@ -11,10 +11,10 @@ # the following are temporary and should go away. Think twice (or more) before adding anything here. # Main goal: pkg/apis should be as self-contained as possible. - - k8s.io/kubernetes/pkg/apis/extensions + - k8s.io/kubernetes/pkg/apis/apps - k8s.io/kubernetes/pkg/api/legacyscheme - k8s.io/kubernetes/pkg/api/testapi - - k8s.io/api/extensions/v1beta1 + - k8s.io/api/apps/v1 ignoredSubTrees: - "./pkg/apis/core/validation" diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 865c269ebe55e..7c9edb94dd9a3 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -74,16 +74,6 @@ INTERNAL_DIRS_CSV=$(IFS=',';echo "${INTERNAL_DIRS[*]// /,}";IFS=$) ${clientgen} --input-base="k8s.io/kubernetes/pkg/apis" --input="${INTERNAL_DIRS_CSV}" "$@" ${clientgen} --output-base "${KUBE_ROOT}/vendor" --output-package="k8s.io/client-go" --clientset-name="kubernetes" --input-base="k8s.io/kubernetes/vendor/k8s.io/api" --input="${GV_DIRS_CSV}" --go-header-file ${KUBE_ROOT}/hack/boilerplate/boilerplate.generatego.txt "$@" -listergen_internal_apis=( -$( - cd ${KUBE_ROOT} - find pkg/apis -maxdepth 2 -name types.go | xargs -n1 dirname | sort -) -) -listergen_internal_apis=(${listergen_internal_apis[@]/#/k8s.io/kubernetes/}) -listergen_internal_apis_csv=$(IFS=,; echo "${listergen_internal_apis[*]}") -${listergen} --input-dirs "${listergen_internal_apis_csv}" "$@" - listergen_external_apis=( $( cd ${KUBE_ROOT}/staging/src @@ -93,21 +83,6 @@ $( listergen_external_apis_csv=$(IFS=,; echo "${listergen_external_apis[*]}") ${listergen} --output-base "${KUBE_ROOT}/vendor" --output-package "k8s.io/client-go/listers" --input-dirs "${listergen_external_apis_csv}" --go-header-file ${KUBE_ROOT}/hack/boilerplate/boilerplate.generatego.txt "$@" -informergen_internal_apis=( -$( - cd ${KUBE_ROOT} - find pkg/apis -maxdepth 2 -name types.go | xargs -n1 dirname | sort -) -) -informergen_internal_apis=(${informergen_internal_apis[@]/#/k8s.io/kubernetes/}) -informergen_internal_apis_csv=$(IFS=,; echo "${informergen_internal_apis[*]}") -${informergen} \ - --input-dirs "${informergen_internal_apis_csv}" \ - --internal-clientset-package k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset \ - --listers-package k8s.io/kubernetes/pkg/client/listers \ - --go-header-file ${KUBE_ROOT}/hack/boilerplate/boilerplate.generatego.txt \ - "$@" - informergen_external_apis=( $( cd ${KUBE_ROOT}/staging/src diff --git a/pkg/BUILD b/pkg/BUILD index 7a9acd421c906..84b7252c89235 100644 --- a/pkg/BUILD +++ b/pkg/BUILD @@ -55,26 +55,7 @@ filegroup( "//pkg/capabilities:all-srcs", "//pkg/client/clientset_generated/internalclientset:all-srcs", "//pkg/client/conditions:all-srcs", - "//pkg/client/informers/informers_generated/internalversion:all-srcs", "//pkg/client/leaderelectionconfig:all-srcs", - "//pkg/client/listers/admissionregistration/internalversion:all-srcs", - "//pkg/client/listers/apps/internalversion:all-srcs", - "//pkg/client/listers/auditregistration/internalversion:all-srcs", - "//pkg/client/listers/authentication/internalversion:all-srcs", - "//pkg/client/listers/authorization/internalversion:all-srcs", - "//pkg/client/listers/autoscaling/internalversion:all-srcs", - "//pkg/client/listers/batch/internalversion:all-srcs", - "//pkg/client/listers/certificates/internalversion:all-srcs", - "//pkg/client/listers/coordination/internalversion:all-srcs", - "//pkg/client/listers/core/internalversion:all-srcs", - "//pkg/client/listers/extensions/internalversion:all-srcs", - "//pkg/client/listers/imagepolicy/internalversion:all-srcs", - "//pkg/client/listers/networking/internalversion:all-srcs", - "//pkg/client/listers/policy/internalversion:all-srcs", - "//pkg/client/listers/rbac/internalversion:all-srcs", - "//pkg/client/listers/scheduling/internalversion:all-srcs", - "//pkg/client/listers/settings/internalversion:all-srcs", - "//pkg/client/listers/storage/internalversion:all-srcs", "//pkg/client/metrics/prometheus:all-srcs", "//pkg/client/testdata:all-srcs", "//pkg/client/tests:all-srcs", diff --git a/pkg/api/pod/util.go b/pkg/api/pod/util.go index b9f875e57a77b..d519c9a25ff30 100644 --- a/pkg/api/pod/util.go +++ b/pkg/api/pod/util.go @@ -248,13 +248,6 @@ func DropDisabledAlphaFields(podSpec *api.PodSpec) { } } - for i := range podSpec.Containers { - DropDisabledVolumeMountsAlphaFields(podSpec.Containers[i].VolumeMounts) - } - for i := range podSpec.InitContainers { - DropDisabledVolumeMountsAlphaFields(podSpec.InitContainers[i].VolumeMounts) - } - DropDisabledVolumeDevicesAlphaFields(podSpec) DropDisabledRunAsGroupField(podSpec) @@ -304,16 +297,6 @@ func DropDisabledProcMountField(podSpec *api.PodSpec) { } } -// DropDisabledVolumeMountsAlphaFields removes disabled fields from []VolumeMount. -// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a VolumeMount -func DropDisabledVolumeMountsAlphaFields(volumeMounts []api.VolumeMount) { - if !utilfeature.DefaultFeatureGate.Enabled(features.MountPropagation) { - for i := range volumeMounts { - volumeMounts[i].MountPropagation = nil - } - } -} - // DropDisabledVolumeDevicesAlphaFields removes disabled fields from []VolumeDevice. // This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a VolumeDevice func DropDisabledVolumeDevicesAlphaFields(podSpec *api.PodSpec) { diff --git a/pkg/api/testing/BUILD b/pkg/api/testing/BUILD index b65e2839b64db..7f3b5aecdfcdb 100644 --- a/pkg/api/testing/BUILD +++ b/pkg/api/testing/BUILD @@ -18,6 +18,7 @@ go_library( deps = [ "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/admissionregistration/fuzzer:go_default_library", + "//pkg/apis/apps:go_default_library", "//pkg/apis/apps/fuzzer:go_default_library", "//pkg/apis/auditregistration/fuzzer:go_default_library", "//pkg/apis/autoscaling/fuzzer:go_default_library", @@ -25,13 +26,12 @@ go_library( "//pkg/apis/certificates/fuzzer:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/fuzzer:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/fuzzer:go_default_library", - "//pkg/apis/extensions/v1beta1:go_default_library", "//pkg/apis/networking/fuzzer:go_default_library", "//pkg/apis/policy/fuzzer:go_default_library", "//pkg/apis/rbac/fuzzer:go_default_library", "//pkg/apis/storage/fuzzer:go_default_library", + "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/apitesting:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/apitesting/fuzzer:go_default_library", @@ -78,12 +78,15 @@ go_test( "//pkg/api/legacyscheme:go_default_library", "//pkg/api/testapi:go_default_library", "//pkg/api/testing/compat:go_default_library", + "//pkg/apis/apps:go_default_library", + "//pkg/apis/apps/v1:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/install:go_default_library", "//pkg/apis/core/v1:go_default_library", "//pkg/apis/core/validation:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", + "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/apitesting/fuzzer:go_default_library", diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index 65b5f42bf907e..b8614b9838a0d 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -21,6 +21,7 @@ import ( fuzz "github.com/google/gofuzz" + appsv1 "k8s.io/api/apps/v1" "k8s.io/api/core/v1" apitesting "k8s.io/apimachinery/pkg/api/apitesting" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" @@ -28,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" admissionregistrationfuzzer "k8s.io/kubernetes/pkg/apis/admissionregistration/fuzzer" + "k8s.io/kubernetes/pkg/apis/apps" appsfuzzer "k8s.io/kubernetes/pkg/apis/apps/fuzzer" auditregistrationfuzzer "k8s.io/kubernetes/pkg/apis/auditregistration/fuzzer" autoscalingfuzzer "k8s.io/kubernetes/pkg/apis/autoscaling/fuzzer" @@ -35,9 +37,7 @@ import ( certificatesfuzzer "k8s.io/kubernetes/pkg/apis/certificates/fuzzer" api "k8s.io/kubernetes/pkg/apis/core" corefuzzer "k8s.io/kubernetes/pkg/apis/core/fuzzer" - "k8s.io/kubernetes/pkg/apis/extensions" extensionsfuzzer "k8s.io/kubernetes/pkg/apis/extensions/fuzzer" - extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" networkingfuzzer "k8s.io/kubernetes/pkg/apis/networking/fuzzer" policyfuzzer "k8s.io/kubernetes/pkg/apis/policy/fuzzer" rbacfuzzer "k8s.io/kubernetes/pkg/apis/rbac/fuzzer" @@ -65,14 +65,14 @@ func overrideGenericFuncs(codecs runtimeserializer.CodecFactory) []interface{} { }, func(r *runtime.RawExtension, c fuzz.Continue) { // Pick an arbitrary type and fuzz it - types := []runtime.Object{&api.Pod{}, &extensions.Deployment{}, &api.Service{}} + types := []runtime.Object{&api.Pod{}, &apps.Deployment{}, &api.Service{}} obj := types[c.Rand.Intn(len(types))] c.Fuzz(obj) var codec runtime.Codec switch obj.(type) { - case *extensions.Deployment: - codec = apitesting.TestCodec(codecs, extensionsv1beta1.SchemeGroupVersion) + case *apps.Deployment: + codec = apitesting.TestCodec(codecs, appsv1.SchemeGroupVersion) default: codec = apitesting.TestCodec(codecs, v1.SchemeGroupVersion) } diff --git a/pkg/api/testing/serialization_test.go b/pkg/api/testing/serialization_test.go index 4655dae9cf6cd..4b3fa2d95d802 100644 --- a/pkg/api/testing/serialization_test.go +++ b/pkg/api/testing/serialization_test.go @@ -27,8 +27,8 @@ import ( jsoniter "github.com/json-iterator/go" + appsv1 "k8s.io/api/apps/v1" "k8s.io/api/core/v1" - "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/roundtrip" apiequality "k8s.io/apimachinery/pkg/api/equality" @@ -44,10 +44,10 @@ import ( "k8s.io/apimachinery/pkg/watch" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/apis/apps" + k8s_apps_v1 "k8s.io/kubernetes/pkg/apis/apps/v1" api "k8s.io/kubernetes/pkg/apis/core" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" - "k8s.io/kubernetes/pkg/apis/extensions" - k8s_v1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" ) // fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate @@ -65,14 +65,14 @@ func fuzzInternalObject(t *testing.T, forVersion schema.GroupVersion, item runti return item } -func ConvertV1beta1ReplicaSetToAPIReplicationController(in *v1beta1.ReplicaSet, out *api.ReplicationController, s conversion.Scope) error { - intermediate1 := &extensions.ReplicaSet{} - if err := k8s_v1beta1.Convert_v1beta1_ReplicaSet_To_extensions_ReplicaSet(in, intermediate1, s); err != nil { +func ConvertV1ReplicaSetToAPIReplicationController(in *appsv1.ReplicaSet, out *api.ReplicationController, s conversion.Scope) error { + intermediate1 := &apps.ReplicaSet{} + if err := k8s_apps_v1.Convert_v1_ReplicaSet_To_apps_ReplicaSet(in, intermediate1, s); err != nil { return err } intermediate2 := &v1.ReplicationController{} - if err := k8s_api_v1.Convert_extensions_ReplicaSet_To_v1_ReplicationController(intermediate1, intermediate2, s); err != nil { + if err := k8s_api_v1.Convert_apps_ReplicaSet_To_v1_ReplicationController(intermediate1, intermediate2, s); err != nil { return err } @@ -80,17 +80,17 @@ func ConvertV1beta1ReplicaSetToAPIReplicationController(in *v1beta1.ReplicaSet, } func TestSetControllerConversion(t *testing.T) { - if err := legacyscheme.Scheme.AddConversionFuncs(ConvertV1beta1ReplicaSetToAPIReplicationController); err != nil { + if err := legacyscheme.Scheme.AddConversionFuncs(ConvertV1ReplicaSetToAPIReplicationController); err != nil { t.Fatal(err) } - rs := &extensions.ReplicaSet{} + rs := &apps.ReplicaSet{} rc := &api.ReplicationController{} - extGroup := testapi.Extensions + extGroup := testapi.Apps defaultGroup := testapi.Default - fuzzInternalObject(t, schema.GroupVersion{Group: "extensions", Version: runtime.APIVersionInternal}, rs, rand.Int63()) + fuzzInternalObject(t, schema.GroupVersion{Group: "apps", Version: runtime.APIVersionInternal}, rs, rand.Int63()) // explicitly set the selector to something that is convertible to old-style selectors // (since normally we'll fuzz the selectors with things that aren't convertible) @@ -101,7 +101,7 @@ func TestSetControllerConversion(t *testing.T) { }, } - t.Logf("rs._internal.extensions -> rs.v1beta1.extensions") + t.Logf("rs._internal.apps -> rs.v1.apps") data, err := runtime.Encode(extGroup.Codec(), rs) if err != nil { t.Fatalf("unexpected encoding error: %v", err) @@ -116,7 +116,7 @@ func TestSetControllerConversion(t *testing.T) { ), ) - t.Logf("rs.v1beta1.extensions -> rc._internal") + t.Logf("rs.v1.apps -> rc._internal") if err := runtime.DecodeInto(decoder, data, rc); err != nil { t.Fatalf("unexpected decoding error: %v", err) } @@ -127,7 +127,7 @@ func TestSetControllerConversion(t *testing.T) { t.Fatalf("unexpected encoding error: %v", err) } - t.Logf("rc.v1 -> rs._internal.extensions") + t.Logf("rc.v1 -> rs._internal.apps") if err := runtime.DecodeInto(decoder, data, rs); err != nil { t.Fatalf("unexpected decoding error: %v", err) } @@ -138,7 +138,7 @@ func TestSetControllerConversion(t *testing.T) { func TestSpecificKind(t *testing.T) { // Uncomment the following line to enable logging of which conversions // legacyscheme.Scheme.Log(t) - internalGVK := schema.GroupVersionKind{Group: "extensions", Version: runtime.APIVersionInternal, Kind: "DaemonSet"} + internalGVK := schema.GroupVersionKind{Group: "apps", Version: runtime.APIVersionInternal, Kind: "DaemonSet"} seed := rand.Int63() fuzzer := fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(seed), legacyscheme.Codecs) diff --git a/pkg/apis/admissionregistration/types.go b/pkg/apis/admissionregistration/types.go index 70b810ababa3e..e8880c49c648b 100644 --- a/pkg/apis/admissionregistration/types.go +++ b/pkg/apis/admissionregistration/types.go @@ -290,7 +290,7 @@ const ( // connection with the webhook type WebhookClientConfig struct { // `url` gives the location of the webhook, in standard URL form - // (`[scheme://]host:port/path`). Exactly one of `url` or `service` + // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // // The `host` should not refer to a service running in the cluster; use diff --git a/pkg/apis/admissionregistration/validation/BUILD b/pkg/apis/admissionregistration/validation/BUILD index ad662b73d4ce5..7efababb33dd8 100644 --- a/pkg/apis/admissionregistration/validation/BUILD +++ b/pkg/apis/admissionregistration/validation/BUILD @@ -27,6 +27,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", ], ) diff --git a/pkg/apis/admissionregistration/validation/validation.go b/pkg/apis/admissionregistration/validation/validation.go index 9174bb0835a5e..4f0fe60b2f014 100644 --- a/pkg/apis/admissionregistration/validation/validation.go +++ b/pkg/apis/admissionregistration/validation/validation.go @@ -18,7 +18,6 @@ package validation import ( "fmt" - "net/url" "strings" genericvalidation "k8s.io/apimachinery/pkg/api/validation" @@ -26,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/util/webhook" "k8s.io/kubernetes/pkg/apis/admissionregistration" ) @@ -200,93 +200,15 @@ func validateWebhook(hook *admissionregistration.Webhook, fldPath *field.Path) f allErrors = append(allErrors, metav1validation.ValidateLabelSelector(hook.NamespaceSelector, fldPath.Child("namespaceSelector"))...) } - allErrors = append(allErrors, validateWebhookClientConfig(fldPath.Child("clientConfig"), &hook.ClientConfig)...) - - return allErrors -} - -func validateWebhookClientConfig(fldPath *field.Path, cc *admissionregistration.WebhookClientConfig) field.ErrorList { - var allErrors field.ErrorList - if (cc.URL == nil) == (cc.Service == nil) { - allErrors = append(allErrors, field.Required(fldPath.Child("url"), "exactly one of url or service is required")) + cc := hook.ClientConfig + switch { + case (cc.URL == nil) == (cc.Service == nil): + allErrors = append(allErrors, field.Required(fldPath.Child("clientConfig"), "exactly one of url or service is required")) + case cc.URL != nil: + allErrors = append(allErrors, webhook.ValidateWebhookURL(fldPath.Child("clientConfig").Child("url"), *cc.URL, true)...) + case cc.Service != nil: + allErrors = append(allErrors, webhook.ValidateWebhookService(fldPath.Child("clientConfig").Child("service"), cc.Service.Name, cc.Service.Namespace, cc.Service.Path)...) } - - if cc.URL != nil { - const form = "; desired format: https://host[/path]" - if u, err := url.Parse(*cc.URL); err != nil { - allErrors = append(allErrors, field.Required(fldPath.Child("url"), "url must be a valid URL: "+err.Error()+form)) - } else { - if u.Scheme != "https" { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.Scheme, "'https' is the only allowed URL scheme"+form)) - } - if len(u.Host) == 0 { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.Host, "host must be provided"+form)) - } - if u.User != nil { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.User.String(), "user information is not permitted in the URL")) - } - if len(u.Fragment) != 0 { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.Fragment, "fragments are not permitted in the URL")) - } - if len(u.RawQuery) != 0 { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.RawQuery, "query parameters are not permitted in the URL")) - } - } - } - - if cc.Service != nil { - allErrors = append(allErrors, validateWebhookService(fldPath.Child("service"), cc.Service)...) - } - return allErrors -} - -// note: this has copy/paste inheritance in auditregistration -func validateWebhookService(fldPath *field.Path, svc *admissionregistration.ServiceReference) field.ErrorList { - var allErrors field.ErrorList - - if len(svc.Name) == 0 { - allErrors = append(allErrors, field.Required(fldPath.Child("name"), "service name is required")) - } - - if len(svc.Namespace) == 0 { - allErrors = append(allErrors, field.Required(fldPath.Child("namespace"), "service namespace is required")) - } - - if svc.Path == nil { - return allErrors - } - - // TODO: replace below with url.Parse + verifying that host is empty? - - urlPath := *svc.Path - if urlPath == "/" || len(urlPath) == 0 { - return allErrors - } - if urlPath == "//" { - allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, "segment[0] may not be empty")) - return allErrors - } - - if !strings.HasPrefix(urlPath, "/") { - allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, "must start with a '/'")) - } - - urlPathToCheck := urlPath[1:] - if strings.HasSuffix(urlPathToCheck, "/") { - urlPathToCheck = urlPathToCheck[:len(urlPathToCheck)-1] - } - steps := strings.Split(urlPathToCheck, "/") - for i, step := range steps { - if len(step) == 0 { - allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, fmt.Sprintf("segment[%d] may not be empty", i))) - continue - } - failures := validation.IsDNS1123Subdomain(step) - for _, failure := range failures { - allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, fmt.Sprintf("segment[%d]: %v", i, failure))) - } - } - return allErrors } diff --git a/pkg/apis/admissionregistration/validation/validation_test.go b/pkg/apis/admissionregistration/validation/validation_test.go index 2cf41fa5979b0..6eaa1804a662b 100644 --- a/pkg/apis/admissionregistration/validation/validation_test.go +++ b/pkg/apis/admissionregistration/validation/validation_test.go @@ -540,7 +540,7 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { }, }, }), - expectedError: `[0].clientConfig.url: Required value: exactly one of url or service is required`, + expectedError: `[0].clientConfig: Required value: exactly one of url or service is required`, }, { name: "blank URL", diff --git a/pkg/apis/apps/BUILD b/pkg/apis/apps/BUILD index 60c1469c0c65a..0d4035331d680 100644 --- a/pkg/apis/apps/BUILD +++ b/pkg/apis/apps/BUILD @@ -17,10 +17,10 @@ go_library( deps = [ "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", ], ) diff --git a/pkg/apis/apps/fuzzer/BUILD b/pkg/apis/apps/fuzzer/BUILD index 6d8a0f03b0513..3da12938631fd 100644 --- a/pkg/apis/apps/fuzzer/BUILD +++ b/pkg/apis/apps/fuzzer/BUILD @@ -13,6 +13,7 @@ go_library( "//pkg/apis/apps:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//vendor/github.com/google/gofuzz:go_default_library", ], ) diff --git a/pkg/apis/apps/fuzzer/fuzzer.go b/pkg/apis/apps/fuzzer/fuzzer.go index edd83be25088b..952dbe64dc915 100644 --- a/pkg/apis/apps/fuzzer/fuzzer.go +++ b/pkg/apis/apps/fuzzer/fuzzer.go @@ -17,10 +17,13 @@ limitations under the License. package fuzzer import ( + "fmt" + fuzz "github.com/google/gofuzz" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/kubernetes/pkg/apis/apps" ) @@ -54,5 +57,85 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { s.Labels = s.Spec.Template.Labels } }, + func(j *apps.Deployment, c fuzz.Continue) { + c.FuzzNoCustom(j) + + // match defaulting + if j.Spec.Selector == nil { + j.Spec.Selector = &metav1.LabelSelector{MatchLabels: j.Spec.Template.Labels} + } + if len(j.Labels) == 0 { + j.Labels = j.Spec.Template.Labels + } + }, + func(j *apps.DeploymentSpec, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + rhl := int32(c.Rand.Int31()) + pds := int32(c.Rand.Int31()) + j.RevisionHistoryLimit = &rhl + j.ProgressDeadlineSeconds = &pds + }, + func(j *apps.DeploymentStrategy, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + // Ensure that strategyType is one of valid values. + strategyTypes := []apps.DeploymentStrategyType{apps.RecreateDeploymentStrategyType, apps.RollingUpdateDeploymentStrategyType} + j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] + if j.Type != apps.RollingUpdateDeploymentStrategyType { + j.RollingUpdate = nil + } else { + rollingUpdate := apps.RollingUpdateDeployment{} + if c.RandBool() { + rollingUpdate.MaxUnavailable = intstr.FromInt(int(c.Rand.Int31())) + rollingUpdate.MaxSurge = intstr.FromInt(int(c.Rand.Int31())) + } else { + rollingUpdate.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.Rand.Int31())) + } + j.RollingUpdate = &rollingUpdate + } + }, + func(j *apps.DaemonSet, c fuzz.Continue) { + c.FuzzNoCustom(j) + + // match defaulter + j.Spec.Template.Generation = 0 + if len(j.ObjectMeta.Labels) == 0 { + j.ObjectMeta.Labels = j.Spec.Template.ObjectMeta.Labels + } + }, + func(j *apps.DaemonSetSpec, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + rhl := int32(c.Rand.Int31()) + j.RevisionHistoryLimit = &rhl + }, + func(j *apps.DaemonSetUpdateStrategy, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + // Ensure that strategyType is one of valid values. + strategyTypes := []apps.DaemonSetUpdateStrategyType{apps.RollingUpdateDaemonSetStrategyType, apps.OnDeleteDaemonSetStrategyType} + j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] + if j.Type != apps.RollingUpdateDaemonSetStrategyType { + j.RollingUpdate = nil + } else { + rollingUpdate := apps.RollingUpdateDaemonSet{} + if c.RandBool() { + if c.RandBool() { + rollingUpdate.MaxUnavailable = intstr.FromInt(1 + int(c.Rand.Int31())) + } else { + rollingUpdate.MaxUnavailable = intstr.FromString(fmt.Sprintf("%d%%", 1+c.Rand.Int31())) + } + } + j.RollingUpdate = &rollingUpdate + } + }, + func(j *apps.ReplicaSet, c fuzz.Continue) { + c.FuzzNoCustom(j) + + // match defaulter + if j.Spec.Selector == nil { + j.Spec.Selector = &metav1.LabelSelector{MatchLabels: j.Spec.Template.Labels} + } + if len(j.Labels) == 0 { + j.Labels = j.Spec.Template.Labels + } + }, } } diff --git a/pkg/apis/apps/register.go b/pkg/apis/apps/register.go index 8b7591807cbe4..b56ec96cb36c6 100644 --- a/pkg/apis/apps/register.go +++ b/pkg/apis/apps/register.go @@ -20,7 +20,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kubernetes/pkg/apis/autoscaling" - "k8s.io/kubernetes/pkg/apis/extensions" ) var ( @@ -48,18 +47,18 @@ func Resource(resource string) schema.GroupResource { func addKnownTypes(scheme *runtime.Scheme) error { // TODO this will get cleaned up with the scheme types are fixed scheme.AddKnownTypes(SchemeGroupVersion, - &extensions.DaemonSet{}, - &extensions.DaemonSetList{}, - &extensions.Deployment{}, - &extensions.DeploymentList{}, - &extensions.DeploymentRollback{}, + &DaemonSet{}, + &DaemonSetList{}, + &Deployment{}, + &DeploymentList{}, + &DeploymentRollback{}, &autoscaling.Scale{}, &StatefulSet{}, &StatefulSetList{}, &ControllerRevision{}, &ControllerRevisionList{}, - &extensions.ReplicaSet{}, - &extensions.ReplicaSetList{}, + &ReplicaSet{}, + &ReplicaSetList{}, ) return nil } diff --git a/pkg/apis/apps/types.go b/pkg/apis/apps/types.go index 850694d7fc23e..c15927d45ec94 100644 --- a/pkg/apis/apps/types.go +++ b/pkg/apis/apps/types.go @@ -19,12 +19,11 @@ package apps import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" api "k8s.io/kubernetes/pkg/apis/core" ) // +genclient -// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/autoscaling.Scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // StatefulSet represents a set of pods with consistent identities. @@ -262,3 +261,541 @@ type ControllerRevisionList struct { // Items is the list of ControllerRevision objects. Items []ControllerRevision } + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Deployment struct { + metav1.TypeMeta + // +optional + metav1.ObjectMeta + + // Specification of the desired behavior of the Deployment. + // +optional + Spec DeploymentSpec + + // Most recently observed status of the Deployment. + // +optional + Status DeploymentStatus +} + +type DeploymentSpec struct { + // Number of desired pods. This is a pointer to distinguish between explicit + // zero and not specified. Defaults to 1. + // +optional + Replicas int32 + + // Label selector for pods. Existing ReplicaSets whose pods are + // selected by this will be the ones affected by this deployment. + // +optional + Selector *metav1.LabelSelector + + // Template describes the pods that will be created. + Template api.PodTemplateSpec + + // The deployment strategy to use to replace existing pods with new ones. + // +optional + Strategy DeploymentStrategy + + // Minimum number of seconds for which a newly created pod should be ready + // without any of its container crashing, for it to be considered available. + // Defaults to 0 (pod will be considered available as soon as it is ready) + // +optional + MinReadySeconds int32 + + // The number of old ReplicaSets to retain to allow rollback. + // This is a pointer to distinguish between explicit zero and not specified. + // This is set to the max value of int32 (i.e. 2147483647) by default, which means + // "retaining all old ReplicaSets". + // +optional + RevisionHistoryLimit *int32 + + // Indicates that the deployment is paused and will not be processed by the + // deployment controller. + // +optional + Paused bool + + // DEPRECATED. + // The config this deployment is rolling back to. Will be cleared after rollback is done. + // +optional + RollbackTo *RollbackConfig + + // The maximum time in seconds for a deployment to make progress before it + // is considered to be failed. The deployment controller will continue to + // process failed deployments and a condition with a ProgressDeadlineExceeded + // reason will be surfaced in the deployment status. Note that progress will + // not be estimated during the time a deployment is paused. This is set to + // the max value of int32 (i.e. 2147483647) by default, which means "no deadline". + // +optional + ProgressDeadlineSeconds *int32 +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// DEPRECATED. +// DeploymentRollback stores the information required to rollback a deployment. +type DeploymentRollback struct { + metav1.TypeMeta + // Required: This must match the Name of a deployment. + Name string + // The annotations to be updated to a deployment + // +optional + UpdatedAnnotations map[string]string + // The config of this deployment rollback. + RollbackTo RollbackConfig +} + +// DEPRECATED. +type RollbackConfig struct { + // The revision to rollback to. If set to 0, rollback to the last revision. + // +optional + Revision int64 +} + +const ( + // DefaultDeploymentUniqueLabelKey is the default key of the selector that is added + // to existing RCs (and label key that is added to its pods) to prevent the existing RCs + // to select new pods (and old pods being select by new RC). + DefaultDeploymentUniqueLabelKey string = "pod-template-hash" +) + +type DeploymentStrategy struct { + // Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate. + // +optional + Type DeploymentStrategyType + + // Rolling update config params. Present only if DeploymentStrategyType = + // RollingUpdate. + //--- + // TODO: Update this to follow our convention for oneOf, whatever we decide it + // to be. + // +optional + RollingUpdate *RollingUpdateDeployment +} + +type DeploymentStrategyType string + +const ( + // Kill all existing pods before creating new ones. + RecreateDeploymentStrategyType DeploymentStrategyType = "Recreate" + + // Replace the old RCs by new one using rolling update i.e gradually scale down the old RCs and scale up the new one. + RollingUpdateDeploymentStrategyType DeploymentStrategyType = "RollingUpdate" +) + +// Spec to control the desired behavior of rolling update. +type RollingUpdateDeployment struct { + // The maximum number of pods that can be unavailable during the update. + // Value can be an absolute number (ex: 5) or a percentage of total pods at the start of update (ex: 10%). + // Absolute number is calculated from percentage by rounding down. + // This can not be 0 if MaxSurge is 0. + // By default, a fixed value of 1 is used. + // Example: when this is set to 30%, the old RC can be scaled down by 30% + // immediately when the rolling update starts. Once new pods are ready, old RC + // can be scaled down further, followed by scaling up the new RC, ensuring + // that at least 70% of original number of pods are available at all times + // during the update. + // +optional + MaxUnavailable intstr.IntOrString + + // The maximum number of pods that can be scheduled above the original number of + // pods. + // Value can be an absolute number (ex: 5) or a percentage of total pods at + // the start of the update (ex: 10%). This can not be 0 if MaxUnavailable is 0. + // Absolute number is calculated from percentage by rounding up. + // By default, a value of 1 is used. + // Example: when this is set to 30%, the new RC can be scaled up by 30% + // immediately when the rolling update starts. Once old pods have been killed, + // new RC can be scaled up further, ensuring that total number of pods running + // at any time during the update is atmost 130% of original pods. + // +optional + MaxSurge intstr.IntOrString +} + +type DeploymentStatus struct { + // The generation observed by the deployment controller. + // +optional + ObservedGeneration int64 + + // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // +optional + Replicas int32 + + // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // +optional + UpdatedReplicas int32 + + // Total number of ready pods targeted by this deployment. + // +optional + ReadyReplicas int32 + + // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // +optional + AvailableReplicas int32 + + // Total number of unavailable pods targeted by this deployment. This is the total number of + // pods that are still required for the deployment to have 100% available capacity. They may + // either be pods that are running but not yet available or pods that still have not been created. + // +optional + UnavailableReplicas int32 + + // Represents the latest available observations of a deployment's current state. + Conditions []DeploymentCondition + + // Count of hash collisions for the Deployment. The Deployment controller uses this + // field as a collision avoidance mechanism when it needs to create the name for the + // newest ReplicaSet. + // +optional + CollisionCount *int32 +} + +type DeploymentConditionType string + +// These are valid conditions of a deployment. +const ( + // Available means the deployment is available, ie. at least the minimum available + // replicas required are up and running for at least minReadySeconds. + DeploymentAvailable DeploymentConditionType = "Available" + // Progressing means the deployment is progressing. Progress for a deployment is + // considered when a new replica set is created or adopted, and when new pods scale + // up or old pods scale down. Progress is not estimated for paused deployments or + // when progressDeadlineSeconds is not specified. + DeploymentProgressing DeploymentConditionType = "Progressing" + // ReplicaFailure is added in a deployment when one of its pods fails to be created + // or deleted. + DeploymentReplicaFailure DeploymentConditionType = "ReplicaFailure" +) + +// DeploymentCondition describes the state of a deployment at a certain point. +type DeploymentCondition struct { + // Type of deployment condition. + Type DeploymentConditionType + // Status of the condition, one of True, False, Unknown. + Status api.ConditionStatus + // The last time this condition was updated. + LastUpdateTime metav1.Time + // Last time the condition transitioned from one status to another. + LastTransitionTime metav1.Time + // The reason for the condition's last transition. + Reason string + // A human readable message indicating details about the transition. + Message string +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type DeploymentList struct { + metav1.TypeMeta + // +optional + metav1.ListMeta + + // Items is the list of deployments. + Items []Deployment +} + +type DaemonSetUpdateStrategy struct { + // Type of daemon set update. Can be "RollingUpdate" or "OnDelete". + // Default is OnDelete. + // +optional + Type DaemonSetUpdateStrategyType + + // Rolling update config params. Present only if type = "RollingUpdate". + //--- + // TODO: Update this to follow our convention for oneOf, whatever we decide it + // to be. Same as Deployment `strategy.rollingUpdate`. + // See https://github.com/kubernetes/kubernetes/issues/35345 + // +optional + RollingUpdate *RollingUpdateDaemonSet +} + +type DaemonSetUpdateStrategyType string + +const ( + // Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other. + RollingUpdateDaemonSetStrategyType DaemonSetUpdateStrategyType = "RollingUpdate" + + // Replace the old daemons only when it's killed + OnDeleteDaemonSetStrategyType DaemonSetUpdateStrategyType = "OnDelete" +) + +// Spec to control the desired behavior of daemon set rolling update. +type RollingUpdateDaemonSet struct { + // The maximum number of DaemonSet pods that can be unavailable during the + // update. Value can be an absolute number (ex: 5) or a percentage of total + // number of DaemonSet pods at the start of the update (ex: 10%). Absolute + // number is calculated from percentage by rounding up. + // This cannot be 0. + // Default value is 1. + // Example: when this is set to 30%, at most 30% of the total number of nodes + // that should be running the daemon pod (i.e. status.desiredNumberScheduled) + // can have their pods stopped for an update at any given + // time. The update starts by stopping at most 30% of those DaemonSet pods + // and then brings up new DaemonSet pods in their place. Once the new pods + // are available, it then proceeds onto other DaemonSet pods, thus ensuring + // that at least 70% of original number of DaemonSet pods are available at + // all times during the update. + // +optional + MaxUnavailable intstr.IntOrString +} + +// DaemonSetSpec is the specification of a daemon set. +type DaemonSetSpec struct { + // A label query over pods that are managed by the daemon set. + // Must match in order to be controlled. + // If empty, defaulted to labels on Pod template. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + // +optional + Selector *metav1.LabelSelector + + // An object that describes the pod that will be created. + // The DaemonSet will create exactly one copy of this pod on every node + // that matches the template's node selector (or on every node if no node + // selector is specified). + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template + Template api.PodTemplateSpec + + // An update strategy to replace existing DaemonSet pods with new pods. + // +optional + UpdateStrategy DaemonSetUpdateStrategy + + // The minimum number of seconds for which a newly created DaemonSet pod should + // be ready without any of its container crashing, for it to be considered + // available. Defaults to 0 (pod will be considered available as soon as it + // is ready). + // +optional + MinReadySeconds int32 + + // DEPRECATED. + // A sequence number representing a specific generation of the template. + // Populated by the system. It can be set only during the creation. + // +optional + TemplateGeneration int64 + + // The number of old history to retain to allow rollback. + // This is a pointer to distinguish between explicit zero and not specified. + // Defaults to 10. + // +optional + RevisionHistoryLimit *int32 +} + +// DaemonSetStatus represents the current status of a daemon set. +type DaemonSetStatus struct { + // The number of nodes that are running at least 1 + // daemon pod and are supposed to run the daemon pod. + CurrentNumberScheduled int32 + + // The number of nodes that are running the daemon pod, but are + // not supposed to run the daemon pod. + NumberMisscheduled int32 + + // The total number of nodes that should be running the daemon + // pod (including nodes correctly running the daemon pod). + DesiredNumberScheduled int32 + + // The number of nodes that should be running the daemon pod and have one + // or more of the daemon pod running and ready. + NumberReady int32 + + // The most recent generation observed by the daemon set controller. + // +optional + ObservedGeneration int64 + + // The total number of nodes that are running updated daemon pod + // +optional + UpdatedNumberScheduled int32 + + // The number of nodes that should be running the + // daemon pod and have one or more of the daemon pod running and + // available (ready for at least spec.minReadySeconds) + // +optional + NumberAvailable int32 + + // The number of nodes that should be running the + // daemon pod and have none of the daemon pod running and available + // (ready for at least spec.minReadySeconds) + // +optional + NumberUnavailable int32 + + // Count of hash collisions for the DaemonSet. The DaemonSet controller + // uses this field as a collision avoidance mechanism when it needs to + // create the name for the newest ControllerRevision. + // +optional + CollisionCount *int32 + + // Represents the latest available observations of a DaemonSet's current state. + Conditions []DaemonSetCondition +} + +type DaemonSetConditionType string + +// TODO: Add valid condition types of a DaemonSet. + +// DaemonSetCondition describes the state of a DaemonSet at a certain point. +type DaemonSetCondition struct { + // Type of DaemonSet condition. + Type DaemonSetConditionType + // Status of the condition, one of True, False, Unknown. + Status api.ConditionStatus + // Last time the condition transitioned from one status to another. + LastTransitionTime metav1.Time + // The reason for the condition's last transition. + Reason string + // A human readable message indicating details about the transition. + Message string +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// DaemonSet represents the configuration of a daemon set. +type DaemonSet struct { + metav1.TypeMeta + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata + // +optional + metav1.ObjectMeta + + // The desired behavior of this daemon set. + // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status + // +optional + Spec DaemonSetSpec + + // The current status of this daemon set. This data may be + // out of date by some window of time. + // Populated by the system. + // Read-only. + // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status + // +optional + Status DaemonSetStatus +} + +const ( + // DEPRECATED: DefaultDaemonSetUniqueLabelKey is used instead. + // DaemonSetTemplateGenerationKey is the key of the labels that is added + // to daemon set pods to distinguish between old and new pod templates + // during DaemonSet template update. + DaemonSetTemplateGenerationKey string = "pod-template-generation" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// DaemonSetList is a collection of daemon sets. +type DaemonSetList struct { + metav1.TypeMeta + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata + // +optional + metav1.ListMeta + + // A list of daemon sets. + Items []DaemonSet +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ReplicaSet ensures that a specified number of pod replicas are running at any given time. +type ReplicaSet struct { + metav1.TypeMeta + // +optional + metav1.ObjectMeta + + // Spec defines the desired behavior of this ReplicaSet. + // +optional + Spec ReplicaSetSpec + + // Status is the current status of this ReplicaSet. This data may be + // out of date by some window of time. + // +optional + Status ReplicaSetStatus +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ReplicaSetList is a collection of ReplicaSets. +type ReplicaSetList struct { + metav1.TypeMeta + // +optional + metav1.ListMeta + + Items []ReplicaSet +} + +// ReplicaSetSpec is the specification of a ReplicaSet. +// As the internal representation of a ReplicaSet, it must have +// a Template set. +type ReplicaSetSpec struct { + // Replicas is the number of desired replicas. + Replicas int32 + + // Minimum number of seconds for which a newly created pod should be ready + // without any of its container crashing, for it to be considered available. + // Defaults to 0 (pod will be considered available as soon as it is ready) + // +optional + MinReadySeconds int32 + + // Selector is a label query over pods that should match the replica count. + // Must match in order to be controlled. + // If empty, defaulted to labels on pod template. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + // +optional + Selector *metav1.LabelSelector + + // Template is the object that describes the pod that will be created if + // insufficient replicas are detected. + // +optional + Template api.PodTemplateSpec +} + +// ReplicaSetStatus represents the current status of a ReplicaSet. +type ReplicaSetStatus struct { + // Replicas is the number of actual replicas. + Replicas int32 + + // The number of pods that have labels matching the labels of the pod template of the replicaset. + // +optional + FullyLabeledReplicas int32 + + // The number of ready replicas for this replica set. + // +optional + ReadyReplicas int32 + + // The number of available replicas (ready for at least minReadySeconds) for this replica set. + // +optional + AvailableReplicas int32 + + // ObservedGeneration is the most recent generation observed by the controller. + // +optional + ObservedGeneration int64 + + // Represents the latest available observations of a replica set's current state. + // +optional + Conditions []ReplicaSetCondition +} + +type ReplicaSetConditionType string + +// These are valid conditions of a replica set. +const ( + // ReplicaSetReplicaFailure is added in a replica set when one of its pods fails to be created + // due to insufficient quota, limit ranges, pod security policy, node selectors, etc. or deleted + // due to kubelet being down or finalizers are failing. + ReplicaSetReplicaFailure ReplicaSetConditionType = "ReplicaFailure" +) + +// ReplicaSetCondition describes the state of a replica set at a certain point. +type ReplicaSetCondition struct { + // Type of replica set condition. + Type ReplicaSetConditionType + // Status of the condition, one of True, False, Unknown. + Status api.ConditionStatus + // The last time the condition transitioned from one status to another. + // +optional + LastTransitionTime metav1.Time + // The reason for the condition's last transition. + // +optional + Reason string + // A human readable message indicating details about the transition. + // +optional + Message string +} diff --git a/pkg/apis/apps/v1/BUILD b/pkg/apis/apps/v1/BUILD index 925be0c91cee2..852490223ea59 100644 --- a/pkg/apis/apps/v1/BUILD +++ b/pkg/apis/apps/v1/BUILD @@ -16,7 +16,6 @@ go_library( "//pkg/apis/apps:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/v1:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", @@ -40,7 +39,6 @@ go_test( "//pkg/apis/apps/install:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/install:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", diff --git a/pkg/apis/apps/v1/conversion.go b/pkg/apis/apps/v1/conversion.go index 565430b0e9607..34f6078b467df 100644 --- a/pkg/apis/apps/v1/conversion.go +++ b/pkg/apis/apps/v1/conversion.go @@ -29,7 +29,6 @@ import ( "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" - "k8s.io/kubernetes/pkg/apis/extensions" ) func addConversionFuncs(scheme *runtime.Scheme) error { @@ -42,29 +41,29 @@ func addConversionFuncs(scheme *runtime.Scheme) error { Convert_apps_StatefulSetSpec_To_v1_StatefulSetSpec, Convert_v1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy, Convert_apps_StatefulSetUpdateStrategy_To_v1_StatefulSetUpdateStrategy, - Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet, - Convert_v1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet, + Convert_apps_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet, + Convert_v1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet, Convert_v1_StatefulSetStatus_To_apps_StatefulSetStatus, Convert_apps_StatefulSetStatus_To_v1_StatefulSetStatus, - Convert_v1_Deployment_To_extensions_Deployment, - Convert_extensions_Deployment_To_v1_Deployment, - Convert_extensions_DaemonSet_To_v1_DaemonSet, - Convert_v1_DaemonSet_To_extensions_DaemonSet, - Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec, - Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec, - Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy, - Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy, + Convert_v1_Deployment_To_apps_Deployment, + Convert_apps_Deployment_To_v1_Deployment, + Convert_apps_DaemonSet_To_v1_DaemonSet, + Convert_v1_DaemonSet_To_apps_DaemonSet, + Convert_apps_DaemonSetSpec_To_v1_DaemonSetSpec, + Convert_v1_DaemonSetSpec_To_apps_DaemonSetSpec, + Convert_apps_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy, + Convert_v1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy, // extensions // TODO: below conversions should be dropped in favor of auto-generated // ones, see https://github.com/kubernetes/kubernetes/issues/39865 - Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec, - Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec, - Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy, - Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy, - Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment, - Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment, - Convert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec, - Convert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec, + Convert_v1_DeploymentSpec_To_apps_DeploymentSpec, + Convert_apps_DeploymentSpec_To_v1_DeploymentSpec, + Convert_v1_DeploymentStrategy_To_apps_DeploymentStrategy, + Convert_apps_DeploymentStrategy_To_v1_DeploymentStrategy, + Convert_v1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment, + Convert_apps_RollingUpdateDeployment_To_v1_RollingUpdateDeployment, + Convert_apps_ReplicaSetSpec_To_v1_ReplicaSetSpec, + Convert_v1_ReplicaSetSpec_To_apps_ReplicaSetSpec, ) if err != nil { return err @@ -72,7 +71,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error { return nil } -func Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { +func Convert_v1_DeploymentSpec_To_apps_DeploymentSpec(in *appsv1.DeploymentSpec, out *apps.DeploymentSpec, s conversion.Scope) error { if in.Replicas != nil { out.Replicas = *in.Replicas } @@ -80,7 +79,7 @@ func Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1.Deploymen if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_v1_DeploymentStrategy_To_apps_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.RevisionHistoryLimit = in.RevisionHistoryLimit @@ -93,13 +92,13 @@ func Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1.Deploymen return nil } -func Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec(in *extensions.DeploymentSpec, out *appsv1.DeploymentSpec, s conversion.Scope) error { +func Convert_apps_DeploymentSpec_To_v1_DeploymentSpec(in *apps.DeploymentSpec, out *appsv1.DeploymentSpec, s conversion.Scope) error { out.Replicas = &in.Replicas out.Selector = in.Selector if err := k8s_api_v1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_apps_DeploymentStrategy_To_v1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } if in.RevisionHistoryLimit != nil { @@ -115,11 +114,11 @@ func Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec(in *extensions.Deplo return nil } -func Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *appsv1.DeploymentStrategy, s conversion.Scope) error { +func Convert_apps_DeploymentStrategy_To_v1_DeploymentStrategy(in *apps.DeploymentStrategy, out *appsv1.DeploymentStrategy, s conversion.Scope) error { out.Type = appsv1.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { out.RollingUpdate = new(appsv1.RollingUpdateDeployment) - if err := Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + if err := Convert_apps_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -128,11 +127,11 @@ func Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(in *extensio return nil } -func Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *appsv1.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { - out.Type = extensions.DeploymentStrategyType(in.Type) +func Convert_v1_DeploymentStrategy_To_apps_DeploymentStrategy(in *appsv1.DeploymentStrategy, out *apps.DeploymentStrategy, s conversion.Scope) error { + out.Type = apps.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { - out.RollingUpdate = new(extensions.RollingUpdateDeployment) - if err := Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + out.RollingUpdate = new(apps.RollingUpdateDeployment) + if err := Convert_v1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -141,7 +140,7 @@ func Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *appsv1.D return nil } -func Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *appsv1.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { +func Convert_v1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in *appsv1.RollingUpdateDeployment, out *apps.RollingUpdateDeployment, s conversion.Scope) error { if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { return err } @@ -151,7 +150,7 @@ func Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in return nil } -func Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *appsv1.RollingUpdateDeployment, s conversion.Scope) error { +func Convert_apps_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in *apps.RollingUpdateDeployment, out *appsv1.RollingUpdateDeployment, s conversion.Scope) error { if out.MaxUnavailable == nil { out.MaxUnavailable = &intstr.IntOrString{} } @@ -167,9 +166,9 @@ func Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in return nil } -func Convert_v1_Deployment_To_extensions_Deployment(in *appsv1.Deployment, out *extensions.Deployment, s conversion.Scope) error { +func Convert_v1_Deployment_To_apps_Deployment(in *appsv1.Deployment, out *apps.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1_DeploymentSpec_To_apps_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } @@ -179,7 +178,7 @@ func Convert_v1_Deployment_To_extensions_Deployment(in *appsv1.Deployment, out * if revision64, err := strconv.ParseInt(revision, 10, 64); err != nil { return fmt.Errorf("failed to parse annotation[%s]=%s as int64: %v", appsv1.DeprecatedRollbackTo, revision, err) } else { - out.Spec.RollbackTo = new(extensions.RollbackConfig) + out.Spec.RollbackTo = new(apps.RollbackConfig) out.Spec.RollbackTo.Revision = revision64 } out.Annotations = deepCopyStringMap(out.Annotations) @@ -188,17 +187,17 @@ func Convert_v1_Deployment_To_extensions_Deployment(in *appsv1.Deployment, out * out.Spec.RollbackTo = nil } - if err := Convert_v1_DeploymentStatus_To_extensions_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1_DeploymentStatus_To_apps_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func Convert_extensions_Deployment_To_v1_Deployment(in *extensions.Deployment, out *appsv1.Deployment, s conversion.Scope) error { +func Convert_apps_Deployment_To_v1_Deployment(in *apps.Deployment, out *appsv1.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Annotations = deepCopyStringMap(out.Annotations) // deep copy because we modify it below - if err := Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DeploymentSpec_To_v1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } @@ -213,13 +212,13 @@ func Convert_extensions_Deployment_To_v1_Deployment(in *extensions.Deployment, o delete(out.Annotations, appsv1.DeprecatedRollbackTo) } - if err := Convert_extensions_DeploymentStatus_To_v1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DeploymentStatus_To_v1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *appsv1.RollingUpdateDaemonSet, s conversion.Scope) error { +func Convert_apps_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in *apps.RollingUpdateDaemonSet, out *appsv1.RollingUpdateDaemonSet, s conversion.Scope) error { if out.MaxUnavailable == nil { out.MaxUnavailable = &intstr.IntOrString{} } @@ -229,19 +228,19 @@ func Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in * return nil } -func Convert_v1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in *appsv1.RollingUpdateDaemonSet, out *extensions.RollingUpdateDaemonSet, s conversion.Scope) error { +func Convert_v1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(in *appsv1.RollingUpdateDaemonSet, out *apps.RollingUpdateDaemonSet, s conversion.Scope) error { if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { return err } return nil } -func Convert_extensions_DaemonSet_To_v1_DaemonSet(in *extensions.DaemonSet, out *appsv1.DaemonSet, s conversion.Scope) error { +func Convert_apps_DaemonSet_To_v1_DaemonSet(in *apps.DaemonSet, out *appsv1.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Annotations = deepCopyStringMap(out.Annotations) // deep copy annotations because we change them below out.Annotations[appsv1.DeprecatedTemplateGeneration] = strconv.FormatInt(in.Spec.TemplateGeneration, 10) - if err := Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DaemonSetSpec_To_v1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { @@ -250,12 +249,12 @@ func Convert_extensions_DaemonSet_To_v1_DaemonSet(in *extensions.DaemonSet, out return nil } -func Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec(in *extensions.DaemonSetSpec, out *appsv1.DaemonSetSpec, s conversion.Scope) error { +func Convert_apps_DaemonSetSpec_To_v1_DaemonSetSpec(in *apps.DaemonSetSpec, out *appsv1.DaemonSetSpec, s conversion.Scope) error { out.Selector = in.Selector if err := k8s_api_v1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_apps_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } out.MinReadySeconds = int32(in.MinReadySeconds) @@ -268,20 +267,20 @@ func Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec(in *extensions.DaemonS return nil } -func Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(in *extensions.DaemonSetUpdateStrategy, out *appsv1.DaemonSetUpdateStrategy, s conversion.Scope) error { +func Convert_apps_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(in *apps.DaemonSetUpdateStrategy, out *appsv1.DaemonSetUpdateStrategy, s conversion.Scope) error { out.Type = appsv1.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { out.RollingUpdate = &appsv1.RollingUpdateDaemonSet{} - if err := Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil { + if err := Convert_apps_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } return nil } -func Convert_v1_DaemonSet_To_extensions_DaemonSet(in *appsv1.DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error { +func Convert_v1_DaemonSet_To_apps_DaemonSet(in *appsv1.DaemonSet, out *apps.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1_DaemonSetSpec_To_apps_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } if value, ok := in.Annotations[appsv1.DeprecatedTemplateGeneration]; ok { @@ -299,12 +298,12 @@ func Convert_v1_DaemonSet_To_extensions_DaemonSet(in *appsv1.DaemonSet, out *ext return nil } -func Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *appsv1.DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error { +func Convert_v1_DaemonSetSpec_To_apps_DaemonSetSpec(in *appsv1.DaemonSetSpec, out *apps.DaemonSetSpec, s conversion.Scope) error { out.Selector = in.Selector if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_v1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } if in.RevisionHistoryLimit != nil { @@ -317,18 +316,18 @@ func Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *appsv1.DaemonSetSp return nil } -func Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in *appsv1.DaemonSetUpdateStrategy, out *extensions.DaemonSetUpdateStrategy, s conversion.Scope) error { - out.Type = extensions.DaemonSetUpdateStrategyType(in.Type) +func Convert_v1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(in *appsv1.DaemonSetUpdateStrategy, out *apps.DaemonSetUpdateStrategy, s conversion.Scope) error { + out.Type = apps.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { - out.RollingUpdate = &extensions.RollingUpdateDaemonSet{} - if err := Convert_v1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil { + out.RollingUpdate = &apps.RollingUpdateDaemonSet{} + if err := Convert_v1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } return nil } -func Convert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *extensions.ReplicaSetSpec, out *appsv1.ReplicaSetSpec, s conversion.Scope) error { +func Convert_apps_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *apps.ReplicaSetSpec, out *appsv1.ReplicaSetSpec, s conversion.Scope) error { out.Replicas = new(int32) *out.Replicas = int32(in.Replicas) out.MinReadySeconds = in.MinReadySeconds @@ -339,7 +338,7 @@ func Convert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *extensions.Repli return nil } -func Convert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *appsv1.ReplicaSetSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error { +func Convert_v1_ReplicaSetSpec_To_apps_ReplicaSetSpec(in *appsv1.ReplicaSetSpec, out *apps.ReplicaSetSpec, s conversion.Scope) error { if in.Replicas != nil { out.Replicas = *in.Replicas } diff --git a/pkg/apis/apps/v1/conversion_test.go b/pkg/apis/apps/v1/conversion_test.go index 8319da61f0475..0d6b08e58f72c 100644 --- a/pkg/apis/apps/v1/conversion_test.go +++ b/pkg/apis/apps/v1/conversion_test.go @@ -27,7 +27,6 @@ import ( "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" utilpointer "k8s.io/utils/pointer" ) @@ -84,20 +83,20 @@ func TestV12StatefulSetSpecConversion(t *testing.T) { // apps -> appsv1 internal1 := &appsv1.StatefulSetSpec{} if err := legacyscheme.Scheme.Convert(tc.stsSpec1, internal1, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "from extensions to appsv1", err) + t.Errorf("%q - %q: unexpected error: %v", k, "from apps to appsv1", err) } if !apiequality.Semantic.DeepEqual(internal1, tc.stsSepc2) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from extensions to appsv1", tc.stsSepc2, internal1) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from apps to appsv1", tc.stsSepc2, internal1) } // appsv1 -> apps internal2 := &apps.StatefulSetSpec{} if err := legacyscheme.Scheme.Convert(tc.stsSepc2, internal2, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "from appsv1 to extensions", err) + t.Errorf("%q - %q: unexpected error: %v", k, "from appsv1 to apps", err) } if !apiequality.Semantic.DeepEqual(internal2, tc.stsSpec1) { - t.Errorf("%q- %q: expected\n\t%#v, got \n\t%#v", k, "from appsv1 to extensions", tc.stsSpec1, internal2) + t.Errorf("%q- %q: expected\n\t%#v, got \n\t%#v", k, "from appsv1 to apps", tc.stsSpec1, internal2) } } } @@ -228,47 +227,47 @@ func TestV1StatefulSetUpdateStrategyConversion(t *testing.T) { func TestV1RollingUpdateDaemonSetConversion(t *testing.T) { intorstr := intstr.FromInt(1) testcases := map[string]struct { - rollingUpdateDs1 *extensions.RollingUpdateDaemonSet + rollingUpdateDs1 *apps.RollingUpdateDaemonSet rollingUpdateDs2 *appsv1.RollingUpdateDaemonSet }{ "RollingUpdateDaemonSet Conversion 2": { - rollingUpdateDs1: &extensions.RollingUpdateDaemonSet{MaxUnavailable: intorstr}, + rollingUpdateDs1: &apps.RollingUpdateDaemonSet{MaxUnavailable: intorstr}, rollingUpdateDs2: &appsv1.RollingUpdateDaemonSet{MaxUnavailable: &intorstr}, }, } for k, tc := range testcases { - // extensions -> v1 + // apps -> v1 internal1 := &appsv1.RollingUpdateDaemonSet{} if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDs1, internal1, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "from extensions to v1", err) + t.Errorf("%q - %q: unexpected error: %v", k, "from apps to v1", err) } if !apiequality.Semantic.DeepEqual(internal1, tc.rollingUpdateDs2) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from extensions to v1", tc.rollingUpdateDs2, internal1) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from apps to v1", tc.rollingUpdateDs2, internal1) } - // v1 -> extensions - internal2 := &extensions.RollingUpdateDaemonSet{} + // v1 -> apps + internal2 := &apps.RollingUpdateDaemonSet{} if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDs2, internal2, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "from v1 to extensions", err) + t.Errorf("%q - %q: unexpected error: %v", k, "from v1 to apps", err) } if !apiequality.Semantic.DeepEqual(internal2, tc.rollingUpdateDs1) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from v1 to extensions", tc.rollingUpdateDs1, internal2) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from v1 to apps", tc.rollingUpdateDs1, internal2) } } } func TestV1DeploymentConversion(t *testing.T) { replica := utilpointer.Int32Ptr(2) - rollbackTo := new(extensions.RollbackConfig) + rollbackTo := new(apps.RollbackConfig) rollbackTo.Revision = int64(2) testcases := map[string]struct { - deployment1 *extensions.Deployment + deployment1 *apps.Deployment deployment2 *appsv1.Deployment }{ "Deployment Conversion 1": { - deployment1: &extensions.Deployment{ - Spec: extensions.DeploymentSpec{ + deployment1: &apps.Deployment{ + Spec: apps.DeploymentSpec{ Replicas: *replica, RollbackTo: rollbackTo, Template: api.PodTemplateSpec{ @@ -293,8 +292,8 @@ func TestV1DeploymentConversion(t *testing.T) { }, }, "Deployment Conversion 2": { - deployment1: &extensions.Deployment{ - Spec: extensions.DeploymentSpec{ + deployment1: &apps.Deployment{ + Spec: apps.DeploymentSpec{ Replicas: *replica, Template: api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -317,22 +316,22 @@ func TestV1DeploymentConversion(t *testing.T) { } for k, tc := range testcases { - // extensions -> v1beta2 + // apps -> v1beta2 internal1 := &appsv1.Deployment{} if err := legacyscheme.Scheme.Convert(tc.deployment1, internal1, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "from extensions to v1beta2", err) + t.Errorf("%q - %q: unexpected error: %v", k, "from apps to v1beta2", err) } if !apiequality.Semantic.DeepEqual(internal1, tc.deployment2) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from extensions to v1beta2", tc.deployment2, internal1) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from apps to v1beta2", tc.deployment2, internal1) } - // v1beta2 -> extensions - internal2 := &extensions.Deployment{} + // v1beta2 -> apps + internal2 := &apps.Deployment{} if err := legacyscheme.Scheme.Convert(tc.deployment2, internal2, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "from v1beta2 to extensions", err) + t.Errorf("%q - %q: unexpected error: %v", k, "from v1beta2 to apps", err) } if !apiequality.Semantic.DeepEqual(internal2, tc.deployment1) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from v1beta2 to extensions", tc.deployment1, internal2) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from v1beta2 to apps", tc.deployment1, internal2) } } } @@ -343,11 +342,11 @@ func TestV1DeploymentSpecConversion(t *testing.T) { progressDeadlineSeconds := utilpointer.Int32Ptr(2) testcases := map[string]struct { - deploymentSpec1 *extensions.DeploymentSpec + deploymentSpec1 *apps.DeploymentSpec deploymentSpec2 *appsv1.DeploymentSpec }{ "DeploymentSpec Conversion 1": { - deploymentSpec1: &extensions.DeploymentSpec{ + deploymentSpec1: &apps.DeploymentSpec{ Replicas: *replica, Template: api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -365,7 +364,7 @@ func TestV1DeploymentSpecConversion(t *testing.T) { }, }, "DeploymentSpec Conversion 2": { - deploymentSpec1: &extensions.DeploymentSpec{ + deploymentSpec1: &apps.DeploymentSpec{ Replicas: *replica, RevisionHistoryLimit: revisionHistoryLimit, MinReadySeconds: 2, @@ -389,7 +388,7 @@ func TestV1DeploymentSpecConversion(t *testing.T) { }, }, "DeploymentSpec Conversion 3": { - deploymentSpec1: &extensions.DeploymentSpec{ + deploymentSpec1: &apps.DeploymentSpec{ Replicas: *replica, ProgressDeadlineSeconds: progressDeadlineSeconds, Template: api.PodTemplateSpec{ @@ -410,26 +409,26 @@ func TestV1DeploymentSpecConversion(t *testing.T) { }, } - // extensions -> appsv1 + // apps -> appsv1 for k, tc := range testcases { internal := &appsv1.DeploymentSpec{} if err := legacyscheme.Scheme.Convert(tc.deploymentSpec1, internal, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", "extensions -> appsv1", k, err) + t.Errorf("%q - %q: unexpected error: %v", "apps -> appsv1", k, err) } if !apiequality.Semantic.DeepEqual(internal, tc.deploymentSpec2) { - t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", "extensions -> appsv1", k, tc.deploymentSpec2, internal) + t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", "apps -> appsv1", k, tc.deploymentSpec2, internal) } } - // appsv1 -> extensions + // appsv1 -> apps for k, tc := range testcases { - internal := &extensions.DeploymentSpec{} + internal := &apps.DeploymentSpec{} if err := legacyscheme.Scheme.Convert(tc.deploymentSpec2, internal, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", "appsv1 -> extensions", k, err) + t.Errorf("%q - %q: unexpected error: %v", "appsv1 -> apps", k, err) } if !apiequality.Semantic.DeepEqual(internal, tc.deploymentSpec1) { - t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", "appsv1 -> extensions", k, tc.deploymentSpec1, internal) + t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", "appsv1 -> apps", k, tc.deploymentSpec1, internal) } } @@ -438,39 +437,39 @@ func TestV1DeploymentSpecConversion(t *testing.T) { func TestV1DeploymentStrategyConversion(t *testing.T) { maxUnavailable := intstr.FromInt(2) maxSurge := intstr.FromInt(2) - extensionsRollingUpdate := extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge} + appsRollingUpdate := apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge} appsv1RollingUpdate := appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &maxSurge} testcases := map[string]struct { - deploymentStrategy1 *extensions.DeploymentStrategy + deploymentStrategy1 *apps.DeploymentStrategy deploymentStrategy2 *appsv1.DeploymentStrategy }{ "DeploymentStrategy Conversion 1": { - deploymentStrategy1: &extensions.DeploymentStrategy{Type: extensions.DeploymentStrategyType("foo")}, + deploymentStrategy1: &apps.DeploymentStrategy{Type: apps.DeploymentStrategyType("foo")}, deploymentStrategy2: &appsv1.DeploymentStrategy{Type: appsv1.DeploymentStrategyType("foo")}, }, "DeploymentStrategy Conversion 2": { - deploymentStrategy1: &extensions.DeploymentStrategy{Type: extensions.DeploymentStrategyType("foo"), RollingUpdate: &extensionsRollingUpdate}, + deploymentStrategy1: &apps.DeploymentStrategy{Type: apps.DeploymentStrategyType("foo"), RollingUpdate: &appsRollingUpdate}, deploymentStrategy2: &appsv1.DeploymentStrategy{Type: appsv1.DeploymentStrategyType("foo"), RollingUpdate: &appsv1RollingUpdate}, }, } for k, tc := range testcases { - // extensions -> appsv1 + // apps -> appsv1 internal1 := &appsv1.DeploymentStrategy{} if err := legacyscheme.Scheme.Convert(tc.deploymentStrategy1, internal1, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "extensions -> appsv1", err) + t.Errorf("%q - %q: unexpected error: %v", k, "apps -> appsv1", err) } if !apiequality.Semantic.DeepEqual(internal1, tc.deploymentStrategy2) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "extensions -> appsv1", tc.deploymentStrategy2, internal1) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "apps -> appsv1", tc.deploymentStrategy2, internal1) } - // appsv1 -> extensions - internal2 := &extensions.DeploymentStrategy{} + // appsv1 -> apps + internal2 := &apps.DeploymentStrategy{} if err := legacyscheme.Scheme.Convert(tc.deploymentStrategy2, internal2, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> extensions", err) + t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> apps", err) } if !apiequality.Semantic.DeepEqual(internal2, tc.deploymentStrategy1) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "appsv1 -> extensions", tc.deploymentStrategy1, internal2) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "appsv1 -> apps", tc.deploymentStrategy1, internal2) } } } @@ -480,44 +479,44 @@ func TestV1RollingUpdateDeploymentConversion(t *testing.T) { maxUnavailable := intstr.FromInt(2) maxSurge := intstr.FromInt(2) testcases := map[string]struct { - rollingUpdateDeployment1 *extensions.RollingUpdateDeployment + rollingUpdateDeployment1 *apps.RollingUpdateDeployment rollingUpdateDeployment2 *appsv1.RollingUpdateDeployment }{ "RollingUpdateDeployment Conversion 1": { - rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{}, + rollingUpdateDeployment1: &apps.RollingUpdateDeployment{}, rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &nilIntStr, MaxSurge: &nilIntStr}, }, "RollingUpdateDeployment Conversion 2": { - rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable}, + rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable}, rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &nilIntStr}, }, "RollingUpdateDeployment Conversion 3": { - rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxSurge: maxSurge}, + rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxSurge: maxSurge}, rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxSurge: &maxSurge, MaxUnavailable: &nilIntStr}, }, "RollingUpdateDeployment Conversion 4": { - rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge}, + rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge}, rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &maxSurge}, }, } for k, tc := range testcases { - // extensions -> appsv1 + // apps -> appsv1 internal1 := &appsv1.RollingUpdateDeployment{} if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDeployment1, internal1, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "extensions -> appsv1", err) + t.Errorf("%q - %q: unexpected error: %v", k, "apps -> appsv1", err) } if !apiequality.Semantic.DeepEqual(internal1, tc.rollingUpdateDeployment2) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "extensions -> appsv1", tc.rollingUpdateDeployment2, internal1) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "apps -> appsv1", tc.rollingUpdateDeployment2, internal1) } - // appsv1 -> extensions - internal2 := &extensions.RollingUpdateDeployment{} + // appsv1 -> apps + internal2 := &apps.RollingUpdateDeployment{} if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDeployment2, internal2, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> extensions", err) + t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> apps", err) } if !apiequality.Semantic.DeepEqual(internal2, tc.rollingUpdateDeployment1) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "appsv1 -> extensions", tc.rollingUpdateDeployment1, internal2) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "appsv1 -> apps", tc.rollingUpdateDeployment1, internal2) } } } @@ -532,11 +531,11 @@ func TestV1ReplicaSetSpecConversion(t *testing.T) { selector := &metav1.LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions} testcases := map[string]struct { - replicaset1 *extensions.ReplicaSetSpec + replicaset1 *apps.ReplicaSetSpec replicaset2 *appsv1.ReplicaSetSpec }{ "ReplicaSetSpec Conversion 1": { - replicaset1: &extensions.ReplicaSetSpec{ + replicaset1: &apps.ReplicaSetSpec{ Replicas: *replicas, MinReadySeconds: 2, Template: api.PodTemplateSpec{ @@ -556,7 +555,7 @@ func TestV1ReplicaSetSpecConversion(t *testing.T) { }, }, "ReplicaSetSpec Conversion 2": { - replicaset1: &extensions.ReplicaSetSpec{ + replicaset1: &apps.ReplicaSetSpec{ Replicas: *replicas, Selector: selector, Template: api.PodTemplateSpec{ @@ -578,23 +577,23 @@ func TestV1ReplicaSetSpecConversion(t *testing.T) { } for k, tc := range testcases { - // extensions -> appsv1 + // apps -> appsv1 internal1 := &appsv1.ReplicaSetSpec{} if err := legacyscheme.Scheme.Convert(tc.replicaset1, internal1, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "extensions -> appsv1", err) + t.Errorf("%q - %q: unexpected error: %v", k, "apps -> appsv1", err) } if !apiequality.Semantic.DeepEqual(internal1, tc.replicaset2) { - t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "extensions -> appsv1", tc.replicaset2, internal1) + t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "apps -> appsv1", tc.replicaset2, internal1) } - // appsv1 -> extensions - internal2 := &extensions.ReplicaSetSpec{} + // appsv1 -> apps + internal2 := &apps.ReplicaSetSpec{} if err := legacyscheme.Scheme.Convert(tc.replicaset2, internal2, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> extensions", err) + t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> apps", err) } if !apiequality.Semantic.DeepEqual(internal2, tc.replicaset1) { - t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "appsv1 -> extensions", tc.replicaset1, internal2) + t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "appsv1 -> apps", tc.replicaset1, internal2) } } } diff --git a/pkg/apis/apps/v1/doc.go b/pkg/apis/apps/v1/doc.go index b70ddca6da8f9..7920560d2a3fb 100644 --- a/pkg/apis/apps/v1/doc.go +++ b/pkg/apis/apps/v1/doc.go @@ -15,7 +15,6 @@ limitations under the License. */ // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/apps -// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/extensions // +k8s:conversion-gen-external-types=k8s.io/api/apps/v1 // +k8s:defaulter-gen=TypeMeta // +k8s:defaulter-gen-input=../../../../vendor/k8s.io/api/apps/v1 diff --git a/pkg/apis/apps/v1/zz_generated.conversion.go b/pkg/apis/apps/v1/zz_generated.conversion.go index dfeb85fe87d3d..0c0c636dd85d0 100644 --- a/pkg/apis/apps/v1/zz_generated.conversion.go +++ b/pkg/apis/apps/v1/zz_generated.conversion.go @@ -31,7 +31,6 @@ import ( apps "k8s.io/kubernetes/pkg/apis/apps" core "k8s.io/kubernetes/pkg/apis/core" apiscorev1 "k8s.io/kubernetes/pkg/apis/core/v1" - extensions "k8s.io/kubernetes/pkg/apis/extensions" ) func init() { @@ -61,193 +60,193 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DaemonSet)(nil), (*extensions.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSet_To_extensions_DaemonSet(a.(*v1.DaemonSet), b.(*extensions.DaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*v1.DaemonSet)(nil), (*apps.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSet_To_apps_DaemonSet(a.(*v1.DaemonSet), b.(*apps.DaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSet)(nil), (*v1.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSet_To_v1_DaemonSet(a.(*extensions.DaemonSet), b.(*v1.DaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSet)(nil), (*v1.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSet_To_v1_DaemonSet(a.(*apps.DaemonSet), b.(*v1.DaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DaemonSetCondition)(nil), (*extensions.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSetCondition_To_extensions_DaemonSetCondition(a.(*v1.DaemonSetCondition), b.(*extensions.DaemonSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1.DaemonSetCondition)(nil), (*apps.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSetCondition_To_apps_DaemonSetCondition(a.(*v1.DaemonSetCondition), b.(*apps.DaemonSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetCondition)(nil), (*v1.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetCondition_To_v1_DaemonSetCondition(a.(*extensions.DaemonSetCondition), b.(*v1.DaemonSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetCondition)(nil), (*v1.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetCondition_To_v1_DaemonSetCondition(a.(*apps.DaemonSetCondition), b.(*v1.DaemonSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DaemonSetList)(nil), (*extensions.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSetList_To_extensions_DaemonSetList(a.(*v1.DaemonSetList), b.(*extensions.DaemonSetList), scope) + if err := s.AddGeneratedConversionFunc((*v1.DaemonSetList)(nil), (*apps.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSetList_To_apps_DaemonSetList(a.(*v1.DaemonSetList), b.(*apps.DaemonSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetList)(nil), (*v1.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetList_To_v1_DaemonSetList(a.(*extensions.DaemonSetList), b.(*v1.DaemonSetList), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetList)(nil), (*v1.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetList_To_v1_DaemonSetList(a.(*apps.DaemonSetList), b.(*v1.DaemonSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DaemonSetSpec)(nil), (*extensions.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec(a.(*v1.DaemonSetSpec), b.(*extensions.DaemonSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1.DaemonSetSpec)(nil), (*apps.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSetSpec_To_apps_DaemonSetSpec(a.(*v1.DaemonSetSpec), b.(*apps.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetSpec)(nil), (*v1.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec(a.(*extensions.DaemonSetSpec), b.(*v1.DaemonSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetSpec)(nil), (*v1.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetSpec_To_v1_DaemonSetSpec(a.(*apps.DaemonSetSpec), b.(*v1.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DaemonSetStatus)(nil), (*extensions.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSetStatus_To_extensions_DaemonSetStatus(a.(*v1.DaemonSetStatus), b.(*extensions.DaemonSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1.DaemonSetStatus)(nil), (*apps.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSetStatus_To_apps_DaemonSetStatus(a.(*v1.DaemonSetStatus), b.(*apps.DaemonSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetStatus)(nil), (*v1.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetStatus_To_v1_DaemonSetStatus(a.(*extensions.DaemonSetStatus), b.(*v1.DaemonSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetStatus)(nil), (*v1.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetStatus_To_v1_DaemonSetStatus(a.(*apps.DaemonSetStatus), b.(*v1.DaemonSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DaemonSetUpdateStrategy)(nil), (*extensions.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(a.(*v1.DaemonSetUpdateStrategy), b.(*extensions.DaemonSetUpdateStrategy), scope) + if err := s.AddGeneratedConversionFunc((*v1.DaemonSetUpdateStrategy)(nil), (*apps.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(a.(*v1.DaemonSetUpdateStrategy), b.(*apps.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetUpdateStrategy)(nil), (*v1.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(a.(*extensions.DaemonSetUpdateStrategy), b.(*v1.DaemonSetUpdateStrategy), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetUpdateStrategy)(nil), (*v1.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(a.(*apps.DaemonSetUpdateStrategy), b.(*v1.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.Deployment)(nil), (*extensions.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_Deployment_To_extensions_Deployment(a.(*v1.Deployment), b.(*extensions.Deployment), scope) + if err := s.AddGeneratedConversionFunc((*v1.Deployment)(nil), (*apps.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_Deployment_To_apps_Deployment(a.(*v1.Deployment), b.(*apps.Deployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.Deployment)(nil), (*v1.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_Deployment_To_v1_Deployment(a.(*extensions.Deployment), b.(*v1.Deployment), scope) + if err := s.AddGeneratedConversionFunc((*apps.Deployment)(nil), (*v1.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_Deployment_To_v1_Deployment(a.(*apps.Deployment), b.(*v1.Deployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DeploymentCondition)(nil), (*extensions.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DeploymentCondition_To_extensions_DeploymentCondition(a.(*v1.DeploymentCondition), b.(*extensions.DeploymentCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1.DeploymentCondition)(nil), (*apps.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DeploymentCondition_To_apps_DeploymentCondition(a.(*v1.DeploymentCondition), b.(*apps.DeploymentCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentCondition)(nil), (*v1.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentCondition_To_v1_DeploymentCondition(a.(*extensions.DeploymentCondition), b.(*v1.DeploymentCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentCondition)(nil), (*v1.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentCondition_To_v1_DeploymentCondition(a.(*apps.DeploymentCondition), b.(*v1.DeploymentCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DeploymentList)(nil), (*extensions.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DeploymentList_To_extensions_DeploymentList(a.(*v1.DeploymentList), b.(*extensions.DeploymentList), scope) + if err := s.AddGeneratedConversionFunc((*v1.DeploymentList)(nil), (*apps.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DeploymentList_To_apps_DeploymentList(a.(*v1.DeploymentList), b.(*apps.DeploymentList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentList)(nil), (*v1.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentList_To_v1_DeploymentList(a.(*extensions.DeploymentList), b.(*v1.DeploymentList), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentList)(nil), (*v1.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentList_To_v1_DeploymentList(a.(*apps.DeploymentList), b.(*v1.DeploymentList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DeploymentSpec)(nil), (*extensions.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(a.(*v1.DeploymentSpec), b.(*extensions.DeploymentSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1.DeploymentSpec)(nil), (*apps.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DeploymentSpec_To_apps_DeploymentSpec(a.(*v1.DeploymentSpec), b.(*apps.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentSpec)(nil), (*v1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec(a.(*extensions.DeploymentSpec), b.(*v1.DeploymentSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentSpec)(nil), (*v1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentSpec_To_v1_DeploymentSpec(a.(*apps.DeploymentSpec), b.(*v1.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DeploymentStatus)(nil), (*extensions.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DeploymentStatus_To_extensions_DeploymentStatus(a.(*v1.DeploymentStatus), b.(*extensions.DeploymentStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1.DeploymentStatus)(nil), (*apps.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DeploymentStatus_To_apps_DeploymentStatus(a.(*v1.DeploymentStatus), b.(*apps.DeploymentStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentStatus)(nil), (*v1.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStatus_To_v1_DeploymentStatus(a.(*extensions.DeploymentStatus), b.(*v1.DeploymentStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentStatus)(nil), (*v1.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStatus_To_v1_DeploymentStatus(a.(*apps.DeploymentStatus), b.(*v1.DeploymentStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.DeploymentStrategy)(nil), (*extensions.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(a.(*v1.DeploymentStrategy), b.(*extensions.DeploymentStrategy), scope) + if err := s.AddGeneratedConversionFunc((*v1.DeploymentStrategy)(nil), (*apps.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DeploymentStrategy_To_apps_DeploymentStrategy(a.(*v1.DeploymentStrategy), b.(*apps.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentStrategy)(nil), (*v1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(a.(*extensions.DeploymentStrategy), b.(*v1.DeploymentStrategy), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentStrategy)(nil), (*v1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStrategy_To_v1_DeploymentStrategy(a.(*apps.DeploymentStrategy), b.(*v1.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.ReplicaSet)(nil), (*extensions.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicaSet_To_extensions_ReplicaSet(a.(*v1.ReplicaSet), b.(*extensions.ReplicaSet), scope) + if err := s.AddGeneratedConversionFunc((*v1.ReplicaSet)(nil), (*apps.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicaSet_To_apps_ReplicaSet(a.(*v1.ReplicaSet), b.(*apps.ReplicaSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSet)(nil), (*v1.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSet_To_v1_ReplicaSet(a.(*extensions.ReplicaSet), b.(*v1.ReplicaSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSet)(nil), (*v1.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSet_To_v1_ReplicaSet(a.(*apps.ReplicaSet), b.(*v1.ReplicaSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.ReplicaSetCondition)(nil), (*extensions.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(a.(*v1.ReplicaSetCondition), b.(*extensions.ReplicaSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1.ReplicaSetCondition)(nil), (*apps.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicaSetCondition_To_apps_ReplicaSetCondition(a.(*v1.ReplicaSetCondition), b.(*apps.ReplicaSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetCondition)(nil), (*v1.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetCondition_To_v1_ReplicaSetCondition(a.(*extensions.ReplicaSetCondition), b.(*v1.ReplicaSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetCondition)(nil), (*v1.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetCondition_To_v1_ReplicaSetCondition(a.(*apps.ReplicaSetCondition), b.(*v1.ReplicaSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.ReplicaSetList)(nil), (*extensions.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicaSetList_To_extensions_ReplicaSetList(a.(*v1.ReplicaSetList), b.(*extensions.ReplicaSetList), scope) + if err := s.AddGeneratedConversionFunc((*v1.ReplicaSetList)(nil), (*apps.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicaSetList_To_apps_ReplicaSetList(a.(*v1.ReplicaSetList), b.(*apps.ReplicaSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetList)(nil), (*v1.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetList_To_v1_ReplicaSetList(a.(*extensions.ReplicaSetList), b.(*v1.ReplicaSetList), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetList)(nil), (*v1.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetList_To_v1_ReplicaSetList(a.(*apps.ReplicaSetList), b.(*v1.ReplicaSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.ReplicaSetSpec)(nil), (*extensions.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(a.(*v1.ReplicaSetSpec), b.(*extensions.ReplicaSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1.ReplicaSetSpec)(nil), (*apps.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicaSetSpec_To_apps_ReplicaSetSpec(a.(*v1.ReplicaSetSpec), b.(*apps.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetSpec)(nil), (*v1.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec(a.(*extensions.ReplicaSetSpec), b.(*v1.ReplicaSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetSpec)(nil), (*v1.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetSpec_To_v1_ReplicaSetSpec(a.(*apps.ReplicaSetSpec), b.(*v1.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.ReplicaSetStatus)(nil), (*extensions.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(a.(*v1.ReplicaSetStatus), b.(*extensions.ReplicaSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1.ReplicaSetStatus)(nil), (*apps.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicaSetStatus_To_apps_ReplicaSetStatus(a.(*v1.ReplicaSetStatus), b.(*apps.ReplicaSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetStatus)(nil), (*v1.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetStatus_To_v1_ReplicaSetStatus(a.(*extensions.ReplicaSetStatus), b.(*v1.ReplicaSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetStatus)(nil), (*v1.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetStatus_To_v1_ReplicaSetStatus(a.(*apps.ReplicaSetStatus), b.(*v1.ReplicaSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.RollingUpdateDaemonSet)(nil), (*extensions.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(a.(*v1.RollingUpdateDaemonSet), b.(*extensions.RollingUpdateDaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*v1.RollingUpdateDaemonSet)(nil), (*apps.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(a.(*v1.RollingUpdateDaemonSet), b.(*apps.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollingUpdateDaemonSet)(nil), (*v1.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(a.(*extensions.RollingUpdateDaemonSet), b.(*v1.RollingUpdateDaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollingUpdateDaemonSet)(nil), (*v1.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(a.(*apps.RollingUpdateDaemonSet), b.(*v1.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.RollingUpdateDeployment)(nil), (*extensions.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(a.(*v1.RollingUpdateDeployment), b.(*extensions.RollingUpdateDeployment), scope) + if err := s.AddGeneratedConversionFunc((*v1.RollingUpdateDeployment)(nil), (*apps.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(a.(*v1.RollingUpdateDeployment), b.(*apps.RollingUpdateDeployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollingUpdateDeployment)(nil), (*v1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(a.(*extensions.RollingUpdateDeployment), b.(*v1.RollingUpdateDeployment), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollingUpdateDeployment)(nil), (*v1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(a.(*apps.RollingUpdateDeployment), b.(*v1.RollingUpdateDeployment), scope) }); err != nil { return err } @@ -321,108 +320,108 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*apps.StatefulSetSpec)(nil), (*v1.StatefulSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apps_StatefulSetSpec_To_v1_StatefulSetSpec(a.(*apps.StatefulSetSpec), b.(*v1.StatefulSetSpec), scope) + if err := s.AddConversionFunc((*apps.DaemonSetSpec)(nil), (*v1.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetSpec_To_v1_DaemonSetSpec(a.(*apps.DaemonSetSpec), b.(*v1.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*apps.StatefulSetStatus)(nil), (*v1.StatefulSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apps_StatefulSetStatus_To_v1_StatefulSetStatus(a.(*apps.StatefulSetStatus), b.(*v1.StatefulSetStatus), scope) + if err := s.AddConversionFunc((*apps.DaemonSetUpdateStrategy)(nil), (*v1.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(a.(*apps.DaemonSetUpdateStrategy), b.(*v1.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*apps.StatefulSetUpdateStrategy)(nil), (*v1.StatefulSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apps_StatefulSetUpdateStrategy_To_v1_StatefulSetUpdateStrategy(a.(*apps.StatefulSetUpdateStrategy), b.(*v1.StatefulSetUpdateStrategy), scope) + if err := s.AddConversionFunc((*apps.DaemonSet)(nil), (*v1.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSet_To_v1_DaemonSet(a.(*apps.DaemonSet), b.(*v1.DaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DaemonSetSpec)(nil), (*v1.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec(a.(*extensions.DaemonSetSpec), b.(*v1.DaemonSetSpec), scope) + if err := s.AddConversionFunc((*apps.DeploymentSpec)(nil), (*v1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentSpec_To_v1_DeploymentSpec(a.(*apps.DeploymentSpec), b.(*v1.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DaemonSetUpdateStrategy)(nil), (*v1.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(a.(*extensions.DaemonSetUpdateStrategy), b.(*v1.DaemonSetUpdateStrategy), scope) + if err := s.AddConversionFunc((*apps.DeploymentStrategy)(nil), (*v1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStrategy_To_v1_DeploymentStrategy(a.(*apps.DeploymentStrategy), b.(*v1.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DaemonSet)(nil), (*v1.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSet_To_v1_DaemonSet(a.(*extensions.DaemonSet), b.(*v1.DaemonSet), scope) + if err := s.AddConversionFunc((*apps.Deployment)(nil), (*v1.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_Deployment_To_v1_Deployment(a.(*apps.Deployment), b.(*v1.Deployment), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DeploymentSpec)(nil), (*v1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec(a.(*extensions.DeploymentSpec), b.(*v1.DeploymentSpec), scope) + if err := s.AddConversionFunc((*apps.ReplicaSetSpec)(nil), (*v1.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetSpec_To_v1_ReplicaSetSpec(a.(*apps.ReplicaSetSpec), b.(*v1.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DeploymentStrategy)(nil), (*v1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(a.(*extensions.DeploymentStrategy), b.(*v1.DeploymentStrategy), scope) + if err := s.AddConversionFunc((*apps.RollingUpdateDaemonSet)(nil), (*v1.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(a.(*apps.RollingUpdateDaemonSet), b.(*v1.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.Deployment)(nil), (*v1.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_Deployment_To_v1_Deployment(a.(*extensions.Deployment), b.(*v1.Deployment), scope) + if err := s.AddConversionFunc((*apps.RollingUpdateDeployment)(nil), (*v1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(a.(*apps.RollingUpdateDeployment), b.(*v1.RollingUpdateDeployment), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.ReplicaSetSpec)(nil), (*v1.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec(a.(*extensions.ReplicaSetSpec), b.(*v1.ReplicaSetSpec), scope) + if err := s.AddConversionFunc((*apps.StatefulSetSpec)(nil), (*v1.StatefulSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_StatefulSetSpec_To_v1_StatefulSetSpec(a.(*apps.StatefulSetSpec), b.(*v1.StatefulSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.RollingUpdateDaemonSet)(nil), (*v1.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(a.(*extensions.RollingUpdateDaemonSet), b.(*v1.RollingUpdateDaemonSet), scope) + if err := s.AddConversionFunc((*apps.StatefulSetStatus)(nil), (*v1.StatefulSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_StatefulSetStatus_To_v1_StatefulSetStatus(a.(*apps.StatefulSetStatus), b.(*v1.StatefulSetStatus), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.RollingUpdateDeployment)(nil), (*v1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(a.(*extensions.RollingUpdateDeployment), b.(*v1.RollingUpdateDeployment), scope) + if err := s.AddConversionFunc((*apps.StatefulSetUpdateStrategy)(nil), (*v1.StatefulSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_StatefulSetUpdateStrategy_To_v1_StatefulSetUpdateStrategy(a.(*apps.StatefulSetUpdateStrategy), b.(*v1.StatefulSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.DaemonSetSpec)(nil), (*extensions.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec(a.(*v1.DaemonSetSpec), b.(*extensions.DaemonSetSpec), scope) + if err := s.AddConversionFunc((*v1.DaemonSetSpec)(nil), (*apps.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSetSpec_To_apps_DaemonSetSpec(a.(*v1.DaemonSetSpec), b.(*apps.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.DaemonSetUpdateStrategy)(nil), (*extensions.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(a.(*v1.DaemonSetUpdateStrategy), b.(*extensions.DaemonSetUpdateStrategy), scope) + if err := s.AddConversionFunc((*v1.DaemonSetUpdateStrategy)(nil), (*apps.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(a.(*v1.DaemonSetUpdateStrategy), b.(*apps.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.DaemonSet)(nil), (*extensions.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DaemonSet_To_extensions_DaemonSet(a.(*v1.DaemonSet), b.(*extensions.DaemonSet), scope) + if err := s.AddConversionFunc((*v1.DaemonSet)(nil), (*apps.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DaemonSet_To_apps_DaemonSet(a.(*v1.DaemonSet), b.(*apps.DaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.DeploymentSpec)(nil), (*extensions.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(a.(*v1.DeploymentSpec), b.(*extensions.DeploymentSpec), scope) + if err := s.AddConversionFunc((*v1.DeploymentSpec)(nil), (*apps.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DeploymentSpec_To_apps_DeploymentSpec(a.(*v1.DeploymentSpec), b.(*apps.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.DeploymentStrategy)(nil), (*extensions.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(a.(*v1.DeploymentStrategy), b.(*extensions.DeploymentStrategy), scope) + if err := s.AddConversionFunc((*v1.DeploymentStrategy)(nil), (*apps.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_DeploymentStrategy_To_apps_DeploymentStrategy(a.(*v1.DeploymentStrategy), b.(*apps.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.Deployment)(nil), (*extensions.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_Deployment_To_extensions_Deployment(a.(*v1.Deployment), b.(*extensions.Deployment), scope) + if err := s.AddConversionFunc((*v1.Deployment)(nil), (*apps.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_Deployment_To_apps_Deployment(a.(*v1.Deployment), b.(*apps.Deployment), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.ReplicaSetSpec)(nil), (*extensions.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(a.(*v1.ReplicaSetSpec), b.(*extensions.ReplicaSetSpec), scope) + if err := s.AddConversionFunc((*v1.ReplicaSetSpec)(nil), (*apps.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicaSetSpec_To_apps_ReplicaSetSpec(a.(*v1.ReplicaSetSpec), b.(*apps.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.RollingUpdateDaemonSet)(nil), (*extensions.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(a.(*v1.RollingUpdateDaemonSet), b.(*extensions.RollingUpdateDaemonSet), scope) + if err := s.AddConversionFunc((*v1.RollingUpdateDaemonSet)(nil), (*apps.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(a.(*v1.RollingUpdateDaemonSet), b.(*apps.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.RollingUpdateDeployment)(nil), (*extensions.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(a.(*v1.RollingUpdateDeployment), b.(*extensions.RollingUpdateDeployment), scope) + if err := s.AddConversionFunc((*v1.RollingUpdateDeployment)(nil), (*apps.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(a.(*v1.RollingUpdateDeployment), b.(*apps.RollingUpdateDeployment), scope) }); err != nil { return err } @@ -514,30 +513,30 @@ func Convert_apps_ControllerRevisionList_To_v1_ControllerRevisionList(in *apps.C return autoConvert_apps_ControllerRevisionList_To_v1_ControllerRevisionList(in, out, s) } -func autoConvert_v1_DaemonSet_To_extensions_DaemonSet(in *v1.DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error { +func autoConvert_v1_DaemonSet_To_apps_DaemonSet(in *v1.DaemonSet, out *apps.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1_DaemonSetSpec_To_apps_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1_DaemonSetStatus_To_extensions_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1_DaemonSetStatus_To_apps_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func autoConvert_extensions_DaemonSet_To_v1_DaemonSet(in *extensions.DaemonSet, out *v1.DaemonSet, s conversion.Scope) error { +func autoConvert_apps_DaemonSet_To_v1_DaemonSet(in *apps.DaemonSet, out *v1.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DaemonSetSpec_To_v1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_DaemonSetStatus_To_v1_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DaemonSetStatus_To_v1_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func autoConvert_v1_DaemonSetCondition_To_extensions_DaemonSetCondition(in *v1.DaemonSetCondition, out *extensions.DaemonSetCondition, s conversion.Scope) error { - out.Type = extensions.DaemonSetConditionType(in.Type) +func autoConvert_v1_DaemonSetCondition_To_apps_DaemonSetCondition(in *v1.DaemonSetCondition, out *apps.DaemonSetCondition, s conversion.Scope) error { + out.Type = apps.DaemonSetConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime out.Reason = in.Reason @@ -545,12 +544,12 @@ func autoConvert_v1_DaemonSetCondition_To_extensions_DaemonSetCondition(in *v1.D return nil } -// Convert_v1_DaemonSetCondition_To_extensions_DaemonSetCondition is an autogenerated conversion function. -func Convert_v1_DaemonSetCondition_To_extensions_DaemonSetCondition(in *v1.DaemonSetCondition, out *extensions.DaemonSetCondition, s conversion.Scope) error { - return autoConvert_v1_DaemonSetCondition_To_extensions_DaemonSetCondition(in, out, s) +// Convert_v1_DaemonSetCondition_To_apps_DaemonSetCondition is an autogenerated conversion function. +func Convert_v1_DaemonSetCondition_To_apps_DaemonSetCondition(in *v1.DaemonSetCondition, out *apps.DaemonSetCondition, s conversion.Scope) error { + return autoConvert_v1_DaemonSetCondition_To_apps_DaemonSetCondition(in, out, s) } -func autoConvert_extensions_DaemonSetCondition_To_v1_DaemonSetCondition(in *extensions.DaemonSetCondition, out *v1.DaemonSetCondition, s conversion.Scope) error { +func autoConvert_apps_DaemonSetCondition_To_v1_DaemonSetCondition(in *apps.DaemonSetCondition, out *v1.DaemonSetCondition, s conversion.Scope) error { out.Type = v1.DaemonSetConditionType(in.Type) out.Status = corev1.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime @@ -559,18 +558,18 @@ func autoConvert_extensions_DaemonSetCondition_To_v1_DaemonSetCondition(in *exte return nil } -// Convert_extensions_DaemonSetCondition_To_v1_DaemonSetCondition is an autogenerated conversion function. -func Convert_extensions_DaemonSetCondition_To_v1_DaemonSetCondition(in *extensions.DaemonSetCondition, out *v1.DaemonSetCondition, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetCondition_To_v1_DaemonSetCondition(in, out, s) +// Convert_apps_DaemonSetCondition_To_v1_DaemonSetCondition is an autogenerated conversion function. +func Convert_apps_DaemonSetCondition_To_v1_DaemonSetCondition(in *apps.DaemonSetCondition, out *v1.DaemonSetCondition, s conversion.Scope) error { + return autoConvert_apps_DaemonSetCondition_To_v1_DaemonSetCondition(in, out, s) } -func autoConvert_v1_DaemonSetList_To_extensions_DaemonSetList(in *v1.DaemonSetList, out *extensions.DaemonSetList, s conversion.Scope) error { +func autoConvert_v1_DaemonSetList_To_apps_DaemonSetList(in *v1.DaemonSetList, out *apps.DaemonSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.DaemonSet, len(*in)) + *out = make([]apps.DaemonSet, len(*in)) for i := range *in { - if err := Convert_v1_DaemonSet_To_extensions_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1_DaemonSet_To_apps_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -580,18 +579,18 @@ func autoConvert_v1_DaemonSetList_To_extensions_DaemonSetList(in *v1.DaemonSetLi return nil } -// Convert_v1_DaemonSetList_To_extensions_DaemonSetList is an autogenerated conversion function. -func Convert_v1_DaemonSetList_To_extensions_DaemonSetList(in *v1.DaemonSetList, out *extensions.DaemonSetList, s conversion.Scope) error { - return autoConvert_v1_DaemonSetList_To_extensions_DaemonSetList(in, out, s) +// Convert_v1_DaemonSetList_To_apps_DaemonSetList is an autogenerated conversion function. +func Convert_v1_DaemonSetList_To_apps_DaemonSetList(in *v1.DaemonSetList, out *apps.DaemonSetList, s conversion.Scope) error { + return autoConvert_v1_DaemonSetList_To_apps_DaemonSetList(in, out, s) } -func autoConvert_extensions_DaemonSetList_To_v1_DaemonSetList(in *extensions.DaemonSetList, out *v1.DaemonSetList, s conversion.Scope) error { +func autoConvert_apps_DaemonSetList_To_v1_DaemonSetList(in *apps.DaemonSetList, out *v1.DaemonSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1.DaemonSet, len(*in)) for i := range *in { - if err := Convert_extensions_DaemonSet_To_v1_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_DaemonSet_To_v1_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -601,17 +600,17 @@ func autoConvert_extensions_DaemonSetList_To_v1_DaemonSetList(in *extensions.Dae return nil } -// Convert_extensions_DaemonSetList_To_v1_DaemonSetList is an autogenerated conversion function. -func Convert_extensions_DaemonSetList_To_v1_DaemonSetList(in *extensions.DaemonSetList, out *v1.DaemonSetList, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetList_To_v1_DaemonSetList(in, out, s) +// Convert_apps_DaemonSetList_To_v1_DaemonSetList is an autogenerated conversion function. +func Convert_apps_DaemonSetList_To_v1_DaemonSetList(in *apps.DaemonSetList, out *v1.DaemonSetList, s conversion.Scope) error { + return autoConvert_apps_DaemonSetList_To_v1_DaemonSetList(in, out, s) } -func autoConvert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *v1.DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error { +func autoConvert_v1_DaemonSetSpec_To_apps_DaemonSetSpec(in *v1.DaemonSetSpec, out *apps.DaemonSetSpec, s conversion.Scope) error { out.Selector = (*metav1.LabelSelector)(unsafe.Pointer(in.Selector)) if err := apiscorev1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_v1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -619,12 +618,12 @@ func autoConvert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *v1.DaemonSetSp return nil } -func autoConvert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec(in *extensions.DaemonSetSpec, out *v1.DaemonSetSpec, s conversion.Scope) error { +func autoConvert_apps_DaemonSetSpec_To_v1_DaemonSetSpec(in *apps.DaemonSetSpec, out *v1.DaemonSetSpec, s conversion.Scope) error { out.Selector = (*metav1.LabelSelector)(unsafe.Pointer(in.Selector)) if err := apiscorev1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_apps_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -633,7 +632,7 @@ func autoConvert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec(in *extensions.Dae return nil } -func autoConvert_v1_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1.DaemonSetStatus, out *extensions.DaemonSetStatus, s conversion.Scope) error { +func autoConvert_v1_DaemonSetStatus_To_apps_DaemonSetStatus(in *v1.DaemonSetStatus, out *apps.DaemonSetStatus, s conversion.Scope) error { out.CurrentNumberScheduled = in.CurrentNumberScheduled out.NumberMisscheduled = in.NumberMisscheduled out.DesiredNumberScheduled = in.DesiredNumberScheduled @@ -643,16 +642,16 @@ func autoConvert_v1_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1.DaemonS out.NumberAvailable = in.NumberAvailable out.NumberUnavailable = in.NumberUnavailable out.CollisionCount = (*int32)(unsafe.Pointer(in.CollisionCount)) - out.Conditions = *(*[]extensions.DaemonSetCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.DaemonSetCondition)(unsafe.Pointer(&in.Conditions)) return nil } -// Convert_v1_DaemonSetStatus_To_extensions_DaemonSetStatus is an autogenerated conversion function. -func Convert_v1_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1.DaemonSetStatus, out *extensions.DaemonSetStatus, s conversion.Scope) error { - return autoConvert_v1_DaemonSetStatus_To_extensions_DaemonSetStatus(in, out, s) +// Convert_v1_DaemonSetStatus_To_apps_DaemonSetStatus is an autogenerated conversion function. +func Convert_v1_DaemonSetStatus_To_apps_DaemonSetStatus(in *v1.DaemonSetStatus, out *apps.DaemonSetStatus, s conversion.Scope) error { + return autoConvert_v1_DaemonSetStatus_To_apps_DaemonSetStatus(in, out, s) } -func autoConvert_extensions_DaemonSetStatus_To_v1_DaemonSetStatus(in *extensions.DaemonSetStatus, out *v1.DaemonSetStatus, s conversion.Scope) error { +func autoConvert_apps_DaemonSetStatus_To_v1_DaemonSetStatus(in *apps.DaemonSetStatus, out *v1.DaemonSetStatus, s conversion.Scope) error { out.CurrentNumberScheduled = in.CurrentNumberScheduled out.NumberMisscheduled = in.NumberMisscheduled out.DesiredNumberScheduled = in.DesiredNumberScheduled @@ -666,17 +665,17 @@ func autoConvert_extensions_DaemonSetStatus_To_v1_DaemonSetStatus(in *extensions return nil } -// Convert_extensions_DaemonSetStatus_To_v1_DaemonSetStatus is an autogenerated conversion function. -func Convert_extensions_DaemonSetStatus_To_v1_DaemonSetStatus(in *extensions.DaemonSetStatus, out *v1.DaemonSetStatus, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetStatus_To_v1_DaemonSetStatus(in, out, s) +// Convert_apps_DaemonSetStatus_To_v1_DaemonSetStatus is an autogenerated conversion function. +func Convert_apps_DaemonSetStatus_To_v1_DaemonSetStatus(in *apps.DaemonSetStatus, out *v1.DaemonSetStatus, s conversion.Scope) error { + return autoConvert_apps_DaemonSetStatus_To_v1_DaemonSetStatus(in, out, s) } -func autoConvert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in *v1.DaemonSetUpdateStrategy, out *extensions.DaemonSetUpdateStrategy, s conversion.Scope) error { - out.Type = extensions.DaemonSetUpdateStrategyType(in.Type) +func autoConvert_v1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(in *v1.DaemonSetUpdateStrategy, out *apps.DaemonSetUpdateStrategy, s conversion.Scope) error { + out.Type = apps.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(extensions.RollingUpdateDaemonSet) - if err := Convert_v1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(*in, *out, s); err != nil { + *out = new(apps.RollingUpdateDaemonSet) + if err := Convert_v1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(*in, *out, s); err != nil { return err } } else { @@ -685,12 +684,12 @@ func autoConvert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrateg return nil } -func autoConvert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(in *extensions.DaemonSetUpdateStrategy, out *v1.DaemonSetUpdateStrategy, s conversion.Scope) error { +func autoConvert_apps_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy(in *apps.DaemonSetUpdateStrategy, out *v1.DaemonSetUpdateStrategy, s conversion.Scope) error { out.Type = v1.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate *out = new(v1.RollingUpdateDaemonSet) - if err := Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(*in, *out, s); err != nil { + if err := Convert_apps_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(*in, *out, s); err != nil { return err } } else { @@ -699,30 +698,30 @@ func autoConvert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrateg return nil } -func autoConvert_v1_Deployment_To_extensions_Deployment(in *v1.Deployment, out *extensions.Deployment, s conversion.Scope) error { +func autoConvert_v1_Deployment_To_apps_Deployment(in *v1.Deployment, out *apps.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1_DeploymentSpec_To_apps_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1_DeploymentStatus_To_extensions_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1_DeploymentStatus_To_apps_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func autoConvert_extensions_Deployment_To_v1_Deployment(in *extensions.Deployment, out *v1.Deployment, s conversion.Scope) error { +func autoConvert_apps_Deployment_To_v1_Deployment(in *apps.Deployment, out *v1.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DeploymentSpec_To_v1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_DeploymentStatus_To_v1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DeploymentStatus_To_v1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func autoConvert_v1_DeploymentCondition_To_extensions_DeploymentCondition(in *v1.DeploymentCondition, out *extensions.DeploymentCondition, s conversion.Scope) error { - out.Type = extensions.DeploymentConditionType(in.Type) +func autoConvert_v1_DeploymentCondition_To_apps_DeploymentCondition(in *v1.DeploymentCondition, out *apps.DeploymentCondition, s conversion.Scope) error { + out.Type = apps.DeploymentConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastUpdateTime = in.LastUpdateTime out.LastTransitionTime = in.LastTransitionTime @@ -731,12 +730,12 @@ func autoConvert_v1_DeploymentCondition_To_extensions_DeploymentCondition(in *v1 return nil } -// Convert_v1_DeploymentCondition_To_extensions_DeploymentCondition is an autogenerated conversion function. -func Convert_v1_DeploymentCondition_To_extensions_DeploymentCondition(in *v1.DeploymentCondition, out *extensions.DeploymentCondition, s conversion.Scope) error { - return autoConvert_v1_DeploymentCondition_To_extensions_DeploymentCondition(in, out, s) +// Convert_v1_DeploymentCondition_To_apps_DeploymentCondition is an autogenerated conversion function. +func Convert_v1_DeploymentCondition_To_apps_DeploymentCondition(in *v1.DeploymentCondition, out *apps.DeploymentCondition, s conversion.Scope) error { + return autoConvert_v1_DeploymentCondition_To_apps_DeploymentCondition(in, out, s) } -func autoConvert_extensions_DeploymentCondition_To_v1_DeploymentCondition(in *extensions.DeploymentCondition, out *v1.DeploymentCondition, s conversion.Scope) error { +func autoConvert_apps_DeploymentCondition_To_v1_DeploymentCondition(in *apps.DeploymentCondition, out *v1.DeploymentCondition, s conversion.Scope) error { out.Type = v1.DeploymentConditionType(in.Type) out.Status = corev1.ConditionStatus(in.Status) out.LastUpdateTime = in.LastUpdateTime @@ -746,18 +745,18 @@ func autoConvert_extensions_DeploymentCondition_To_v1_DeploymentCondition(in *ex return nil } -// Convert_extensions_DeploymentCondition_To_v1_DeploymentCondition is an autogenerated conversion function. -func Convert_extensions_DeploymentCondition_To_v1_DeploymentCondition(in *extensions.DeploymentCondition, out *v1.DeploymentCondition, s conversion.Scope) error { - return autoConvert_extensions_DeploymentCondition_To_v1_DeploymentCondition(in, out, s) +// Convert_apps_DeploymentCondition_To_v1_DeploymentCondition is an autogenerated conversion function. +func Convert_apps_DeploymentCondition_To_v1_DeploymentCondition(in *apps.DeploymentCondition, out *v1.DeploymentCondition, s conversion.Scope) error { + return autoConvert_apps_DeploymentCondition_To_v1_DeploymentCondition(in, out, s) } -func autoConvert_v1_DeploymentList_To_extensions_DeploymentList(in *v1.DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { +func autoConvert_v1_DeploymentList_To_apps_DeploymentList(in *v1.DeploymentList, out *apps.DeploymentList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.Deployment, len(*in)) + *out = make([]apps.Deployment, len(*in)) for i := range *in { - if err := Convert_v1_Deployment_To_extensions_Deployment(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1_Deployment_To_apps_Deployment(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -767,18 +766,18 @@ func autoConvert_v1_DeploymentList_To_extensions_DeploymentList(in *v1.Deploymen return nil } -// Convert_v1_DeploymentList_To_extensions_DeploymentList is an autogenerated conversion function. -func Convert_v1_DeploymentList_To_extensions_DeploymentList(in *v1.DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { - return autoConvert_v1_DeploymentList_To_extensions_DeploymentList(in, out, s) +// Convert_v1_DeploymentList_To_apps_DeploymentList is an autogenerated conversion function. +func Convert_v1_DeploymentList_To_apps_DeploymentList(in *v1.DeploymentList, out *apps.DeploymentList, s conversion.Scope) error { + return autoConvert_v1_DeploymentList_To_apps_DeploymentList(in, out, s) } -func autoConvert_extensions_DeploymentList_To_v1_DeploymentList(in *extensions.DeploymentList, out *v1.DeploymentList, s conversion.Scope) error { +func autoConvert_apps_DeploymentList_To_v1_DeploymentList(in *apps.DeploymentList, out *v1.DeploymentList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1.Deployment, len(*in)) for i := range *in { - if err := Convert_extensions_Deployment_To_v1_Deployment(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_Deployment_To_v1_Deployment(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -788,12 +787,12 @@ func autoConvert_extensions_DeploymentList_To_v1_DeploymentList(in *extensions.D return nil } -// Convert_extensions_DeploymentList_To_v1_DeploymentList is an autogenerated conversion function. -func Convert_extensions_DeploymentList_To_v1_DeploymentList(in *extensions.DeploymentList, out *v1.DeploymentList, s conversion.Scope) error { - return autoConvert_extensions_DeploymentList_To_v1_DeploymentList(in, out, s) +// Convert_apps_DeploymentList_To_v1_DeploymentList is an autogenerated conversion function. +func Convert_apps_DeploymentList_To_v1_DeploymentList(in *apps.DeploymentList, out *v1.DeploymentList, s conversion.Scope) error { + return autoConvert_apps_DeploymentList_To_v1_DeploymentList(in, out, s) } -func autoConvert_v1_DeploymentSpec_To_extensions_DeploymentSpec(in *v1.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { +func autoConvert_v1_DeploymentSpec_To_apps_DeploymentSpec(in *v1.DeploymentSpec, out *apps.DeploymentSpec, s conversion.Scope) error { if err := metav1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -801,7 +800,7 @@ func autoConvert_v1_DeploymentSpec_To_extensions_DeploymentSpec(in *v1.Deploymen if err := apiscorev1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_v1_DeploymentStrategy_To_apps_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -811,7 +810,7 @@ func autoConvert_v1_DeploymentSpec_To_extensions_DeploymentSpec(in *v1.Deploymen return nil } -func autoConvert_extensions_DeploymentSpec_To_v1_DeploymentSpec(in *extensions.DeploymentSpec, out *v1.DeploymentSpec, s conversion.Scope) error { +func autoConvert_apps_DeploymentSpec_To_v1_DeploymentSpec(in *apps.DeploymentSpec, out *v1.DeploymentSpec, s conversion.Scope) error { if err := metav1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -819,7 +818,7 @@ func autoConvert_extensions_DeploymentSpec_To_v1_DeploymentSpec(in *extensions.D if err := apiscorev1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_apps_DeploymentStrategy_To_v1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -830,24 +829,24 @@ func autoConvert_extensions_DeploymentSpec_To_v1_DeploymentSpec(in *extensions.D return nil } -func autoConvert_v1_DeploymentStatus_To_extensions_DeploymentStatus(in *v1.DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { +func autoConvert_v1_DeploymentStatus_To_apps_DeploymentStatus(in *v1.DeploymentStatus, out *apps.DeploymentStatus, s conversion.Scope) error { out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas out.ReadyReplicas = in.ReadyReplicas out.AvailableReplicas = in.AvailableReplicas out.UnavailableReplicas = in.UnavailableReplicas - out.Conditions = *(*[]extensions.DeploymentCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.DeploymentCondition)(unsafe.Pointer(&in.Conditions)) out.CollisionCount = (*int32)(unsafe.Pointer(in.CollisionCount)) return nil } -// Convert_v1_DeploymentStatus_To_extensions_DeploymentStatus is an autogenerated conversion function. -func Convert_v1_DeploymentStatus_To_extensions_DeploymentStatus(in *v1.DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { - return autoConvert_v1_DeploymentStatus_To_extensions_DeploymentStatus(in, out, s) +// Convert_v1_DeploymentStatus_To_apps_DeploymentStatus is an autogenerated conversion function. +func Convert_v1_DeploymentStatus_To_apps_DeploymentStatus(in *v1.DeploymentStatus, out *apps.DeploymentStatus, s conversion.Scope) error { + return autoConvert_v1_DeploymentStatus_To_apps_DeploymentStatus(in, out, s) } -func autoConvert_extensions_DeploymentStatus_To_v1_DeploymentStatus(in *extensions.DeploymentStatus, out *v1.DeploymentStatus, s conversion.Scope) error { +func autoConvert_apps_DeploymentStatus_To_v1_DeploymentStatus(in *apps.DeploymentStatus, out *v1.DeploymentStatus, s conversion.Scope) error { out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas @@ -859,17 +858,17 @@ func autoConvert_extensions_DeploymentStatus_To_v1_DeploymentStatus(in *extensio return nil } -// Convert_extensions_DeploymentStatus_To_v1_DeploymentStatus is an autogenerated conversion function. -func Convert_extensions_DeploymentStatus_To_v1_DeploymentStatus(in *extensions.DeploymentStatus, out *v1.DeploymentStatus, s conversion.Scope) error { - return autoConvert_extensions_DeploymentStatus_To_v1_DeploymentStatus(in, out, s) +// Convert_apps_DeploymentStatus_To_v1_DeploymentStatus is an autogenerated conversion function. +func Convert_apps_DeploymentStatus_To_v1_DeploymentStatus(in *apps.DeploymentStatus, out *v1.DeploymentStatus, s conversion.Scope) error { + return autoConvert_apps_DeploymentStatus_To_v1_DeploymentStatus(in, out, s) } -func autoConvert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *v1.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { - out.Type = extensions.DeploymentStrategyType(in.Type) +func autoConvert_v1_DeploymentStrategy_To_apps_DeploymentStrategy(in *v1.DeploymentStrategy, out *apps.DeploymentStrategy, s conversion.Scope) error { + out.Type = apps.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(extensions.RollingUpdateDeployment) - if err := Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(*in, *out, s); err != nil { + *out = new(apps.RollingUpdateDeployment) + if err := Convert_v1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(*in, *out, s); err != nil { return err } } else { @@ -878,12 +877,12 @@ func autoConvert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *v1.D return nil } -func autoConvert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *v1.DeploymentStrategy, s conversion.Scope) error { +func autoConvert_apps_DeploymentStrategy_To_v1_DeploymentStrategy(in *apps.DeploymentStrategy, out *v1.DeploymentStrategy, s conversion.Scope) error { out.Type = v1.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate *out = new(v1.RollingUpdateDeployment) - if err := Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(*in, *out, s); err != nil { + if err := Convert_apps_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(*in, *out, s); err != nil { return err } } else { @@ -892,40 +891,40 @@ func autoConvert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(in *exte return nil } -func autoConvert_v1_ReplicaSet_To_extensions_ReplicaSet(in *v1.ReplicaSet, out *extensions.ReplicaSet, s conversion.Scope) error { +func autoConvert_v1_ReplicaSet_To_apps_ReplicaSet(in *v1.ReplicaSet, out *apps.ReplicaSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1_ReplicaSetSpec_To_apps_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1_ReplicaSetStatus_To_apps_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_v1_ReplicaSet_To_extensions_ReplicaSet is an autogenerated conversion function. -func Convert_v1_ReplicaSet_To_extensions_ReplicaSet(in *v1.ReplicaSet, out *extensions.ReplicaSet, s conversion.Scope) error { - return autoConvert_v1_ReplicaSet_To_extensions_ReplicaSet(in, out, s) +// Convert_v1_ReplicaSet_To_apps_ReplicaSet is an autogenerated conversion function. +func Convert_v1_ReplicaSet_To_apps_ReplicaSet(in *v1.ReplicaSet, out *apps.ReplicaSet, s conversion.Scope) error { + return autoConvert_v1_ReplicaSet_To_apps_ReplicaSet(in, out, s) } -func autoConvert_extensions_ReplicaSet_To_v1_ReplicaSet(in *extensions.ReplicaSet, out *v1.ReplicaSet, s conversion.Scope) error { +func autoConvert_apps_ReplicaSet_To_v1_ReplicaSet(in *apps.ReplicaSet, out *v1.ReplicaSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_ReplicaSetSpec_To_v1_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_ReplicaSetStatus_To_v1_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_ReplicaSetStatus_To_v1_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_extensions_ReplicaSet_To_v1_ReplicaSet is an autogenerated conversion function. -func Convert_extensions_ReplicaSet_To_v1_ReplicaSet(in *extensions.ReplicaSet, out *v1.ReplicaSet, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSet_To_v1_ReplicaSet(in, out, s) +// Convert_apps_ReplicaSet_To_v1_ReplicaSet is an autogenerated conversion function. +func Convert_apps_ReplicaSet_To_v1_ReplicaSet(in *apps.ReplicaSet, out *v1.ReplicaSet, s conversion.Scope) error { + return autoConvert_apps_ReplicaSet_To_v1_ReplicaSet(in, out, s) } -func autoConvert_v1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in *v1.ReplicaSetCondition, out *extensions.ReplicaSetCondition, s conversion.Scope) error { - out.Type = extensions.ReplicaSetConditionType(in.Type) +func autoConvert_v1_ReplicaSetCondition_To_apps_ReplicaSetCondition(in *v1.ReplicaSetCondition, out *apps.ReplicaSetCondition, s conversion.Scope) error { + out.Type = apps.ReplicaSetConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime out.Reason = in.Reason @@ -933,12 +932,12 @@ func autoConvert_v1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in *v1 return nil } -// Convert_v1_ReplicaSetCondition_To_extensions_ReplicaSetCondition is an autogenerated conversion function. -func Convert_v1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in *v1.ReplicaSetCondition, out *extensions.ReplicaSetCondition, s conversion.Scope) error { - return autoConvert_v1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in, out, s) +// Convert_v1_ReplicaSetCondition_To_apps_ReplicaSetCondition is an autogenerated conversion function. +func Convert_v1_ReplicaSetCondition_To_apps_ReplicaSetCondition(in *v1.ReplicaSetCondition, out *apps.ReplicaSetCondition, s conversion.Scope) error { + return autoConvert_v1_ReplicaSetCondition_To_apps_ReplicaSetCondition(in, out, s) } -func autoConvert_extensions_ReplicaSetCondition_To_v1_ReplicaSetCondition(in *extensions.ReplicaSetCondition, out *v1.ReplicaSetCondition, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetCondition_To_v1_ReplicaSetCondition(in *apps.ReplicaSetCondition, out *v1.ReplicaSetCondition, s conversion.Scope) error { out.Type = v1.ReplicaSetConditionType(in.Type) out.Status = corev1.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime @@ -947,18 +946,18 @@ func autoConvert_extensions_ReplicaSetCondition_To_v1_ReplicaSetCondition(in *ex return nil } -// Convert_extensions_ReplicaSetCondition_To_v1_ReplicaSetCondition is an autogenerated conversion function. -func Convert_extensions_ReplicaSetCondition_To_v1_ReplicaSetCondition(in *extensions.ReplicaSetCondition, out *v1.ReplicaSetCondition, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetCondition_To_v1_ReplicaSetCondition(in, out, s) +// Convert_apps_ReplicaSetCondition_To_v1_ReplicaSetCondition is an autogenerated conversion function. +func Convert_apps_ReplicaSetCondition_To_v1_ReplicaSetCondition(in *apps.ReplicaSetCondition, out *v1.ReplicaSetCondition, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetCondition_To_v1_ReplicaSetCondition(in, out, s) } -func autoConvert_v1_ReplicaSetList_To_extensions_ReplicaSetList(in *v1.ReplicaSetList, out *extensions.ReplicaSetList, s conversion.Scope) error { +func autoConvert_v1_ReplicaSetList_To_apps_ReplicaSetList(in *v1.ReplicaSetList, out *apps.ReplicaSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.ReplicaSet, len(*in)) + *out = make([]apps.ReplicaSet, len(*in)) for i := range *in { - if err := Convert_v1_ReplicaSet_To_extensions_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1_ReplicaSet_To_apps_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -968,18 +967,18 @@ func autoConvert_v1_ReplicaSetList_To_extensions_ReplicaSetList(in *v1.ReplicaSe return nil } -// Convert_v1_ReplicaSetList_To_extensions_ReplicaSetList is an autogenerated conversion function. -func Convert_v1_ReplicaSetList_To_extensions_ReplicaSetList(in *v1.ReplicaSetList, out *extensions.ReplicaSetList, s conversion.Scope) error { - return autoConvert_v1_ReplicaSetList_To_extensions_ReplicaSetList(in, out, s) +// Convert_v1_ReplicaSetList_To_apps_ReplicaSetList is an autogenerated conversion function. +func Convert_v1_ReplicaSetList_To_apps_ReplicaSetList(in *v1.ReplicaSetList, out *apps.ReplicaSetList, s conversion.Scope) error { + return autoConvert_v1_ReplicaSetList_To_apps_ReplicaSetList(in, out, s) } -func autoConvert_extensions_ReplicaSetList_To_v1_ReplicaSetList(in *extensions.ReplicaSetList, out *v1.ReplicaSetList, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetList_To_v1_ReplicaSetList(in *apps.ReplicaSetList, out *v1.ReplicaSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1.ReplicaSet, len(*in)) for i := range *in { - if err := Convert_extensions_ReplicaSet_To_v1_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_ReplicaSet_To_v1_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -989,12 +988,12 @@ func autoConvert_extensions_ReplicaSetList_To_v1_ReplicaSetList(in *extensions.R return nil } -// Convert_extensions_ReplicaSetList_To_v1_ReplicaSetList is an autogenerated conversion function. -func Convert_extensions_ReplicaSetList_To_v1_ReplicaSetList(in *extensions.ReplicaSetList, out *v1.ReplicaSetList, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetList_To_v1_ReplicaSetList(in, out, s) +// Convert_apps_ReplicaSetList_To_v1_ReplicaSetList is an autogenerated conversion function. +func Convert_apps_ReplicaSetList_To_v1_ReplicaSetList(in *apps.ReplicaSetList, out *v1.ReplicaSetList, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetList_To_v1_ReplicaSetList(in, out, s) } -func autoConvert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *v1.ReplicaSetSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error { +func autoConvert_v1_ReplicaSetSpec_To_apps_ReplicaSetSpec(in *v1.ReplicaSetSpec, out *apps.ReplicaSetSpec, s conversion.Scope) error { if err := metav1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -1006,7 +1005,7 @@ func autoConvert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *v1.ReplicaSe return nil } -func autoConvert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *extensions.ReplicaSetSpec, out *v1.ReplicaSetSpec, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *apps.ReplicaSetSpec, out *v1.ReplicaSetSpec, s conversion.Scope) error { if err := metav1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -1018,22 +1017,22 @@ func autoConvert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *extensions.R return nil } -func autoConvert_v1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in *v1.ReplicaSetStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error { +func autoConvert_v1_ReplicaSetStatus_To_apps_ReplicaSetStatus(in *v1.ReplicaSetStatus, out *apps.ReplicaSetStatus, s conversion.Scope) error { out.Replicas = in.Replicas out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ReadyReplicas = in.ReadyReplicas out.AvailableReplicas = in.AvailableReplicas out.ObservedGeneration = in.ObservedGeneration - out.Conditions = *(*[]extensions.ReplicaSetCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.ReplicaSetCondition)(unsafe.Pointer(&in.Conditions)) return nil } -// Convert_v1_ReplicaSetStatus_To_extensions_ReplicaSetStatus is an autogenerated conversion function. -func Convert_v1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in *v1.ReplicaSetStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error { - return autoConvert_v1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in, out, s) +// Convert_v1_ReplicaSetStatus_To_apps_ReplicaSetStatus is an autogenerated conversion function. +func Convert_v1_ReplicaSetStatus_To_apps_ReplicaSetStatus(in *v1.ReplicaSetStatus, out *apps.ReplicaSetStatus, s conversion.Scope) error { + return autoConvert_v1_ReplicaSetStatus_To_apps_ReplicaSetStatus(in, out, s) } -func autoConvert_extensions_ReplicaSetStatus_To_v1_ReplicaSetStatus(in *extensions.ReplicaSetStatus, out *v1.ReplicaSetStatus, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetStatus_To_v1_ReplicaSetStatus(in *apps.ReplicaSetStatus, out *v1.ReplicaSetStatus, s conversion.Scope) error { out.Replicas = in.Replicas out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ReadyReplicas = in.ReadyReplicas @@ -1043,28 +1042,28 @@ func autoConvert_extensions_ReplicaSetStatus_To_v1_ReplicaSetStatus(in *extensio return nil } -// Convert_extensions_ReplicaSetStatus_To_v1_ReplicaSetStatus is an autogenerated conversion function. -func Convert_extensions_ReplicaSetStatus_To_v1_ReplicaSetStatus(in *extensions.ReplicaSetStatus, out *v1.ReplicaSetStatus, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetStatus_To_v1_ReplicaSetStatus(in, out, s) +// Convert_apps_ReplicaSetStatus_To_v1_ReplicaSetStatus is an autogenerated conversion function. +func Convert_apps_ReplicaSetStatus_To_v1_ReplicaSetStatus(in *apps.ReplicaSetStatus, out *v1.ReplicaSetStatus, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetStatus_To_v1_ReplicaSetStatus(in, out, s) } -func autoConvert_v1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in *v1.RollingUpdateDaemonSet, out *extensions.RollingUpdateDaemonSet, s conversion.Scope) error { +func autoConvert_v1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(in *v1.RollingUpdateDaemonSet, out *apps.RollingUpdateDaemonSet, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *v1.RollingUpdateDaemonSet, s conversion.Scope) error { +func autoConvert_apps_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in *apps.RollingUpdateDaemonSet, out *v1.RollingUpdateDaemonSet, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *v1.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { +func autoConvert_v1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in *v1.RollingUpdateDeployment, out *apps.RollingUpdateDeployment, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) // WARNING: in.MaxSurge requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *v1.RollingUpdateDeployment, s conversion.Scope) error { +func autoConvert_apps_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in *apps.RollingUpdateDeployment, out *v1.RollingUpdateDeployment, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) // WARNING: in.MaxSurge requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil diff --git a/pkg/apis/apps/v1beta1/BUILD b/pkg/apis/apps/v1beta1/BUILD index a4e8399d981d0..a4110a88eca4f 100644 --- a/pkg/apis/apps/v1beta1/BUILD +++ b/pkg/apis/apps/v1beta1/BUILD @@ -22,7 +22,6 @@ go_library( "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/v1:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/api/apps/v1beta1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/pkg/apis/apps/v1beta1/conversion.go b/pkg/apis/apps/v1beta1/conversion.go index 680da870a9444..15804ad9bbf60 100644 --- a/pkg/apis/apps/v1beta1/conversion.go +++ b/pkg/apis/apps/v1beta1/conversion.go @@ -30,7 +30,6 @@ import ( "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" - "k8s.io/kubernetes/pkg/apis/extensions" ) func addConversionFuncs(scheme *runtime.Scheme) error { @@ -48,12 +47,12 @@ func addConversionFuncs(scheme *runtime.Scheme) error { // ones, see https://github.com/kubernetes/kubernetes/issues/39865 Convert_v1beta1_ScaleStatus_To_autoscaling_ScaleStatus, Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus, - Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec, - Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec, - Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy, - Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy, - Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment, - Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment, + Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec, + Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec, + Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy, + Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy, + Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment, + Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment, ) if err != nil { return err @@ -213,7 +212,7 @@ func Convert_v1beta1_ScaleStatus_To_autoscaling_ScaleStatus(in *appsv1beta1.Scal return nil } -func Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1beta1.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { +func Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(in *appsv1beta1.DeploymentSpec, out *apps.DeploymentSpec, s conversion.Scope) error { if in.Replicas != nil { out.Replicas = *in.Replicas } @@ -221,14 +220,14 @@ func Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1beta1 if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.RevisionHistoryLimit = in.RevisionHistoryLimit out.MinReadySeconds = in.MinReadySeconds out.Paused = in.Paused if in.RollbackTo != nil { - out.RollbackTo = new(extensions.RollbackConfig) + out.RollbackTo = new(apps.RollbackConfig) out.RollbackTo.Revision = in.RollbackTo.Revision } else { out.RollbackTo = nil @@ -240,13 +239,13 @@ func Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1beta1 return nil } -func Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.DeploymentSpec, out *appsv1beta1.DeploymentSpec, s conversion.Scope) error { +func Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(in *apps.DeploymentSpec, out *appsv1beta1.DeploymentSpec, s conversion.Scope) error { out.Replicas = &in.Replicas out.Selector = in.Selector if err := k8s_api_v1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } if in.RevisionHistoryLimit != nil { @@ -268,11 +267,11 @@ func Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions. return nil } -func Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *appsv1beta1.DeploymentStrategy, s conversion.Scope) error { +func Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *apps.DeploymentStrategy, out *appsv1beta1.DeploymentStrategy, s conversion.Scope) error { out.Type = appsv1beta1.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { out.RollingUpdate = new(appsv1beta1.RollingUpdateDeployment) - if err := Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + if err := Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -281,11 +280,11 @@ func Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *ext return nil } -func Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *appsv1beta1.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { - out.Type = extensions.DeploymentStrategyType(in.Type) +func Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(in *appsv1beta1.DeploymentStrategy, out *apps.DeploymentStrategy, s conversion.Scope) error { + out.Type = apps.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { - out.RollingUpdate = new(extensions.RollingUpdateDeployment) - if err := Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + out.RollingUpdate = new(apps.RollingUpdateDeployment) + if err := Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -294,7 +293,7 @@ func Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *app return nil } -func Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *appsv1beta1.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { +func Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in *appsv1beta1.RollingUpdateDeployment, out *apps.RollingUpdateDeployment, s conversion.Scope) error { if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { return err } @@ -304,7 +303,7 @@ func Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployme return nil } -func Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *appsv1beta1.RollingUpdateDeployment, s conversion.Scope) error { +func Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *apps.RollingUpdateDeployment, out *appsv1beta1.RollingUpdateDeployment, s conversion.Scope) error { if out.MaxUnavailable == nil { out.MaxUnavailable = &intstr.IntOrString{} } diff --git a/pkg/apis/apps/v1beta1/doc.go b/pkg/apis/apps/v1beta1/doc.go index d4672d4f3fde3..372a18ae8d4cf 100644 --- a/pkg/apis/apps/v1beta1/doc.go +++ b/pkg/apis/apps/v1beta1/doc.go @@ -16,7 +16,6 @@ limitations under the License. // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/apps // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/autoscaling -// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/extensions // +k8s:conversion-gen-external-types=k8s.io/api/apps/v1beta1 // +k8s:defaulter-gen=TypeMeta // +k8s:defaulter-gen-input=../../../../vendor/k8s.io/api/apps/v1beta1 diff --git a/pkg/apis/apps/v1beta1/zz_generated.conversion.go b/pkg/apis/apps/v1beta1/zz_generated.conversion.go index 3268019690a22..728db5da9235c 100644 --- a/pkg/apis/apps/v1beta1/zz_generated.conversion.go +++ b/pkg/apis/apps/v1beta1/zz_generated.conversion.go @@ -32,7 +32,6 @@ import ( autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" core "k8s.io/kubernetes/pkg/apis/core" corev1 "k8s.io/kubernetes/pkg/apis/core/v1" - extensions "k8s.io/kubernetes/pkg/apis/extensions" ) func init() { @@ -62,93 +61,93 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.Deployment)(nil), (*extensions.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_Deployment_To_extensions_Deployment(a.(*v1beta1.Deployment), b.(*extensions.Deployment), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.Deployment)(nil), (*apps.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Deployment_To_apps_Deployment(a.(*v1beta1.Deployment), b.(*apps.Deployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.Deployment)(nil), (*v1beta1.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_Deployment_To_v1beta1_Deployment(a.(*extensions.Deployment), b.(*v1beta1.Deployment), scope) + if err := s.AddGeneratedConversionFunc((*apps.Deployment)(nil), (*v1beta1.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_Deployment_To_v1beta1_Deployment(a.(*apps.Deployment), b.(*v1beta1.Deployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentCondition)(nil), (*extensions.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(a.(*v1beta1.DeploymentCondition), b.(*extensions.DeploymentCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentCondition)(nil), (*apps.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition(a.(*v1beta1.DeploymentCondition), b.(*apps.DeploymentCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentCondition)(nil), (*v1beta1.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(a.(*extensions.DeploymentCondition), b.(*v1beta1.DeploymentCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentCondition)(nil), (*v1beta1.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition(a.(*apps.DeploymentCondition), b.(*v1beta1.DeploymentCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentList)(nil), (*extensions.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentList_To_extensions_DeploymentList(a.(*v1beta1.DeploymentList), b.(*extensions.DeploymentList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentList)(nil), (*apps.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentList_To_apps_DeploymentList(a.(*v1beta1.DeploymentList), b.(*apps.DeploymentList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentList)(nil), (*v1beta1.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentList_To_v1beta1_DeploymentList(a.(*extensions.DeploymentList), b.(*v1beta1.DeploymentList), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentList)(nil), (*v1beta1.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentList_To_v1beta1_DeploymentList(a.(*apps.DeploymentList), b.(*v1beta1.DeploymentList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentRollback)(nil), (*extensions.DeploymentRollback)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback(a.(*v1beta1.DeploymentRollback), b.(*extensions.DeploymentRollback), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentRollback)(nil), (*apps.DeploymentRollback)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback(a.(*v1beta1.DeploymentRollback), b.(*apps.DeploymentRollback), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentRollback)(nil), (*v1beta1.DeploymentRollback)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback(a.(*extensions.DeploymentRollback), b.(*v1beta1.DeploymentRollback), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentRollback)(nil), (*v1beta1.DeploymentRollback)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback(a.(*apps.DeploymentRollback), b.(*v1beta1.DeploymentRollback), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentSpec)(nil), (*extensions.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(a.(*v1beta1.DeploymentSpec), b.(*extensions.DeploymentSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentSpec)(nil), (*apps.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(a.(*v1beta1.DeploymentSpec), b.(*apps.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentSpec)(nil), (*v1beta1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(a.(*extensions.DeploymentSpec), b.(*v1beta1.DeploymentSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentSpec)(nil), (*v1beta1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(a.(*apps.DeploymentSpec), b.(*v1beta1.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentStatus)(nil), (*extensions.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(a.(*v1beta1.DeploymentStatus), b.(*extensions.DeploymentStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentStatus)(nil), (*apps.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(a.(*v1beta1.DeploymentStatus), b.(*apps.DeploymentStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentStatus)(nil), (*v1beta1.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(a.(*extensions.DeploymentStatus), b.(*v1beta1.DeploymentStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentStatus)(nil), (*v1beta1.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(a.(*apps.DeploymentStatus), b.(*v1beta1.DeploymentStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentStrategy)(nil), (*extensions.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(a.(*v1beta1.DeploymentStrategy), b.(*extensions.DeploymentStrategy), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentStrategy)(nil), (*apps.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(a.(*v1beta1.DeploymentStrategy), b.(*apps.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentStrategy)(nil), (*v1beta1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(a.(*extensions.DeploymentStrategy), b.(*v1beta1.DeploymentStrategy), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentStrategy)(nil), (*v1beta1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(a.(*apps.DeploymentStrategy), b.(*v1beta1.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.RollbackConfig)(nil), (*extensions.RollbackConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(a.(*v1beta1.RollbackConfig), b.(*extensions.RollbackConfig), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.RollbackConfig)(nil), (*apps.RollbackConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollbackConfig_To_apps_RollbackConfig(a.(*v1beta1.RollbackConfig), b.(*apps.RollbackConfig), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollbackConfig)(nil), (*v1beta1.RollbackConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(a.(*extensions.RollbackConfig), b.(*v1beta1.RollbackConfig), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollbackConfig)(nil), (*v1beta1.RollbackConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollbackConfig_To_v1beta1_RollbackConfig(a.(*apps.RollbackConfig), b.(*v1beta1.RollbackConfig), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.RollingUpdateDeployment)(nil), (*extensions.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(a.(*v1beta1.RollingUpdateDeployment), b.(*extensions.RollingUpdateDeployment), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.RollingUpdateDeployment)(nil), (*apps.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(a.(*v1beta1.RollingUpdateDeployment), b.(*apps.RollingUpdateDeployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollingUpdateDeployment)(nil), (*v1beta1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(a.(*extensions.RollingUpdateDeployment), b.(*v1beta1.RollingUpdateDeployment), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollingUpdateDeployment)(nil), (*v1beta1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(a.(*apps.RollingUpdateDeployment), b.(*v1beta1.RollingUpdateDeployment), scope) }); err != nil { return err } @@ -252,48 +251,48 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*apps.StatefulSetSpec)(nil), (*v1beta1.StatefulSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec(a.(*apps.StatefulSetSpec), b.(*v1beta1.StatefulSetSpec), scope) + if err := s.AddConversionFunc((*apps.DeploymentSpec)(nil), (*v1beta1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(a.(*apps.DeploymentSpec), b.(*v1beta1.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*apps.StatefulSetUpdateStrategy)(nil), (*v1beta1.StatefulSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(a.(*apps.StatefulSetUpdateStrategy), b.(*v1beta1.StatefulSetUpdateStrategy), scope) + if err := s.AddConversionFunc((*apps.DeploymentStrategy)(nil), (*v1beta1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(a.(*apps.DeploymentStrategy), b.(*v1beta1.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*autoscaling.ScaleStatus)(nil), (*v1beta1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus(a.(*autoscaling.ScaleStatus), b.(*v1beta1.ScaleStatus), scope) + if err := s.AddConversionFunc((*apps.RollingUpdateDeployment)(nil), (*v1beta1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(a.(*apps.RollingUpdateDeployment), b.(*v1beta1.RollingUpdateDeployment), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DeploymentSpec)(nil), (*v1beta1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(a.(*extensions.DeploymentSpec), b.(*v1beta1.DeploymentSpec), scope) + if err := s.AddConversionFunc((*apps.StatefulSetSpec)(nil), (*v1beta1.StatefulSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec(a.(*apps.StatefulSetSpec), b.(*v1beta1.StatefulSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DeploymentStrategy)(nil), (*v1beta1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(a.(*extensions.DeploymentStrategy), b.(*v1beta1.DeploymentStrategy), scope) + if err := s.AddConversionFunc((*apps.StatefulSetUpdateStrategy)(nil), (*v1beta1.StatefulSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(a.(*apps.StatefulSetUpdateStrategy), b.(*v1beta1.StatefulSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.RollingUpdateDeployment)(nil), (*v1beta1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(a.(*extensions.RollingUpdateDeployment), b.(*v1beta1.RollingUpdateDeployment), scope) + if err := s.AddConversionFunc((*autoscaling.ScaleStatus)(nil), (*v1beta1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus(a.(*autoscaling.ScaleStatus), b.(*v1beta1.ScaleStatus), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.DeploymentSpec)(nil), (*extensions.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(a.(*v1beta1.DeploymentSpec), b.(*extensions.DeploymentSpec), scope) + if err := s.AddConversionFunc((*v1beta1.DeploymentSpec)(nil), (*apps.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(a.(*v1beta1.DeploymentSpec), b.(*apps.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.DeploymentStrategy)(nil), (*extensions.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(a.(*v1beta1.DeploymentStrategy), b.(*extensions.DeploymentStrategy), scope) + if err := s.AddConversionFunc((*v1beta1.DeploymentStrategy)(nil), (*apps.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(a.(*v1beta1.DeploymentStrategy), b.(*apps.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.RollingUpdateDeployment)(nil), (*extensions.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(a.(*v1beta1.RollingUpdateDeployment), b.(*extensions.RollingUpdateDeployment), scope) + if err := s.AddConversionFunc((*v1beta1.RollingUpdateDeployment)(nil), (*apps.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(a.(*v1beta1.RollingUpdateDeployment), b.(*apps.RollingUpdateDeployment), scope) }); err != nil { return err } @@ -385,40 +384,40 @@ func Convert_apps_ControllerRevisionList_To_v1beta1_ControllerRevisionList(in *a return autoConvert_apps_ControllerRevisionList_To_v1beta1_ControllerRevisionList(in, out, s) } -func autoConvert_v1beta1_Deployment_To_extensions_Deployment(in *v1beta1.Deployment, out *extensions.Deployment, s conversion.Scope) error { +func autoConvert_v1beta1_Deployment_To_apps_Deployment(in *v1beta1.Deployment, out *apps.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_v1beta1_Deployment_To_extensions_Deployment is an autogenerated conversion function. -func Convert_v1beta1_Deployment_To_extensions_Deployment(in *v1beta1.Deployment, out *extensions.Deployment, s conversion.Scope) error { - return autoConvert_v1beta1_Deployment_To_extensions_Deployment(in, out, s) +// Convert_v1beta1_Deployment_To_apps_Deployment is an autogenerated conversion function. +func Convert_v1beta1_Deployment_To_apps_Deployment(in *v1beta1.Deployment, out *apps.Deployment, s conversion.Scope) error { + return autoConvert_v1beta1_Deployment_To_apps_Deployment(in, out, s) } -func autoConvert_extensions_Deployment_To_v1beta1_Deployment(in *extensions.Deployment, out *v1beta1.Deployment, s conversion.Scope) error { +func autoConvert_apps_Deployment_To_v1beta1_Deployment(in *apps.Deployment, out *v1beta1.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_extensions_Deployment_To_v1beta1_Deployment is an autogenerated conversion function. -func Convert_extensions_Deployment_To_v1beta1_Deployment(in *extensions.Deployment, out *v1beta1.Deployment, s conversion.Scope) error { - return autoConvert_extensions_Deployment_To_v1beta1_Deployment(in, out, s) +// Convert_apps_Deployment_To_v1beta1_Deployment is an autogenerated conversion function. +func Convert_apps_Deployment_To_v1beta1_Deployment(in *apps.Deployment, out *v1beta1.Deployment, s conversion.Scope) error { + return autoConvert_apps_Deployment_To_v1beta1_Deployment(in, out, s) } -func autoConvert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(in *v1beta1.DeploymentCondition, out *extensions.DeploymentCondition, s conversion.Scope) error { - out.Type = extensions.DeploymentConditionType(in.Type) +func autoConvert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition(in *v1beta1.DeploymentCondition, out *apps.DeploymentCondition, s conversion.Scope) error { + out.Type = apps.DeploymentConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastUpdateTime = in.LastUpdateTime out.LastTransitionTime = in.LastTransitionTime @@ -427,12 +426,12 @@ func autoConvert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(i return nil } -// Convert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition is an autogenerated conversion function. -func Convert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(in *v1beta1.DeploymentCondition, out *extensions.DeploymentCondition, s conversion.Scope) error { - return autoConvert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(in, out, s) +// Convert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition is an autogenerated conversion function. +func Convert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition(in *v1beta1.DeploymentCondition, out *apps.DeploymentCondition, s conversion.Scope) error { + return autoConvert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition(in, out, s) } -func autoConvert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(in *extensions.DeploymentCondition, out *v1beta1.DeploymentCondition, s conversion.Scope) error { +func autoConvert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition(in *apps.DeploymentCondition, out *v1beta1.DeploymentCondition, s conversion.Scope) error { out.Type = v1beta1.DeploymentConditionType(in.Type) out.Status = v1.ConditionStatus(in.Status) out.LastUpdateTime = in.LastUpdateTime @@ -442,18 +441,18 @@ func autoConvert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(i return nil } -// Convert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition is an autogenerated conversion function. -func Convert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(in *extensions.DeploymentCondition, out *v1beta1.DeploymentCondition, s conversion.Scope) error { - return autoConvert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(in, out, s) +// Convert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition is an autogenerated conversion function. +func Convert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition(in *apps.DeploymentCondition, out *v1beta1.DeploymentCondition, s conversion.Scope) error { + return autoConvert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition(in, out, s) } -func autoConvert_v1beta1_DeploymentList_To_extensions_DeploymentList(in *v1beta1.DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { +func autoConvert_v1beta1_DeploymentList_To_apps_DeploymentList(in *v1beta1.DeploymentList, out *apps.DeploymentList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.Deployment, len(*in)) + *out = make([]apps.Deployment, len(*in)) for i := range *in { - if err := Convert_v1beta1_Deployment_To_extensions_Deployment(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1beta1_Deployment_To_apps_Deployment(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -463,18 +462,18 @@ func autoConvert_v1beta1_DeploymentList_To_extensions_DeploymentList(in *v1beta1 return nil } -// Convert_v1beta1_DeploymentList_To_extensions_DeploymentList is an autogenerated conversion function. -func Convert_v1beta1_DeploymentList_To_extensions_DeploymentList(in *v1beta1.DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { - return autoConvert_v1beta1_DeploymentList_To_extensions_DeploymentList(in, out, s) +// Convert_v1beta1_DeploymentList_To_apps_DeploymentList is an autogenerated conversion function. +func Convert_v1beta1_DeploymentList_To_apps_DeploymentList(in *v1beta1.DeploymentList, out *apps.DeploymentList, s conversion.Scope) error { + return autoConvert_v1beta1_DeploymentList_To_apps_DeploymentList(in, out, s) } -func autoConvert_extensions_DeploymentList_To_v1beta1_DeploymentList(in *extensions.DeploymentList, out *v1beta1.DeploymentList, s conversion.Scope) error { +func autoConvert_apps_DeploymentList_To_v1beta1_DeploymentList(in *apps.DeploymentList, out *v1beta1.DeploymentList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1beta1.Deployment, len(*in)) for i := range *in { - if err := Convert_extensions_Deployment_To_v1beta1_Deployment(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_Deployment_To_v1beta1_Deployment(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -484,40 +483,40 @@ func autoConvert_extensions_DeploymentList_To_v1beta1_DeploymentList(in *extensi return nil } -// Convert_extensions_DeploymentList_To_v1beta1_DeploymentList is an autogenerated conversion function. -func Convert_extensions_DeploymentList_To_v1beta1_DeploymentList(in *extensions.DeploymentList, out *v1beta1.DeploymentList, s conversion.Scope) error { - return autoConvert_extensions_DeploymentList_To_v1beta1_DeploymentList(in, out, s) +// Convert_apps_DeploymentList_To_v1beta1_DeploymentList is an autogenerated conversion function. +func Convert_apps_DeploymentList_To_v1beta1_DeploymentList(in *apps.DeploymentList, out *v1beta1.DeploymentList, s conversion.Scope) error { + return autoConvert_apps_DeploymentList_To_v1beta1_DeploymentList(in, out, s) } -func autoConvert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback(in *v1beta1.DeploymentRollback, out *extensions.DeploymentRollback, s conversion.Scope) error { +func autoConvert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback(in *v1beta1.DeploymentRollback, out *apps.DeploymentRollback, s conversion.Scope) error { out.Name = in.Name out.UpdatedAnnotations = *(*map[string]string)(unsafe.Pointer(&in.UpdatedAnnotations)) - if err := Convert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(&in.RollbackTo, &out.RollbackTo, s); err != nil { + if err := Convert_v1beta1_RollbackConfig_To_apps_RollbackConfig(&in.RollbackTo, &out.RollbackTo, s); err != nil { return err } return nil } -// Convert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback is an autogenerated conversion function. -func Convert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback(in *v1beta1.DeploymentRollback, out *extensions.DeploymentRollback, s conversion.Scope) error { - return autoConvert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback(in, out, s) +// Convert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback is an autogenerated conversion function. +func Convert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback(in *v1beta1.DeploymentRollback, out *apps.DeploymentRollback, s conversion.Scope) error { + return autoConvert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback(in, out, s) } -func autoConvert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback(in *extensions.DeploymentRollback, out *v1beta1.DeploymentRollback, s conversion.Scope) error { +func autoConvert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback(in *apps.DeploymentRollback, out *v1beta1.DeploymentRollback, s conversion.Scope) error { out.Name = in.Name out.UpdatedAnnotations = *(*map[string]string)(unsafe.Pointer(&in.UpdatedAnnotations)) - if err := Convert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(&in.RollbackTo, &out.RollbackTo, s); err != nil { + if err := Convert_apps_RollbackConfig_To_v1beta1_RollbackConfig(&in.RollbackTo, &out.RollbackTo, s); err != nil { return err } return nil } -// Convert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback is an autogenerated conversion function. -func Convert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback(in *extensions.DeploymentRollback, out *v1beta1.DeploymentRollback, s conversion.Scope) error { - return autoConvert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback(in, out, s) +// Convert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback is an autogenerated conversion function. +func Convert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback(in *apps.DeploymentRollback, out *v1beta1.DeploymentRollback, s conversion.Scope) error { + return autoConvert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback(in, out, s) } -func autoConvert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *v1beta1.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { +func autoConvert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(in *v1beta1.DeploymentSpec, out *apps.DeploymentSpec, s conversion.Scope) error { if err := metav1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -525,18 +524,18 @@ func autoConvert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *v1beta1 if err := corev1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) out.Paused = in.Paused - out.RollbackTo = (*extensions.RollbackConfig)(unsafe.Pointer(in.RollbackTo)) + out.RollbackTo = (*apps.RollbackConfig)(unsafe.Pointer(in.RollbackTo)) out.ProgressDeadlineSeconds = (*int32)(unsafe.Pointer(in.ProgressDeadlineSeconds)) return nil } -func autoConvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.DeploymentSpec, out *v1beta1.DeploymentSpec, s conversion.Scope) error { +func autoConvert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(in *apps.DeploymentSpec, out *v1beta1.DeploymentSpec, s conversion.Scope) error { if err := metav1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -544,7 +543,7 @@ func autoConvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensi if err := corev1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -555,24 +554,24 @@ func autoConvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensi return nil } -func autoConvert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in *v1beta1.DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { +func autoConvert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(in *v1beta1.DeploymentStatus, out *apps.DeploymentStatus, s conversion.Scope) error { out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas out.ReadyReplicas = in.ReadyReplicas out.AvailableReplicas = in.AvailableReplicas out.UnavailableReplicas = in.UnavailableReplicas - out.Conditions = *(*[]extensions.DeploymentCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.DeploymentCondition)(unsafe.Pointer(&in.Conditions)) out.CollisionCount = (*int32)(unsafe.Pointer(in.CollisionCount)) return nil } -// Convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus is an autogenerated conversion function. -func Convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in *v1beta1.DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { - return autoConvert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in, out, s) +// Convert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus is an autogenerated conversion function. +func Convert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(in *v1beta1.DeploymentStatus, out *apps.DeploymentStatus, s conversion.Scope) error { + return autoConvert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(in, out, s) } -func autoConvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *extensions.DeploymentStatus, out *v1beta1.DeploymentStatus, s conversion.Scope) error { +func autoConvert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(in *apps.DeploymentStatus, out *v1beta1.DeploymentStatus, s conversion.Scope) error { out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas @@ -584,17 +583,17 @@ func autoConvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *ext return nil } -// Convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus is an autogenerated conversion function. -func Convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *extensions.DeploymentStatus, out *v1beta1.DeploymentStatus, s conversion.Scope) error { - return autoConvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in, out, s) +// Convert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus is an autogenerated conversion function. +func Convert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(in *apps.DeploymentStatus, out *v1beta1.DeploymentStatus, s conversion.Scope) error { + return autoConvert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(in, out, s) } -func autoConvert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *v1beta1.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { - out.Type = extensions.DeploymentStrategyType(in.Type) +func autoConvert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(in *v1beta1.DeploymentStrategy, out *apps.DeploymentStrategy, s conversion.Scope) error { + out.Type = apps.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(extensions.RollingUpdateDeployment) - if err := Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(*in, *out, s); err != nil { + *out = new(apps.RollingUpdateDeployment) + if err := Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(*in, *out, s); err != nil { return err } } else { @@ -603,12 +602,12 @@ func autoConvert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in return nil } -func autoConvert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *v1beta1.DeploymentStrategy, s conversion.Scope) error { +func autoConvert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *apps.DeploymentStrategy, out *v1beta1.DeploymentStrategy, s conversion.Scope) error { out.Type = v1beta1.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate *out = new(v1beta1.RollingUpdateDeployment) - if err := Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(*in, *out, s); err != nil { + if err := Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(*in, *out, s); err != nil { return err } } else { @@ -617,33 +616,33 @@ func autoConvert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in return nil } -func autoConvert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(in *v1beta1.RollbackConfig, out *extensions.RollbackConfig, s conversion.Scope) error { +func autoConvert_v1beta1_RollbackConfig_To_apps_RollbackConfig(in *v1beta1.RollbackConfig, out *apps.RollbackConfig, s conversion.Scope) error { out.Revision = in.Revision return nil } -// Convert_v1beta1_RollbackConfig_To_extensions_RollbackConfig is an autogenerated conversion function. -func Convert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(in *v1beta1.RollbackConfig, out *extensions.RollbackConfig, s conversion.Scope) error { - return autoConvert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(in, out, s) +// Convert_v1beta1_RollbackConfig_To_apps_RollbackConfig is an autogenerated conversion function. +func Convert_v1beta1_RollbackConfig_To_apps_RollbackConfig(in *v1beta1.RollbackConfig, out *apps.RollbackConfig, s conversion.Scope) error { + return autoConvert_v1beta1_RollbackConfig_To_apps_RollbackConfig(in, out, s) } -func autoConvert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(in *extensions.RollbackConfig, out *v1beta1.RollbackConfig, s conversion.Scope) error { +func autoConvert_apps_RollbackConfig_To_v1beta1_RollbackConfig(in *apps.RollbackConfig, out *v1beta1.RollbackConfig, s conversion.Scope) error { out.Revision = in.Revision return nil } -// Convert_extensions_RollbackConfig_To_v1beta1_RollbackConfig is an autogenerated conversion function. -func Convert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(in *extensions.RollbackConfig, out *v1beta1.RollbackConfig, s conversion.Scope) error { - return autoConvert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(in, out, s) +// Convert_apps_RollbackConfig_To_v1beta1_RollbackConfig is an autogenerated conversion function. +func Convert_apps_RollbackConfig_To_v1beta1_RollbackConfig(in *apps.RollbackConfig, out *v1beta1.RollbackConfig, s conversion.Scope) error { + return autoConvert_apps_RollbackConfig_To_v1beta1_RollbackConfig(in, out, s) } -func autoConvert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *v1beta1.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { +func autoConvert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in *v1beta1.RollingUpdateDeployment, out *apps.RollingUpdateDeployment, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) // WARNING: in.MaxSurge requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *v1beta1.RollingUpdateDeployment, s conversion.Scope) error { +func autoConvert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *apps.RollingUpdateDeployment, out *v1beta1.RollingUpdateDeployment, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) // WARNING: in.MaxSurge requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil diff --git a/pkg/apis/apps/v1beta2/BUILD b/pkg/apis/apps/v1beta2/BUILD index 37816e1e3caf7..42a6b8191f478 100644 --- a/pkg/apis/apps/v1beta2/BUILD +++ b/pkg/apis/apps/v1beta2/BUILD @@ -22,7 +22,6 @@ go_library( "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/v1:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/api/apps/v1beta2:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", @@ -61,7 +60,6 @@ go_test( "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/install:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/api/apps/v1beta2:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", diff --git a/pkg/apis/apps/v1beta2/conversion.go b/pkg/apis/apps/v1beta2/conversion.go index 3bfd5279392f8..8d0e753a35cad 100644 --- a/pkg/apis/apps/v1beta2/conversion.go +++ b/pkg/apis/apps/v1beta2/conversion.go @@ -31,7 +31,6 @@ import ( autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" - "k8s.io/kubernetes/pkg/apis/extensions" ) func addConversionFuncs(scheme *runtime.Scheme) error { @@ -44,31 +43,31 @@ func addConversionFuncs(scheme *runtime.Scheme) error { Convert_apps_StatefulSetSpec_To_v1beta2_StatefulSetSpec, Convert_v1beta2_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy, Convert_apps_StatefulSetUpdateStrategy_To_v1beta2_StatefulSetUpdateStrategy, - Convert_extensions_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet, - Convert_v1beta2_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet, + Convert_apps_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet, + Convert_v1beta2_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet, Convert_v1beta2_StatefulSetStatus_To_apps_StatefulSetStatus, Convert_apps_StatefulSetStatus_To_v1beta2_StatefulSetStatus, - Convert_v1beta2_Deployment_To_extensions_Deployment, - Convert_extensions_Deployment_To_v1beta2_Deployment, - Convert_extensions_DaemonSet_To_v1beta2_DaemonSet, - Convert_v1beta2_DaemonSet_To_extensions_DaemonSet, - Convert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec, - Convert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec, - Convert_extensions_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy, - Convert_v1beta2_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy, + Convert_v1beta2_Deployment_To_apps_Deployment, + Convert_apps_Deployment_To_v1beta2_Deployment, + Convert_apps_DaemonSet_To_v1beta2_DaemonSet, + Convert_v1beta2_DaemonSet_To_apps_DaemonSet, + Convert_apps_DaemonSetSpec_To_v1beta2_DaemonSetSpec, + Convert_v1beta2_DaemonSetSpec_To_apps_DaemonSetSpec, + Convert_apps_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy, + Convert_v1beta2_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy, // extensions // TODO: below conversions should be dropped in favor of auto-generated // ones, see https://github.com/kubernetes/kubernetes/issues/39865 Convert_v1beta2_ScaleStatus_To_autoscaling_ScaleStatus, Convert_autoscaling_ScaleStatus_To_v1beta2_ScaleStatus, - Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec, - Convert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec, - Convert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy, - Convert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy, - Convert_v1beta2_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment, - Convert_extensions_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment, - Convert_extensions_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec, - Convert_v1beta2_ReplicaSetSpec_To_extensions_ReplicaSetSpec, + Convert_v1beta2_DeploymentSpec_To_apps_DeploymentSpec, + Convert_apps_DeploymentSpec_To_v1beta2_DeploymentSpec, + Convert_v1beta2_DeploymentStrategy_To_apps_DeploymentStrategy, + Convert_apps_DeploymentStrategy_To_v1beta2_DeploymentStrategy, + Convert_v1beta2_RollingUpdateDeployment_To_apps_RollingUpdateDeployment, + Convert_apps_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment, + Convert_apps_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec, + Convert_v1beta2_ReplicaSetSpec_To_apps_ReplicaSetSpec, ) if err != nil { return err @@ -91,7 +90,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error { return nil } -func Convert_extensions_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *appsv1beta2.RollingUpdateDaemonSet, s conversion.Scope) error { +func Convert_apps_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(in *apps.RollingUpdateDaemonSet, out *appsv1beta2.RollingUpdateDaemonSet, s conversion.Scope) error { if out.MaxUnavailable == nil { out.MaxUnavailable = &intstr.IntOrString{} } @@ -101,7 +100,7 @@ func Convert_extensions_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet return nil } -func Convert_v1beta2_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in *appsv1beta2.RollingUpdateDaemonSet, out *extensions.RollingUpdateDaemonSet, s conversion.Scope) error { +func Convert_v1beta2_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(in *appsv1beta2.RollingUpdateDaemonSet, out *apps.RollingUpdateDaemonSet, s conversion.Scope) error { if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { return err } @@ -294,7 +293,7 @@ func Convert_v1beta2_ScaleStatus_To_autoscaling_ScaleStatus(in *appsv1beta2.Scal return nil } -func Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1beta2.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { +func Convert_v1beta2_DeploymentSpec_To_apps_DeploymentSpec(in *appsv1beta2.DeploymentSpec, out *apps.DeploymentSpec, s conversion.Scope) error { if in.Replicas != nil { out.Replicas = *in.Replicas } @@ -302,7 +301,7 @@ func Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1beta2 if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_v1beta2_DeploymentStrategy_To_apps_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.RevisionHistoryLimit = in.RevisionHistoryLimit @@ -315,13 +314,13 @@ func Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1beta2 return nil } -func Convert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(in *extensions.DeploymentSpec, out *appsv1beta2.DeploymentSpec, s conversion.Scope) error { +func Convert_apps_DeploymentSpec_To_v1beta2_DeploymentSpec(in *apps.DeploymentSpec, out *appsv1beta2.DeploymentSpec, s conversion.Scope) error { out.Replicas = &in.Replicas out.Selector = in.Selector if err := k8s_api_v1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_apps_DeploymentStrategy_To_v1beta2_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } if in.RevisionHistoryLimit != nil { @@ -337,11 +336,11 @@ func Convert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(in *extensions. return nil } -func Convert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy(in *extensions.DeploymentStrategy, out *appsv1beta2.DeploymentStrategy, s conversion.Scope) error { +func Convert_apps_DeploymentStrategy_To_v1beta2_DeploymentStrategy(in *apps.DeploymentStrategy, out *appsv1beta2.DeploymentStrategy, s conversion.Scope) error { out.Type = appsv1beta2.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { out.RollingUpdate = new(appsv1beta2.RollingUpdateDeployment) - if err := Convert_extensions_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + if err := Convert_apps_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -350,11 +349,11 @@ func Convert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy(in *ext return nil } -func Convert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy(in *appsv1beta2.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { - out.Type = extensions.DeploymentStrategyType(in.Type) +func Convert_v1beta2_DeploymentStrategy_To_apps_DeploymentStrategy(in *appsv1beta2.DeploymentStrategy, out *apps.DeploymentStrategy, s conversion.Scope) error { + out.Type = apps.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { - out.RollingUpdate = new(extensions.RollingUpdateDeployment) - if err := Convert_v1beta2_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + out.RollingUpdate = new(apps.RollingUpdateDeployment) + if err := Convert_v1beta2_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -363,7 +362,7 @@ func Convert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy(in *app return nil } -func Convert_v1beta2_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *appsv1beta2.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { +func Convert_v1beta2_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in *appsv1beta2.RollingUpdateDeployment, out *apps.RollingUpdateDeployment, s conversion.Scope) error { if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { return err } @@ -373,7 +372,7 @@ func Convert_v1beta2_RollingUpdateDeployment_To_extensions_RollingUpdateDeployme return nil } -func Convert_extensions_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *appsv1beta2.RollingUpdateDeployment, s conversion.Scope) error { +func Convert_apps_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(in *apps.RollingUpdateDeployment, out *appsv1beta2.RollingUpdateDeployment, s conversion.Scope) error { if out.MaxUnavailable == nil { out.MaxUnavailable = &intstr.IntOrString{} } @@ -389,7 +388,7 @@ func Convert_extensions_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployme return nil } -func Convert_extensions_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(in *extensions.ReplicaSetSpec, out *appsv1beta2.ReplicaSetSpec, s conversion.Scope) error { +func Convert_apps_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(in *apps.ReplicaSetSpec, out *appsv1beta2.ReplicaSetSpec, s conversion.Scope) error { out.Replicas = new(int32) *out.Replicas = int32(in.Replicas) out.MinReadySeconds = in.MinReadySeconds @@ -400,9 +399,9 @@ func Convert_extensions_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(in *extensions. return nil } -func Convert_v1beta2_Deployment_To_extensions_Deployment(in *appsv1beta2.Deployment, out *extensions.Deployment, s conversion.Scope) error { +func Convert_v1beta2_Deployment_To_apps_Deployment(in *appsv1beta2.Deployment, out *apps.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta2_DeploymentSpec_To_apps_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } @@ -412,7 +411,7 @@ func Convert_v1beta2_Deployment_To_extensions_Deployment(in *appsv1beta2.Deploym if revision64, err := strconv.ParseInt(revision, 10, 64); err != nil { return fmt.Errorf("failed to parse annotation[%s]=%s as int64: %v", appsv1beta2.DeprecatedRollbackTo, revision, err) } else { - out.Spec.RollbackTo = new(extensions.RollbackConfig) + out.Spec.RollbackTo = new(apps.RollbackConfig) out.Spec.RollbackTo.Revision = revision64 } out.Annotations = deepCopyStringMap(out.Annotations) @@ -421,13 +420,13 @@ func Convert_v1beta2_Deployment_To_extensions_Deployment(in *appsv1beta2.Deploym out.Spec.RollbackTo = nil } - if err := Convert_v1beta2_DeploymentStatus_To_extensions_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1beta2_DeploymentStatus_To_apps_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func Convert_v1beta2_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *appsv1beta2.ReplicaSetSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error { +func Convert_v1beta2_ReplicaSetSpec_To_apps_ReplicaSetSpec(in *appsv1beta2.ReplicaSetSpec, out *apps.ReplicaSetSpec, s conversion.Scope) error { if in.Replicas != nil { out.Replicas = *in.Replicas } @@ -439,11 +438,11 @@ func Convert_v1beta2_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *appsv1beta2 return nil } -func Convert_extensions_Deployment_To_v1beta2_Deployment(in *extensions.Deployment, out *appsv1beta2.Deployment, s conversion.Scope) error { +func Convert_apps_Deployment_To_v1beta2_Deployment(in *apps.Deployment, out *appsv1beta2.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Annotations = deepCopyStringMap(out.Annotations) // deep copy because we modify annotations below - if err := Convert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DeploymentSpec_To_v1beta2_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } @@ -458,17 +457,17 @@ func Convert_extensions_Deployment_To_v1beta2_Deployment(in *extensions.Deployme delete(out.Annotations, appsv1beta2.DeprecatedRollbackTo) } - if err := Convert_extensions_DeploymentStatus_To_v1beta2_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DeploymentStatus_To_v1beta2_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func Convert_extensions_DaemonSet_To_v1beta2_DaemonSet(in *extensions.DaemonSet, out *appsv1beta2.DaemonSet, s conversion.Scope) error { +func Convert_apps_DaemonSet_To_v1beta2_DaemonSet(in *apps.DaemonSet, out *appsv1beta2.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Annotations = deepCopyStringMap(out.Annotations) out.Annotations[appsv1beta2.DeprecatedTemplateGeneration] = strconv.FormatInt(in.Spec.TemplateGeneration, 10) - if err := Convert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DaemonSetSpec_To_v1beta2_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { @@ -477,12 +476,12 @@ func Convert_extensions_DaemonSet_To_v1beta2_DaemonSet(in *extensions.DaemonSet, return nil } -func Convert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec(in *extensions.DaemonSetSpec, out *appsv1beta2.DaemonSetSpec, s conversion.Scope) error { +func Convert_apps_DaemonSetSpec_To_v1beta2_DaemonSetSpec(in *apps.DaemonSetSpec, out *appsv1beta2.DaemonSetSpec, s conversion.Scope) error { out.Selector = in.Selector if err := k8s_api_v1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_apps_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } out.MinReadySeconds = int32(in.MinReadySeconds) @@ -495,20 +494,20 @@ func Convert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec(in *extensions.Da return nil } -func Convert_extensions_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(in *extensions.DaemonSetUpdateStrategy, out *appsv1beta2.DaemonSetUpdateStrategy, s conversion.Scope) error { +func Convert_apps_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(in *apps.DaemonSetUpdateStrategy, out *appsv1beta2.DaemonSetUpdateStrategy, s conversion.Scope) error { out.Type = appsv1beta2.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { out.RollingUpdate = &appsv1beta2.RollingUpdateDaemonSet{} - if err := Convert_extensions_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil { + if err := Convert_apps_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } return nil } -func Convert_v1beta2_DaemonSet_To_extensions_DaemonSet(in *appsv1beta2.DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error { +func Convert_v1beta2_DaemonSet_To_apps_DaemonSet(in *appsv1beta2.DaemonSet, out *apps.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta2_DaemonSetSpec_To_apps_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } if value, ok := in.Annotations[appsv1beta2.DeprecatedTemplateGeneration]; ok { @@ -526,12 +525,12 @@ func Convert_v1beta2_DaemonSet_To_extensions_DaemonSet(in *appsv1beta2.DaemonSet return nil } -func Convert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec(in *appsv1beta2.DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error { +func Convert_v1beta2_DaemonSetSpec_To_apps_DaemonSetSpec(in *appsv1beta2.DaemonSetSpec, out *apps.DaemonSetSpec, s conversion.Scope) error { out.Selector = in.Selector if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta2_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_v1beta2_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } if in.RevisionHistoryLimit != nil { @@ -544,11 +543,11 @@ func Convert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec(in *appsv1beta2.D return nil } -func Convert_v1beta2_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in *appsv1beta2.DaemonSetUpdateStrategy, out *extensions.DaemonSetUpdateStrategy, s conversion.Scope) error { - out.Type = extensions.DaemonSetUpdateStrategyType(in.Type) +func Convert_v1beta2_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(in *appsv1beta2.DaemonSetUpdateStrategy, out *apps.DaemonSetUpdateStrategy, s conversion.Scope) error { + out.Type = apps.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { - out.RollingUpdate = &extensions.RollingUpdateDaemonSet{} - if err := Convert_v1beta2_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil { + out.RollingUpdate = &apps.RollingUpdateDaemonSet{} + if err := Convert_v1beta2_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } diff --git a/pkg/apis/apps/v1beta2/conversion_test.go b/pkg/apis/apps/v1beta2/conversion_test.go index 0bc76511e049b..f0f185c1f1760 100644 --- a/pkg/apis/apps/v1beta2/conversion_test.go +++ b/pkg/apis/apps/v1beta2/conversion_test.go @@ -26,7 +26,6 @@ import ( "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -155,11 +154,11 @@ func TestV1beta2StatefulSetUpdateStrategyConversion(t *testing.T) { func TestV1beta2RollingUpdateDaemonSetConversion(t *testing.T) { intorstr := intstr.FromInt(1) testcases := map[string]struct { - rollingUpdateDs1 *extensions.RollingUpdateDaemonSet + rollingUpdateDs1 *apps.RollingUpdateDaemonSet rollingUpdateDs2 *v1beta2.RollingUpdateDaemonSet }{ "RollingUpdateDaemonSet Conversion 2": { - rollingUpdateDs1: &extensions.RollingUpdateDaemonSet{MaxUnavailable: intorstr}, + rollingUpdateDs1: &apps.RollingUpdateDaemonSet{MaxUnavailable: intorstr}, rollingUpdateDs2: &v1beta2.RollingUpdateDaemonSet{MaxUnavailable: &intorstr}, }, } @@ -175,7 +174,7 @@ func TestV1beta2RollingUpdateDaemonSetConversion(t *testing.T) { } // v1beta2 -> extensions - internal2 := &extensions.RollingUpdateDaemonSet{} + internal2 := &apps.RollingUpdateDaemonSet{} if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDs2, internal2, nil); err != nil { t.Errorf("%q - %q: unexpected error: %v", k, "from v1beta2 to extensions", err) } @@ -262,15 +261,15 @@ func TestV1beta2StatefulSetStatusConversion(t *testing.T) { func TestV1beta2DeploymentConversion(t *testing.T) { replica := utilpointer.Int32Ptr(2) - rollbackTo := new(extensions.RollbackConfig) + rollbackTo := new(apps.RollbackConfig) rollbackTo.Revision = int64(2) testcases := map[string]struct { - deployment1 *extensions.Deployment + deployment1 *apps.Deployment deployment2 *v1beta2.Deployment }{ "Deployment Conversion 1": { - deployment1: &extensions.Deployment{ - Spec: extensions.DeploymentSpec{ + deployment1: &apps.Deployment{ + Spec: apps.DeploymentSpec{ Replicas: *replica, RollbackTo: rollbackTo, Template: api.PodTemplateSpec{ @@ -295,8 +294,8 @@ func TestV1beta2DeploymentConversion(t *testing.T) { }, }, "Deployment Conversion 2": { - deployment1: &extensions.Deployment{ - Spec: extensions.DeploymentSpec{ + deployment1: &apps.Deployment{ + Spec: apps.DeploymentSpec{ Replicas: *replica, Template: api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -329,7 +328,7 @@ func TestV1beta2DeploymentConversion(t *testing.T) { } // v1beta2 -> extensions - internal2 := &extensions.Deployment{} + internal2 := &apps.Deployment{} if err := legacyscheme.Scheme.Convert(tc.deployment2, internal2, nil); err != nil { t.Errorf("%q - %q: unexpected error: %v", k, "from v1beta2 to extensions", err) } @@ -396,11 +395,11 @@ func TestV1beta2DeploymentSpecConversion(t *testing.T) { progressDeadlineSeconds := utilpointer.Int32Ptr(2) testcases := map[string]struct { - deploymentSpec1 *extensions.DeploymentSpec + deploymentSpec1 *apps.DeploymentSpec deploymentSpec2 *v1beta2.DeploymentSpec }{ "DeploymentSpec Conversion 1": { - deploymentSpec1: &extensions.DeploymentSpec{ + deploymentSpec1: &apps.DeploymentSpec{ Replicas: *replica, Template: api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -418,7 +417,7 @@ func TestV1beta2DeploymentSpecConversion(t *testing.T) { }, }, "DeploymentSpec Conversion 2": { - deploymentSpec1: &extensions.DeploymentSpec{ + deploymentSpec1: &apps.DeploymentSpec{ Replicas: *replica, RevisionHistoryLimit: revisionHistoryLimit, MinReadySeconds: 2, @@ -442,7 +441,7 @@ func TestV1beta2DeploymentSpecConversion(t *testing.T) { }, }, "DeploymentSpec Conversion 3": { - deploymentSpec1: &extensions.DeploymentSpec{ + deploymentSpec1: &apps.DeploymentSpec{ Replicas: *replica, ProgressDeadlineSeconds: progressDeadlineSeconds, Template: api.PodTemplateSpec{ @@ -477,7 +476,7 @@ func TestV1beta2DeploymentSpecConversion(t *testing.T) { // v1beta2 -> extensions for k, tc := range testcases { - internal := &extensions.DeploymentSpec{} + internal := &apps.DeploymentSpec{} if err := legacyscheme.Scheme.Convert(tc.deploymentSpec2, internal, nil); err != nil { t.Errorf("%q - %q: unexpected error: %v", "v1beta2 -> extensions", k, err) } @@ -491,18 +490,18 @@ func TestV1beta2DeploymentSpecConversion(t *testing.T) { func TestV1beta2DeploymentStrategyConversion(t *testing.T) { maxUnavailable := intstr.FromInt(2) maxSurge := intstr.FromInt(2) - extensionsRollingUpdate := extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge} + extensionsRollingUpdate := apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge} v1beta2RollingUpdate := v1beta2.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &maxSurge} testcases := map[string]struct { - deploymentStrategy1 *extensions.DeploymentStrategy + deploymentStrategy1 *apps.DeploymentStrategy deploymentStrategy2 *v1beta2.DeploymentStrategy }{ "DeploymentStrategy Conversion 1": { - deploymentStrategy1: &extensions.DeploymentStrategy{Type: extensions.DeploymentStrategyType("foo")}, + deploymentStrategy1: &apps.DeploymentStrategy{Type: apps.DeploymentStrategyType("foo")}, deploymentStrategy2: &v1beta2.DeploymentStrategy{Type: v1beta2.DeploymentStrategyType("foo")}, }, "DeploymentStrategy Conversion 2": { - deploymentStrategy1: &extensions.DeploymentStrategy{Type: extensions.DeploymentStrategyType("foo"), RollingUpdate: &extensionsRollingUpdate}, + deploymentStrategy1: &apps.DeploymentStrategy{Type: apps.DeploymentStrategyType("foo"), RollingUpdate: &extensionsRollingUpdate}, deploymentStrategy2: &v1beta2.DeploymentStrategy{Type: v1beta2.DeploymentStrategyType("foo"), RollingUpdate: &v1beta2RollingUpdate}, }, } @@ -518,7 +517,7 @@ func TestV1beta2DeploymentStrategyConversion(t *testing.T) { } // v1beta2 -> extensions - internal2 := &extensions.DeploymentStrategy{} + internal2 := &apps.DeploymentStrategy{} if err := legacyscheme.Scheme.Convert(tc.deploymentStrategy2, internal2, nil); err != nil { t.Errorf("%q - %q: unexpected error: %v", k, "v1beta2 -> extensions", err) } @@ -533,23 +532,23 @@ func TestV1beta2RollingUpdateDeploymentConversion(t *testing.T) { maxUnavailable := intstr.FromInt(2) maxSurge := intstr.FromInt(2) testcases := map[string]struct { - rollingUpdateDeployment1 *extensions.RollingUpdateDeployment + rollingUpdateDeployment1 *apps.RollingUpdateDeployment rollingUpdateDeployment2 *v1beta2.RollingUpdateDeployment }{ "RollingUpdateDeployment Conversion 1": { - rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{}, + rollingUpdateDeployment1: &apps.RollingUpdateDeployment{}, rollingUpdateDeployment2: &v1beta2.RollingUpdateDeployment{MaxUnavailable: &nilIntStr, MaxSurge: &nilIntStr}, }, "RollingUpdateDeployment Conversion 2": { - rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable}, + rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable}, rollingUpdateDeployment2: &v1beta2.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &nilIntStr}, }, "RollingUpdateDeployment Conversion 3": { - rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxSurge: maxSurge}, + rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxSurge: maxSurge}, rollingUpdateDeployment2: &v1beta2.RollingUpdateDeployment{MaxSurge: &maxSurge, MaxUnavailable: &nilIntStr}, }, "RollingUpdateDeployment Conversion 4": { - rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge}, + rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge}, rollingUpdateDeployment2: &v1beta2.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &maxSurge}, }, } @@ -565,7 +564,7 @@ func TestV1beta2RollingUpdateDeploymentConversion(t *testing.T) { } // v1beta2 -> extensions - internal2 := &extensions.RollingUpdateDeployment{} + internal2 := &apps.RollingUpdateDeployment{} if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDeployment2, internal2, nil); err != nil { t.Errorf("%q - %q: unexpected error: %v", k, "v1beta2 -> extensions", err) } @@ -585,11 +584,11 @@ func TestV1beta2ReplicaSetSpecConversion(t *testing.T) { selector := &metav1.LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions} testcases := map[string]struct { - replicaset1 *extensions.ReplicaSetSpec + replicaset1 *apps.ReplicaSetSpec replicaset2 *v1beta2.ReplicaSetSpec }{ "ReplicaSetSpec Conversion 1": { - replicaset1: &extensions.ReplicaSetSpec{ + replicaset1: &apps.ReplicaSetSpec{ Replicas: *replicas, MinReadySeconds: 2, Template: api.PodTemplateSpec{ @@ -609,7 +608,7 @@ func TestV1beta2ReplicaSetSpecConversion(t *testing.T) { }, }, "ReplicaSetSpec Conversion 2": { - replicaset1: &extensions.ReplicaSetSpec{ + replicaset1: &apps.ReplicaSetSpec{ Replicas: *replicas, Selector: selector, Template: api.PodTemplateSpec{ @@ -642,7 +641,7 @@ func TestV1beta2ReplicaSetSpecConversion(t *testing.T) { } // v1beta2 -> extensions - internal2 := &extensions.ReplicaSetSpec{} + internal2 := &apps.ReplicaSetSpec{} if err := legacyscheme.Scheme.Convert(tc.replicaset2, internal2, nil); err != nil { t.Errorf("%q - %q: unexpected error: %v", k, "v1beta2 -> extensions", err) } diff --git a/pkg/apis/apps/v1beta2/doc.go b/pkg/apis/apps/v1beta2/doc.go index cad91c57c3cf7..567551b74ab38 100644 --- a/pkg/apis/apps/v1beta2/doc.go +++ b/pkg/apis/apps/v1beta2/doc.go @@ -16,7 +16,6 @@ limitations under the License. // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/apps // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/autoscaling -// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/extensions // +k8s:conversion-gen-external-types=k8s.io/api/apps/v1beta2 // +k8s:defaulter-gen=TypeMeta // +k8s:defaulter-gen-input=../../../../vendor/k8s.io/api/apps/v1beta2 diff --git a/pkg/apis/apps/v1beta2/zz_generated.conversion.go b/pkg/apis/apps/v1beta2/zz_generated.conversion.go index 5fabfdccbdab8..ae5d8692fa80b 100644 --- a/pkg/apis/apps/v1beta2/zz_generated.conversion.go +++ b/pkg/apis/apps/v1beta2/zz_generated.conversion.go @@ -32,7 +32,6 @@ import ( autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" core "k8s.io/kubernetes/pkg/apis/core" corev1 "k8s.io/kubernetes/pkg/apis/core/v1" - extensions "k8s.io/kubernetes/pkg/apis/extensions" ) func init() { @@ -62,193 +61,193 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSet)(nil), (*extensions.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSet_To_extensions_DaemonSet(a.(*v1beta2.DaemonSet), b.(*extensions.DaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSet)(nil), (*apps.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSet_To_apps_DaemonSet(a.(*v1beta2.DaemonSet), b.(*apps.DaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSet)(nil), (*v1beta2.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSet_To_v1beta2_DaemonSet(a.(*extensions.DaemonSet), b.(*v1beta2.DaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSet)(nil), (*v1beta2.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSet_To_v1beta2_DaemonSet(a.(*apps.DaemonSet), b.(*v1beta2.DaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetCondition)(nil), (*extensions.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSetCondition_To_extensions_DaemonSetCondition(a.(*v1beta2.DaemonSetCondition), b.(*extensions.DaemonSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetCondition)(nil), (*apps.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSetCondition_To_apps_DaemonSetCondition(a.(*v1beta2.DaemonSetCondition), b.(*apps.DaemonSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetCondition)(nil), (*v1beta2.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetCondition_To_v1beta2_DaemonSetCondition(a.(*extensions.DaemonSetCondition), b.(*v1beta2.DaemonSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetCondition)(nil), (*v1beta2.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetCondition_To_v1beta2_DaemonSetCondition(a.(*apps.DaemonSetCondition), b.(*v1beta2.DaemonSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetList)(nil), (*extensions.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSetList_To_extensions_DaemonSetList(a.(*v1beta2.DaemonSetList), b.(*extensions.DaemonSetList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetList)(nil), (*apps.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSetList_To_apps_DaemonSetList(a.(*v1beta2.DaemonSetList), b.(*apps.DaemonSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetList)(nil), (*v1beta2.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetList_To_v1beta2_DaemonSetList(a.(*extensions.DaemonSetList), b.(*v1beta2.DaemonSetList), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetList)(nil), (*v1beta2.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetList_To_v1beta2_DaemonSetList(a.(*apps.DaemonSetList), b.(*v1beta2.DaemonSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetSpec)(nil), (*extensions.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec(a.(*v1beta2.DaemonSetSpec), b.(*extensions.DaemonSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetSpec)(nil), (*apps.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSetSpec_To_apps_DaemonSetSpec(a.(*v1beta2.DaemonSetSpec), b.(*apps.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetSpec)(nil), (*v1beta2.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec(a.(*extensions.DaemonSetSpec), b.(*v1beta2.DaemonSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetSpec)(nil), (*v1beta2.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetSpec_To_v1beta2_DaemonSetSpec(a.(*apps.DaemonSetSpec), b.(*v1beta2.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetStatus)(nil), (*extensions.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSetStatus_To_extensions_DaemonSetStatus(a.(*v1beta2.DaemonSetStatus), b.(*extensions.DaemonSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetStatus)(nil), (*apps.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSetStatus_To_apps_DaemonSetStatus(a.(*v1beta2.DaemonSetStatus), b.(*apps.DaemonSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetStatus)(nil), (*v1beta2.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetStatus_To_v1beta2_DaemonSetStatus(a.(*extensions.DaemonSetStatus), b.(*v1beta2.DaemonSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetStatus)(nil), (*v1beta2.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetStatus_To_v1beta2_DaemonSetStatus(a.(*apps.DaemonSetStatus), b.(*v1beta2.DaemonSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetUpdateStrategy)(nil), (*extensions.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(a.(*v1beta2.DaemonSetUpdateStrategy), b.(*extensions.DaemonSetUpdateStrategy), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DaemonSetUpdateStrategy)(nil), (*apps.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(a.(*v1beta2.DaemonSetUpdateStrategy), b.(*apps.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetUpdateStrategy)(nil), (*v1beta2.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(a.(*extensions.DaemonSetUpdateStrategy), b.(*v1beta2.DaemonSetUpdateStrategy), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetUpdateStrategy)(nil), (*v1beta2.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(a.(*apps.DaemonSetUpdateStrategy), b.(*v1beta2.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.Deployment)(nil), (*extensions.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_Deployment_To_extensions_Deployment(a.(*v1beta2.Deployment), b.(*extensions.Deployment), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.Deployment)(nil), (*apps.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_Deployment_To_apps_Deployment(a.(*v1beta2.Deployment), b.(*apps.Deployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.Deployment)(nil), (*v1beta2.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_Deployment_To_v1beta2_Deployment(a.(*extensions.Deployment), b.(*v1beta2.Deployment), scope) + if err := s.AddGeneratedConversionFunc((*apps.Deployment)(nil), (*v1beta2.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_Deployment_To_v1beta2_Deployment(a.(*apps.Deployment), b.(*v1beta2.Deployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentCondition)(nil), (*extensions.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DeploymentCondition_To_extensions_DeploymentCondition(a.(*v1beta2.DeploymentCondition), b.(*extensions.DeploymentCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentCondition)(nil), (*apps.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DeploymentCondition_To_apps_DeploymentCondition(a.(*v1beta2.DeploymentCondition), b.(*apps.DeploymentCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentCondition)(nil), (*v1beta2.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentCondition_To_v1beta2_DeploymentCondition(a.(*extensions.DeploymentCondition), b.(*v1beta2.DeploymentCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentCondition)(nil), (*v1beta2.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentCondition_To_v1beta2_DeploymentCondition(a.(*apps.DeploymentCondition), b.(*v1beta2.DeploymentCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentList)(nil), (*extensions.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DeploymentList_To_extensions_DeploymentList(a.(*v1beta2.DeploymentList), b.(*extensions.DeploymentList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentList)(nil), (*apps.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DeploymentList_To_apps_DeploymentList(a.(*v1beta2.DeploymentList), b.(*apps.DeploymentList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentList)(nil), (*v1beta2.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentList_To_v1beta2_DeploymentList(a.(*extensions.DeploymentList), b.(*v1beta2.DeploymentList), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentList)(nil), (*v1beta2.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentList_To_v1beta2_DeploymentList(a.(*apps.DeploymentList), b.(*v1beta2.DeploymentList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentSpec)(nil), (*extensions.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(a.(*v1beta2.DeploymentSpec), b.(*extensions.DeploymentSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentSpec)(nil), (*apps.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DeploymentSpec_To_apps_DeploymentSpec(a.(*v1beta2.DeploymentSpec), b.(*apps.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentSpec)(nil), (*v1beta2.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(a.(*extensions.DeploymentSpec), b.(*v1beta2.DeploymentSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentSpec)(nil), (*v1beta2.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentSpec_To_v1beta2_DeploymentSpec(a.(*apps.DeploymentSpec), b.(*v1beta2.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentStatus)(nil), (*extensions.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DeploymentStatus_To_extensions_DeploymentStatus(a.(*v1beta2.DeploymentStatus), b.(*extensions.DeploymentStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentStatus)(nil), (*apps.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DeploymentStatus_To_apps_DeploymentStatus(a.(*v1beta2.DeploymentStatus), b.(*apps.DeploymentStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentStatus)(nil), (*v1beta2.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStatus_To_v1beta2_DeploymentStatus(a.(*extensions.DeploymentStatus), b.(*v1beta2.DeploymentStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentStatus)(nil), (*v1beta2.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStatus_To_v1beta2_DeploymentStatus(a.(*apps.DeploymentStatus), b.(*v1beta2.DeploymentStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentStrategy)(nil), (*extensions.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy(a.(*v1beta2.DeploymentStrategy), b.(*extensions.DeploymentStrategy), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.DeploymentStrategy)(nil), (*apps.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DeploymentStrategy_To_apps_DeploymentStrategy(a.(*v1beta2.DeploymentStrategy), b.(*apps.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentStrategy)(nil), (*v1beta2.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy(a.(*extensions.DeploymentStrategy), b.(*v1beta2.DeploymentStrategy), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentStrategy)(nil), (*v1beta2.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStrategy_To_v1beta2_DeploymentStrategy(a.(*apps.DeploymentStrategy), b.(*v1beta2.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSet)(nil), (*extensions.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_ReplicaSet_To_extensions_ReplicaSet(a.(*v1beta2.ReplicaSet), b.(*extensions.ReplicaSet), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSet)(nil), (*apps.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_ReplicaSet_To_apps_ReplicaSet(a.(*v1beta2.ReplicaSet), b.(*apps.ReplicaSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSet)(nil), (*v1beta2.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSet_To_v1beta2_ReplicaSet(a.(*extensions.ReplicaSet), b.(*v1beta2.ReplicaSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSet)(nil), (*v1beta2.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSet_To_v1beta2_ReplicaSet(a.(*apps.ReplicaSet), b.(*v1beta2.ReplicaSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSetCondition)(nil), (*extensions.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_ReplicaSetCondition_To_extensions_ReplicaSetCondition(a.(*v1beta2.ReplicaSetCondition), b.(*extensions.ReplicaSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSetCondition)(nil), (*apps.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_ReplicaSetCondition_To_apps_ReplicaSetCondition(a.(*v1beta2.ReplicaSetCondition), b.(*apps.ReplicaSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetCondition)(nil), (*v1beta2.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(a.(*extensions.ReplicaSetCondition), b.(*v1beta2.ReplicaSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetCondition)(nil), (*v1beta2.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(a.(*apps.ReplicaSetCondition), b.(*v1beta2.ReplicaSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSetList)(nil), (*extensions.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_ReplicaSetList_To_extensions_ReplicaSetList(a.(*v1beta2.ReplicaSetList), b.(*extensions.ReplicaSetList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSetList)(nil), (*apps.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_ReplicaSetList_To_apps_ReplicaSetList(a.(*v1beta2.ReplicaSetList), b.(*apps.ReplicaSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetList)(nil), (*v1beta2.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetList_To_v1beta2_ReplicaSetList(a.(*extensions.ReplicaSetList), b.(*v1beta2.ReplicaSetList), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetList)(nil), (*v1beta2.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetList_To_v1beta2_ReplicaSetList(a.(*apps.ReplicaSetList), b.(*v1beta2.ReplicaSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSetSpec)(nil), (*extensions.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_ReplicaSetSpec_To_extensions_ReplicaSetSpec(a.(*v1beta2.ReplicaSetSpec), b.(*extensions.ReplicaSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSetSpec)(nil), (*apps.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_ReplicaSetSpec_To_apps_ReplicaSetSpec(a.(*v1beta2.ReplicaSetSpec), b.(*apps.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetSpec)(nil), (*v1beta2.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(a.(*extensions.ReplicaSetSpec), b.(*v1beta2.ReplicaSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetSpec)(nil), (*v1beta2.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(a.(*apps.ReplicaSetSpec), b.(*v1beta2.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSetStatus)(nil), (*extensions.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_ReplicaSetStatus_To_extensions_ReplicaSetStatus(a.(*v1beta2.ReplicaSetStatus), b.(*extensions.ReplicaSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.ReplicaSetStatus)(nil), (*apps.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_ReplicaSetStatus_To_apps_ReplicaSetStatus(a.(*v1beta2.ReplicaSetStatus), b.(*apps.ReplicaSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetStatus)(nil), (*v1beta2.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(a.(*extensions.ReplicaSetStatus), b.(*v1beta2.ReplicaSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetStatus)(nil), (*v1beta2.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(a.(*apps.ReplicaSetStatus), b.(*v1beta2.ReplicaSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.RollingUpdateDaemonSet)(nil), (*extensions.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(a.(*v1beta2.RollingUpdateDaemonSet), b.(*extensions.RollingUpdateDaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.RollingUpdateDaemonSet)(nil), (*apps.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(a.(*v1beta2.RollingUpdateDaemonSet), b.(*apps.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollingUpdateDaemonSet)(nil), (*v1beta2.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(a.(*extensions.RollingUpdateDaemonSet), b.(*v1beta2.RollingUpdateDaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollingUpdateDaemonSet)(nil), (*v1beta2.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(a.(*apps.RollingUpdateDaemonSet), b.(*v1beta2.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.RollingUpdateDeployment)(nil), (*extensions.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(a.(*v1beta2.RollingUpdateDeployment), b.(*extensions.RollingUpdateDeployment), scope) + if err := s.AddGeneratedConversionFunc((*v1beta2.RollingUpdateDeployment)(nil), (*apps.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(a.(*v1beta2.RollingUpdateDeployment), b.(*apps.RollingUpdateDeployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollingUpdateDeployment)(nil), (*v1beta2.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(a.(*extensions.RollingUpdateDeployment), b.(*v1beta2.RollingUpdateDeployment), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollingUpdateDeployment)(nil), (*v1beta2.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(a.(*apps.RollingUpdateDeployment), b.(*v1beta2.RollingUpdateDeployment), scope) }); err != nil { return err } @@ -352,113 +351,113 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*apps.StatefulSetSpec)(nil), (*v1beta2.StatefulSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apps_StatefulSetSpec_To_v1beta2_StatefulSetSpec(a.(*apps.StatefulSetSpec), b.(*v1beta2.StatefulSetSpec), scope) + if err := s.AddConversionFunc((*apps.DaemonSetSpec)(nil), (*v1beta2.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetSpec_To_v1beta2_DaemonSetSpec(a.(*apps.DaemonSetSpec), b.(*v1beta2.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*apps.StatefulSetStatus)(nil), (*v1beta2.StatefulSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apps_StatefulSetStatus_To_v1beta2_StatefulSetStatus(a.(*apps.StatefulSetStatus), b.(*v1beta2.StatefulSetStatus), scope) + if err := s.AddConversionFunc((*apps.DaemonSetUpdateStrategy)(nil), (*v1beta2.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(a.(*apps.DaemonSetUpdateStrategy), b.(*v1beta2.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*apps.StatefulSetUpdateStrategy)(nil), (*v1beta2.StatefulSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apps_StatefulSetUpdateStrategy_To_v1beta2_StatefulSetUpdateStrategy(a.(*apps.StatefulSetUpdateStrategy), b.(*v1beta2.StatefulSetUpdateStrategy), scope) + if err := s.AddConversionFunc((*apps.DaemonSet)(nil), (*v1beta2.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSet_To_v1beta2_DaemonSet(a.(*apps.DaemonSet), b.(*v1beta2.DaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*autoscaling.ScaleStatus)(nil), (*v1beta2.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_autoscaling_ScaleStatus_To_v1beta2_ScaleStatus(a.(*autoscaling.ScaleStatus), b.(*v1beta2.ScaleStatus), scope) + if err := s.AddConversionFunc((*apps.DeploymentSpec)(nil), (*v1beta2.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentSpec_To_v1beta2_DeploymentSpec(a.(*apps.DeploymentSpec), b.(*v1beta2.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DaemonSetSpec)(nil), (*v1beta2.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec(a.(*extensions.DaemonSetSpec), b.(*v1beta2.DaemonSetSpec), scope) + if err := s.AddConversionFunc((*apps.DeploymentStrategy)(nil), (*v1beta2.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStrategy_To_v1beta2_DeploymentStrategy(a.(*apps.DeploymentStrategy), b.(*v1beta2.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DaemonSetUpdateStrategy)(nil), (*v1beta2.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(a.(*extensions.DaemonSetUpdateStrategy), b.(*v1beta2.DaemonSetUpdateStrategy), scope) + if err := s.AddConversionFunc((*apps.Deployment)(nil), (*v1beta2.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_Deployment_To_v1beta2_Deployment(a.(*apps.Deployment), b.(*v1beta2.Deployment), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DaemonSet)(nil), (*v1beta2.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSet_To_v1beta2_DaemonSet(a.(*extensions.DaemonSet), b.(*v1beta2.DaemonSet), scope) + if err := s.AddConversionFunc((*apps.ReplicaSetSpec)(nil), (*v1beta2.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(a.(*apps.ReplicaSetSpec), b.(*v1beta2.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DeploymentSpec)(nil), (*v1beta2.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(a.(*extensions.DeploymentSpec), b.(*v1beta2.DeploymentSpec), scope) + if err := s.AddConversionFunc((*apps.RollingUpdateDaemonSet)(nil), (*v1beta2.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(a.(*apps.RollingUpdateDaemonSet), b.(*v1beta2.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DeploymentStrategy)(nil), (*v1beta2.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy(a.(*extensions.DeploymentStrategy), b.(*v1beta2.DeploymentStrategy), scope) + if err := s.AddConversionFunc((*apps.RollingUpdateDeployment)(nil), (*v1beta2.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(a.(*apps.RollingUpdateDeployment), b.(*v1beta2.RollingUpdateDeployment), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.Deployment)(nil), (*v1beta2.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_Deployment_To_v1beta2_Deployment(a.(*extensions.Deployment), b.(*v1beta2.Deployment), scope) + if err := s.AddConversionFunc((*apps.StatefulSetSpec)(nil), (*v1beta2.StatefulSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_StatefulSetSpec_To_v1beta2_StatefulSetSpec(a.(*apps.StatefulSetSpec), b.(*v1beta2.StatefulSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.ReplicaSetSpec)(nil), (*v1beta2.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(a.(*extensions.ReplicaSetSpec), b.(*v1beta2.ReplicaSetSpec), scope) + if err := s.AddConversionFunc((*apps.StatefulSetStatus)(nil), (*v1beta2.StatefulSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_StatefulSetStatus_To_v1beta2_StatefulSetStatus(a.(*apps.StatefulSetStatus), b.(*v1beta2.StatefulSetStatus), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.RollingUpdateDaemonSet)(nil), (*v1beta2.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(a.(*extensions.RollingUpdateDaemonSet), b.(*v1beta2.RollingUpdateDaemonSet), scope) + if err := s.AddConversionFunc((*apps.StatefulSetUpdateStrategy)(nil), (*v1beta2.StatefulSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_StatefulSetUpdateStrategy_To_v1beta2_StatefulSetUpdateStrategy(a.(*apps.StatefulSetUpdateStrategy), b.(*v1beta2.StatefulSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.RollingUpdateDeployment)(nil), (*v1beta2.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(a.(*extensions.RollingUpdateDeployment), b.(*v1beta2.RollingUpdateDeployment), scope) + if err := s.AddConversionFunc((*autoscaling.ScaleStatus)(nil), (*v1beta2.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_autoscaling_ScaleStatus_To_v1beta2_ScaleStatus(a.(*autoscaling.ScaleStatus), b.(*v1beta2.ScaleStatus), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.DaemonSetSpec)(nil), (*extensions.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec(a.(*v1beta2.DaemonSetSpec), b.(*extensions.DaemonSetSpec), scope) + if err := s.AddConversionFunc((*v1beta2.DaemonSetSpec)(nil), (*apps.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSetSpec_To_apps_DaemonSetSpec(a.(*v1beta2.DaemonSetSpec), b.(*apps.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.DaemonSetUpdateStrategy)(nil), (*extensions.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(a.(*v1beta2.DaemonSetUpdateStrategy), b.(*extensions.DaemonSetUpdateStrategy), scope) + if err := s.AddConversionFunc((*v1beta2.DaemonSetUpdateStrategy)(nil), (*apps.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(a.(*v1beta2.DaemonSetUpdateStrategy), b.(*apps.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.DaemonSet)(nil), (*extensions.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DaemonSet_To_extensions_DaemonSet(a.(*v1beta2.DaemonSet), b.(*extensions.DaemonSet), scope) + if err := s.AddConversionFunc((*v1beta2.DaemonSet)(nil), (*apps.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DaemonSet_To_apps_DaemonSet(a.(*v1beta2.DaemonSet), b.(*apps.DaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.DeploymentSpec)(nil), (*extensions.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(a.(*v1beta2.DeploymentSpec), b.(*extensions.DeploymentSpec), scope) + if err := s.AddConversionFunc((*v1beta2.DeploymentSpec)(nil), (*apps.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DeploymentSpec_To_apps_DeploymentSpec(a.(*v1beta2.DeploymentSpec), b.(*apps.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.DeploymentStrategy)(nil), (*extensions.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy(a.(*v1beta2.DeploymentStrategy), b.(*extensions.DeploymentStrategy), scope) + if err := s.AddConversionFunc((*v1beta2.DeploymentStrategy)(nil), (*apps.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_DeploymentStrategy_To_apps_DeploymentStrategy(a.(*v1beta2.DeploymentStrategy), b.(*apps.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.Deployment)(nil), (*extensions.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_Deployment_To_extensions_Deployment(a.(*v1beta2.Deployment), b.(*extensions.Deployment), scope) + if err := s.AddConversionFunc((*v1beta2.Deployment)(nil), (*apps.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_Deployment_To_apps_Deployment(a.(*v1beta2.Deployment), b.(*apps.Deployment), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.ReplicaSetSpec)(nil), (*extensions.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_ReplicaSetSpec_To_extensions_ReplicaSetSpec(a.(*v1beta2.ReplicaSetSpec), b.(*extensions.ReplicaSetSpec), scope) + if err := s.AddConversionFunc((*v1beta2.ReplicaSetSpec)(nil), (*apps.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_ReplicaSetSpec_To_apps_ReplicaSetSpec(a.(*v1beta2.ReplicaSetSpec), b.(*apps.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.RollingUpdateDaemonSet)(nil), (*extensions.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(a.(*v1beta2.RollingUpdateDaemonSet), b.(*extensions.RollingUpdateDaemonSet), scope) + if err := s.AddConversionFunc((*v1beta2.RollingUpdateDaemonSet)(nil), (*apps.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(a.(*v1beta2.RollingUpdateDaemonSet), b.(*apps.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta2.RollingUpdateDeployment)(nil), (*extensions.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(a.(*v1beta2.RollingUpdateDeployment), b.(*extensions.RollingUpdateDeployment), scope) + if err := s.AddConversionFunc((*v1beta2.RollingUpdateDeployment)(nil), (*apps.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(a.(*v1beta2.RollingUpdateDeployment), b.(*apps.RollingUpdateDeployment), scope) }); err != nil { return err } @@ -555,30 +554,30 @@ func Convert_apps_ControllerRevisionList_To_v1beta2_ControllerRevisionList(in *a return autoConvert_apps_ControllerRevisionList_To_v1beta2_ControllerRevisionList(in, out, s) } -func autoConvert_v1beta2_DaemonSet_To_extensions_DaemonSet(in *v1beta2.DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error { +func autoConvert_v1beta2_DaemonSet_To_apps_DaemonSet(in *v1beta2.DaemonSet, out *apps.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta2_DaemonSetSpec_To_apps_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1beta2_DaemonSetStatus_To_extensions_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1beta2_DaemonSetStatus_To_apps_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func autoConvert_extensions_DaemonSet_To_v1beta2_DaemonSet(in *extensions.DaemonSet, out *v1beta2.DaemonSet, s conversion.Scope) error { +func autoConvert_apps_DaemonSet_To_v1beta2_DaemonSet(in *apps.DaemonSet, out *v1beta2.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DaemonSetSpec_To_v1beta2_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_DaemonSetStatus_To_v1beta2_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DaemonSetStatus_To_v1beta2_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func autoConvert_v1beta2_DaemonSetCondition_To_extensions_DaemonSetCondition(in *v1beta2.DaemonSetCondition, out *extensions.DaemonSetCondition, s conversion.Scope) error { - out.Type = extensions.DaemonSetConditionType(in.Type) +func autoConvert_v1beta2_DaemonSetCondition_To_apps_DaemonSetCondition(in *v1beta2.DaemonSetCondition, out *apps.DaemonSetCondition, s conversion.Scope) error { + out.Type = apps.DaemonSetConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime out.Reason = in.Reason @@ -586,12 +585,12 @@ func autoConvert_v1beta2_DaemonSetCondition_To_extensions_DaemonSetCondition(in return nil } -// Convert_v1beta2_DaemonSetCondition_To_extensions_DaemonSetCondition is an autogenerated conversion function. -func Convert_v1beta2_DaemonSetCondition_To_extensions_DaemonSetCondition(in *v1beta2.DaemonSetCondition, out *extensions.DaemonSetCondition, s conversion.Scope) error { - return autoConvert_v1beta2_DaemonSetCondition_To_extensions_DaemonSetCondition(in, out, s) +// Convert_v1beta2_DaemonSetCondition_To_apps_DaemonSetCondition is an autogenerated conversion function. +func Convert_v1beta2_DaemonSetCondition_To_apps_DaemonSetCondition(in *v1beta2.DaemonSetCondition, out *apps.DaemonSetCondition, s conversion.Scope) error { + return autoConvert_v1beta2_DaemonSetCondition_To_apps_DaemonSetCondition(in, out, s) } -func autoConvert_extensions_DaemonSetCondition_To_v1beta2_DaemonSetCondition(in *extensions.DaemonSetCondition, out *v1beta2.DaemonSetCondition, s conversion.Scope) error { +func autoConvert_apps_DaemonSetCondition_To_v1beta2_DaemonSetCondition(in *apps.DaemonSetCondition, out *v1beta2.DaemonSetCondition, s conversion.Scope) error { out.Type = v1beta2.DaemonSetConditionType(in.Type) out.Status = v1.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime @@ -600,18 +599,18 @@ func autoConvert_extensions_DaemonSetCondition_To_v1beta2_DaemonSetCondition(in return nil } -// Convert_extensions_DaemonSetCondition_To_v1beta2_DaemonSetCondition is an autogenerated conversion function. -func Convert_extensions_DaemonSetCondition_To_v1beta2_DaemonSetCondition(in *extensions.DaemonSetCondition, out *v1beta2.DaemonSetCondition, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetCondition_To_v1beta2_DaemonSetCondition(in, out, s) +// Convert_apps_DaemonSetCondition_To_v1beta2_DaemonSetCondition is an autogenerated conversion function. +func Convert_apps_DaemonSetCondition_To_v1beta2_DaemonSetCondition(in *apps.DaemonSetCondition, out *v1beta2.DaemonSetCondition, s conversion.Scope) error { + return autoConvert_apps_DaemonSetCondition_To_v1beta2_DaemonSetCondition(in, out, s) } -func autoConvert_v1beta2_DaemonSetList_To_extensions_DaemonSetList(in *v1beta2.DaemonSetList, out *extensions.DaemonSetList, s conversion.Scope) error { +func autoConvert_v1beta2_DaemonSetList_To_apps_DaemonSetList(in *v1beta2.DaemonSetList, out *apps.DaemonSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.DaemonSet, len(*in)) + *out = make([]apps.DaemonSet, len(*in)) for i := range *in { - if err := Convert_v1beta2_DaemonSet_To_extensions_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1beta2_DaemonSet_To_apps_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -621,18 +620,18 @@ func autoConvert_v1beta2_DaemonSetList_To_extensions_DaemonSetList(in *v1beta2.D return nil } -// Convert_v1beta2_DaemonSetList_To_extensions_DaemonSetList is an autogenerated conversion function. -func Convert_v1beta2_DaemonSetList_To_extensions_DaemonSetList(in *v1beta2.DaemonSetList, out *extensions.DaemonSetList, s conversion.Scope) error { - return autoConvert_v1beta2_DaemonSetList_To_extensions_DaemonSetList(in, out, s) +// Convert_v1beta2_DaemonSetList_To_apps_DaemonSetList is an autogenerated conversion function. +func Convert_v1beta2_DaemonSetList_To_apps_DaemonSetList(in *v1beta2.DaemonSetList, out *apps.DaemonSetList, s conversion.Scope) error { + return autoConvert_v1beta2_DaemonSetList_To_apps_DaemonSetList(in, out, s) } -func autoConvert_extensions_DaemonSetList_To_v1beta2_DaemonSetList(in *extensions.DaemonSetList, out *v1beta2.DaemonSetList, s conversion.Scope) error { +func autoConvert_apps_DaemonSetList_To_v1beta2_DaemonSetList(in *apps.DaemonSetList, out *v1beta2.DaemonSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1beta2.DaemonSet, len(*in)) for i := range *in { - if err := Convert_extensions_DaemonSet_To_v1beta2_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_DaemonSet_To_v1beta2_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -642,17 +641,17 @@ func autoConvert_extensions_DaemonSetList_To_v1beta2_DaemonSetList(in *extension return nil } -// Convert_extensions_DaemonSetList_To_v1beta2_DaemonSetList is an autogenerated conversion function. -func Convert_extensions_DaemonSetList_To_v1beta2_DaemonSetList(in *extensions.DaemonSetList, out *v1beta2.DaemonSetList, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetList_To_v1beta2_DaemonSetList(in, out, s) +// Convert_apps_DaemonSetList_To_v1beta2_DaemonSetList is an autogenerated conversion function. +func Convert_apps_DaemonSetList_To_v1beta2_DaemonSetList(in *apps.DaemonSetList, out *v1beta2.DaemonSetList, s conversion.Scope) error { + return autoConvert_apps_DaemonSetList_To_v1beta2_DaemonSetList(in, out, s) } -func autoConvert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec(in *v1beta2.DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error { +func autoConvert_v1beta2_DaemonSetSpec_To_apps_DaemonSetSpec(in *v1beta2.DaemonSetSpec, out *apps.DaemonSetSpec, s conversion.Scope) error { out.Selector = (*metav1.LabelSelector)(unsafe.Pointer(in.Selector)) if err := corev1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta2_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_v1beta2_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -660,12 +659,12 @@ func autoConvert_v1beta2_DaemonSetSpec_To_extensions_DaemonSetSpec(in *v1beta2.D return nil } -func autoConvert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec(in *extensions.DaemonSetSpec, out *v1beta2.DaemonSetSpec, s conversion.Scope) error { +func autoConvert_apps_DaemonSetSpec_To_v1beta2_DaemonSetSpec(in *apps.DaemonSetSpec, out *v1beta2.DaemonSetSpec, s conversion.Scope) error { out.Selector = (*metav1.LabelSelector)(unsafe.Pointer(in.Selector)) if err := corev1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_apps_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -674,7 +673,7 @@ func autoConvert_extensions_DaemonSetSpec_To_v1beta2_DaemonSetSpec(in *extension return nil } -func autoConvert_v1beta2_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1beta2.DaemonSetStatus, out *extensions.DaemonSetStatus, s conversion.Scope) error { +func autoConvert_v1beta2_DaemonSetStatus_To_apps_DaemonSetStatus(in *v1beta2.DaemonSetStatus, out *apps.DaemonSetStatus, s conversion.Scope) error { out.CurrentNumberScheduled = in.CurrentNumberScheduled out.NumberMisscheduled = in.NumberMisscheduled out.DesiredNumberScheduled = in.DesiredNumberScheduled @@ -684,16 +683,16 @@ func autoConvert_v1beta2_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1bet out.NumberAvailable = in.NumberAvailable out.NumberUnavailable = in.NumberUnavailable out.CollisionCount = (*int32)(unsafe.Pointer(in.CollisionCount)) - out.Conditions = *(*[]extensions.DaemonSetCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.DaemonSetCondition)(unsafe.Pointer(&in.Conditions)) return nil } -// Convert_v1beta2_DaemonSetStatus_To_extensions_DaemonSetStatus is an autogenerated conversion function. -func Convert_v1beta2_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1beta2.DaemonSetStatus, out *extensions.DaemonSetStatus, s conversion.Scope) error { - return autoConvert_v1beta2_DaemonSetStatus_To_extensions_DaemonSetStatus(in, out, s) +// Convert_v1beta2_DaemonSetStatus_To_apps_DaemonSetStatus is an autogenerated conversion function. +func Convert_v1beta2_DaemonSetStatus_To_apps_DaemonSetStatus(in *v1beta2.DaemonSetStatus, out *apps.DaemonSetStatus, s conversion.Scope) error { + return autoConvert_v1beta2_DaemonSetStatus_To_apps_DaemonSetStatus(in, out, s) } -func autoConvert_extensions_DaemonSetStatus_To_v1beta2_DaemonSetStatus(in *extensions.DaemonSetStatus, out *v1beta2.DaemonSetStatus, s conversion.Scope) error { +func autoConvert_apps_DaemonSetStatus_To_v1beta2_DaemonSetStatus(in *apps.DaemonSetStatus, out *v1beta2.DaemonSetStatus, s conversion.Scope) error { out.CurrentNumberScheduled = in.CurrentNumberScheduled out.NumberMisscheduled = in.NumberMisscheduled out.DesiredNumberScheduled = in.DesiredNumberScheduled @@ -707,17 +706,17 @@ func autoConvert_extensions_DaemonSetStatus_To_v1beta2_DaemonSetStatus(in *exten return nil } -// Convert_extensions_DaemonSetStatus_To_v1beta2_DaemonSetStatus is an autogenerated conversion function. -func Convert_extensions_DaemonSetStatus_To_v1beta2_DaemonSetStatus(in *extensions.DaemonSetStatus, out *v1beta2.DaemonSetStatus, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetStatus_To_v1beta2_DaemonSetStatus(in, out, s) +// Convert_apps_DaemonSetStatus_To_v1beta2_DaemonSetStatus is an autogenerated conversion function. +func Convert_apps_DaemonSetStatus_To_v1beta2_DaemonSetStatus(in *apps.DaemonSetStatus, out *v1beta2.DaemonSetStatus, s conversion.Scope) error { + return autoConvert_apps_DaemonSetStatus_To_v1beta2_DaemonSetStatus(in, out, s) } -func autoConvert_v1beta2_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in *v1beta2.DaemonSetUpdateStrategy, out *extensions.DaemonSetUpdateStrategy, s conversion.Scope) error { - out.Type = extensions.DaemonSetUpdateStrategyType(in.Type) +func autoConvert_v1beta2_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(in *v1beta2.DaemonSetUpdateStrategy, out *apps.DaemonSetUpdateStrategy, s conversion.Scope) error { + out.Type = apps.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(extensions.RollingUpdateDaemonSet) - if err := Convert_v1beta2_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(*in, *out, s); err != nil { + *out = new(apps.RollingUpdateDaemonSet) + if err := Convert_v1beta2_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(*in, *out, s); err != nil { return err } } else { @@ -726,12 +725,12 @@ func autoConvert_v1beta2_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateSt return nil } -func autoConvert_extensions_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(in *extensions.DaemonSetUpdateStrategy, out *v1beta2.DaemonSetUpdateStrategy, s conversion.Scope) error { +func autoConvert_apps_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateStrategy(in *apps.DaemonSetUpdateStrategy, out *v1beta2.DaemonSetUpdateStrategy, s conversion.Scope) error { out.Type = v1beta2.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate *out = new(v1beta2.RollingUpdateDaemonSet) - if err := Convert_extensions_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(*in, *out, s); err != nil { + if err := Convert_apps_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(*in, *out, s); err != nil { return err } } else { @@ -740,30 +739,30 @@ func autoConvert_extensions_DaemonSetUpdateStrategy_To_v1beta2_DaemonSetUpdateSt return nil } -func autoConvert_v1beta2_Deployment_To_extensions_Deployment(in *v1beta2.Deployment, out *extensions.Deployment, s conversion.Scope) error { +func autoConvert_v1beta2_Deployment_To_apps_Deployment(in *v1beta2.Deployment, out *apps.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta2_DeploymentSpec_To_apps_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1beta2_DeploymentStatus_To_extensions_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1beta2_DeploymentStatus_To_apps_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func autoConvert_extensions_Deployment_To_v1beta2_Deployment(in *extensions.Deployment, out *v1beta2.Deployment, s conversion.Scope) error { +func autoConvert_apps_Deployment_To_v1beta2_Deployment(in *apps.Deployment, out *v1beta2.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DeploymentSpec_To_v1beta2_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_DeploymentStatus_To_v1beta2_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DeploymentStatus_To_v1beta2_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func autoConvert_v1beta2_DeploymentCondition_To_extensions_DeploymentCondition(in *v1beta2.DeploymentCondition, out *extensions.DeploymentCondition, s conversion.Scope) error { - out.Type = extensions.DeploymentConditionType(in.Type) +func autoConvert_v1beta2_DeploymentCondition_To_apps_DeploymentCondition(in *v1beta2.DeploymentCondition, out *apps.DeploymentCondition, s conversion.Scope) error { + out.Type = apps.DeploymentConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastUpdateTime = in.LastUpdateTime out.LastTransitionTime = in.LastTransitionTime @@ -772,12 +771,12 @@ func autoConvert_v1beta2_DeploymentCondition_To_extensions_DeploymentCondition(i return nil } -// Convert_v1beta2_DeploymentCondition_To_extensions_DeploymentCondition is an autogenerated conversion function. -func Convert_v1beta2_DeploymentCondition_To_extensions_DeploymentCondition(in *v1beta2.DeploymentCondition, out *extensions.DeploymentCondition, s conversion.Scope) error { - return autoConvert_v1beta2_DeploymentCondition_To_extensions_DeploymentCondition(in, out, s) +// Convert_v1beta2_DeploymentCondition_To_apps_DeploymentCondition is an autogenerated conversion function. +func Convert_v1beta2_DeploymentCondition_To_apps_DeploymentCondition(in *v1beta2.DeploymentCondition, out *apps.DeploymentCondition, s conversion.Scope) error { + return autoConvert_v1beta2_DeploymentCondition_To_apps_DeploymentCondition(in, out, s) } -func autoConvert_extensions_DeploymentCondition_To_v1beta2_DeploymentCondition(in *extensions.DeploymentCondition, out *v1beta2.DeploymentCondition, s conversion.Scope) error { +func autoConvert_apps_DeploymentCondition_To_v1beta2_DeploymentCondition(in *apps.DeploymentCondition, out *v1beta2.DeploymentCondition, s conversion.Scope) error { out.Type = v1beta2.DeploymentConditionType(in.Type) out.Status = v1.ConditionStatus(in.Status) out.LastUpdateTime = in.LastUpdateTime @@ -787,18 +786,18 @@ func autoConvert_extensions_DeploymentCondition_To_v1beta2_DeploymentCondition(i return nil } -// Convert_extensions_DeploymentCondition_To_v1beta2_DeploymentCondition is an autogenerated conversion function. -func Convert_extensions_DeploymentCondition_To_v1beta2_DeploymentCondition(in *extensions.DeploymentCondition, out *v1beta2.DeploymentCondition, s conversion.Scope) error { - return autoConvert_extensions_DeploymentCondition_To_v1beta2_DeploymentCondition(in, out, s) +// Convert_apps_DeploymentCondition_To_v1beta2_DeploymentCondition is an autogenerated conversion function. +func Convert_apps_DeploymentCondition_To_v1beta2_DeploymentCondition(in *apps.DeploymentCondition, out *v1beta2.DeploymentCondition, s conversion.Scope) error { + return autoConvert_apps_DeploymentCondition_To_v1beta2_DeploymentCondition(in, out, s) } -func autoConvert_v1beta2_DeploymentList_To_extensions_DeploymentList(in *v1beta2.DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { +func autoConvert_v1beta2_DeploymentList_To_apps_DeploymentList(in *v1beta2.DeploymentList, out *apps.DeploymentList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.Deployment, len(*in)) + *out = make([]apps.Deployment, len(*in)) for i := range *in { - if err := Convert_v1beta2_Deployment_To_extensions_Deployment(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1beta2_Deployment_To_apps_Deployment(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -808,18 +807,18 @@ func autoConvert_v1beta2_DeploymentList_To_extensions_DeploymentList(in *v1beta2 return nil } -// Convert_v1beta2_DeploymentList_To_extensions_DeploymentList is an autogenerated conversion function. -func Convert_v1beta2_DeploymentList_To_extensions_DeploymentList(in *v1beta2.DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { - return autoConvert_v1beta2_DeploymentList_To_extensions_DeploymentList(in, out, s) +// Convert_v1beta2_DeploymentList_To_apps_DeploymentList is an autogenerated conversion function. +func Convert_v1beta2_DeploymentList_To_apps_DeploymentList(in *v1beta2.DeploymentList, out *apps.DeploymentList, s conversion.Scope) error { + return autoConvert_v1beta2_DeploymentList_To_apps_DeploymentList(in, out, s) } -func autoConvert_extensions_DeploymentList_To_v1beta2_DeploymentList(in *extensions.DeploymentList, out *v1beta2.DeploymentList, s conversion.Scope) error { +func autoConvert_apps_DeploymentList_To_v1beta2_DeploymentList(in *apps.DeploymentList, out *v1beta2.DeploymentList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1beta2.Deployment, len(*in)) for i := range *in { - if err := Convert_extensions_Deployment_To_v1beta2_Deployment(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_Deployment_To_v1beta2_Deployment(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -829,12 +828,12 @@ func autoConvert_extensions_DeploymentList_To_v1beta2_DeploymentList(in *extensi return nil } -// Convert_extensions_DeploymentList_To_v1beta2_DeploymentList is an autogenerated conversion function. -func Convert_extensions_DeploymentList_To_v1beta2_DeploymentList(in *extensions.DeploymentList, out *v1beta2.DeploymentList, s conversion.Scope) error { - return autoConvert_extensions_DeploymentList_To_v1beta2_DeploymentList(in, out, s) +// Convert_apps_DeploymentList_To_v1beta2_DeploymentList is an autogenerated conversion function. +func Convert_apps_DeploymentList_To_v1beta2_DeploymentList(in *apps.DeploymentList, out *v1beta2.DeploymentList, s conversion.Scope) error { + return autoConvert_apps_DeploymentList_To_v1beta2_DeploymentList(in, out, s) } -func autoConvert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(in *v1beta2.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { +func autoConvert_v1beta2_DeploymentSpec_To_apps_DeploymentSpec(in *v1beta2.DeploymentSpec, out *apps.DeploymentSpec, s conversion.Scope) error { if err := metav1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -842,7 +841,7 @@ func autoConvert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(in *v1beta2 if err := corev1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_v1beta2_DeploymentStrategy_To_apps_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -852,7 +851,7 @@ func autoConvert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec(in *v1beta2 return nil } -func autoConvert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(in *extensions.DeploymentSpec, out *v1beta2.DeploymentSpec, s conversion.Scope) error { +func autoConvert_apps_DeploymentSpec_To_v1beta2_DeploymentSpec(in *apps.DeploymentSpec, out *v1beta2.DeploymentSpec, s conversion.Scope) error { if err := metav1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -860,7 +859,7 @@ func autoConvert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(in *extensi if err := corev1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_apps_DeploymentStrategy_To_v1beta2_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -871,24 +870,24 @@ func autoConvert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec(in *extensi return nil } -func autoConvert_v1beta2_DeploymentStatus_To_extensions_DeploymentStatus(in *v1beta2.DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { +func autoConvert_v1beta2_DeploymentStatus_To_apps_DeploymentStatus(in *v1beta2.DeploymentStatus, out *apps.DeploymentStatus, s conversion.Scope) error { out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas out.ReadyReplicas = in.ReadyReplicas out.AvailableReplicas = in.AvailableReplicas out.UnavailableReplicas = in.UnavailableReplicas - out.Conditions = *(*[]extensions.DeploymentCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.DeploymentCondition)(unsafe.Pointer(&in.Conditions)) out.CollisionCount = (*int32)(unsafe.Pointer(in.CollisionCount)) return nil } -// Convert_v1beta2_DeploymentStatus_To_extensions_DeploymentStatus is an autogenerated conversion function. -func Convert_v1beta2_DeploymentStatus_To_extensions_DeploymentStatus(in *v1beta2.DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { - return autoConvert_v1beta2_DeploymentStatus_To_extensions_DeploymentStatus(in, out, s) +// Convert_v1beta2_DeploymentStatus_To_apps_DeploymentStatus is an autogenerated conversion function. +func Convert_v1beta2_DeploymentStatus_To_apps_DeploymentStatus(in *v1beta2.DeploymentStatus, out *apps.DeploymentStatus, s conversion.Scope) error { + return autoConvert_v1beta2_DeploymentStatus_To_apps_DeploymentStatus(in, out, s) } -func autoConvert_extensions_DeploymentStatus_To_v1beta2_DeploymentStatus(in *extensions.DeploymentStatus, out *v1beta2.DeploymentStatus, s conversion.Scope) error { +func autoConvert_apps_DeploymentStatus_To_v1beta2_DeploymentStatus(in *apps.DeploymentStatus, out *v1beta2.DeploymentStatus, s conversion.Scope) error { out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas @@ -900,17 +899,17 @@ func autoConvert_extensions_DeploymentStatus_To_v1beta2_DeploymentStatus(in *ext return nil } -// Convert_extensions_DeploymentStatus_To_v1beta2_DeploymentStatus is an autogenerated conversion function. -func Convert_extensions_DeploymentStatus_To_v1beta2_DeploymentStatus(in *extensions.DeploymentStatus, out *v1beta2.DeploymentStatus, s conversion.Scope) error { - return autoConvert_extensions_DeploymentStatus_To_v1beta2_DeploymentStatus(in, out, s) +// Convert_apps_DeploymentStatus_To_v1beta2_DeploymentStatus is an autogenerated conversion function. +func Convert_apps_DeploymentStatus_To_v1beta2_DeploymentStatus(in *apps.DeploymentStatus, out *v1beta2.DeploymentStatus, s conversion.Scope) error { + return autoConvert_apps_DeploymentStatus_To_v1beta2_DeploymentStatus(in, out, s) } -func autoConvert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy(in *v1beta2.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { - out.Type = extensions.DeploymentStrategyType(in.Type) +func autoConvert_v1beta2_DeploymentStrategy_To_apps_DeploymentStrategy(in *v1beta2.DeploymentStrategy, out *apps.DeploymentStrategy, s conversion.Scope) error { + out.Type = apps.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(extensions.RollingUpdateDeployment) - if err := Convert_v1beta2_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(*in, *out, s); err != nil { + *out = new(apps.RollingUpdateDeployment) + if err := Convert_v1beta2_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(*in, *out, s); err != nil { return err } } else { @@ -919,12 +918,12 @@ func autoConvert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy(in return nil } -func autoConvert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy(in *extensions.DeploymentStrategy, out *v1beta2.DeploymentStrategy, s conversion.Scope) error { +func autoConvert_apps_DeploymentStrategy_To_v1beta2_DeploymentStrategy(in *apps.DeploymentStrategy, out *v1beta2.DeploymentStrategy, s conversion.Scope) error { out.Type = v1beta2.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate *out = new(v1beta2.RollingUpdateDeployment) - if err := Convert_extensions_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(*in, *out, s); err != nil { + if err := Convert_apps_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(*in, *out, s); err != nil { return err } } else { @@ -933,40 +932,40 @@ func autoConvert_extensions_DeploymentStrategy_To_v1beta2_DeploymentStrategy(in return nil } -func autoConvert_v1beta2_ReplicaSet_To_extensions_ReplicaSet(in *v1beta2.ReplicaSet, out *extensions.ReplicaSet, s conversion.Scope) error { +func autoConvert_v1beta2_ReplicaSet_To_apps_ReplicaSet(in *v1beta2.ReplicaSet, out *apps.ReplicaSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta2_ReplicaSetSpec_To_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta2_ReplicaSetSpec_To_apps_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1beta2_ReplicaSetStatus_To_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1beta2_ReplicaSetStatus_To_apps_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_v1beta2_ReplicaSet_To_extensions_ReplicaSet is an autogenerated conversion function. -func Convert_v1beta2_ReplicaSet_To_extensions_ReplicaSet(in *v1beta2.ReplicaSet, out *extensions.ReplicaSet, s conversion.Scope) error { - return autoConvert_v1beta2_ReplicaSet_To_extensions_ReplicaSet(in, out, s) +// Convert_v1beta2_ReplicaSet_To_apps_ReplicaSet is an autogenerated conversion function. +func Convert_v1beta2_ReplicaSet_To_apps_ReplicaSet(in *v1beta2.ReplicaSet, out *apps.ReplicaSet, s conversion.Scope) error { + return autoConvert_v1beta2_ReplicaSet_To_apps_ReplicaSet(in, out, s) } -func autoConvert_extensions_ReplicaSet_To_v1beta2_ReplicaSet(in *extensions.ReplicaSet, out *v1beta2.ReplicaSet, s conversion.Scope) error { +func autoConvert_apps_ReplicaSet_To_v1beta2_ReplicaSet(in *apps.ReplicaSet, out *v1beta2.ReplicaSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_extensions_ReplicaSet_To_v1beta2_ReplicaSet is an autogenerated conversion function. -func Convert_extensions_ReplicaSet_To_v1beta2_ReplicaSet(in *extensions.ReplicaSet, out *v1beta2.ReplicaSet, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSet_To_v1beta2_ReplicaSet(in, out, s) +// Convert_apps_ReplicaSet_To_v1beta2_ReplicaSet is an autogenerated conversion function. +func Convert_apps_ReplicaSet_To_v1beta2_ReplicaSet(in *apps.ReplicaSet, out *v1beta2.ReplicaSet, s conversion.Scope) error { + return autoConvert_apps_ReplicaSet_To_v1beta2_ReplicaSet(in, out, s) } -func autoConvert_v1beta2_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in *v1beta2.ReplicaSetCondition, out *extensions.ReplicaSetCondition, s conversion.Scope) error { - out.Type = extensions.ReplicaSetConditionType(in.Type) +func autoConvert_v1beta2_ReplicaSetCondition_To_apps_ReplicaSetCondition(in *v1beta2.ReplicaSetCondition, out *apps.ReplicaSetCondition, s conversion.Scope) error { + out.Type = apps.ReplicaSetConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime out.Reason = in.Reason @@ -974,12 +973,12 @@ func autoConvert_v1beta2_ReplicaSetCondition_To_extensions_ReplicaSetCondition(i return nil } -// Convert_v1beta2_ReplicaSetCondition_To_extensions_ReplicaSetCondition is an autogenerated conversion function. -func Convert_v1beta2_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in *v1beta2.ReplicaSetCondition, out *extensions.ReplicaSetCondition, s conversion.Scope) error { - return autoConvert_v1beta2_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in, out, s) +// Convert_v1beta2_ReplicaSetCondition_To_apps_ReplicaSetCondition is an autogenerated conversion function. +func Convert_v1beta2_ReplicaSetCondition_To_apps_ReplicaSetCondition(in *v1beta2.ReplicaSetCondition, out *apps.ReplicaSetCondition, s conversion.Scope) error { + return autoConvert_v1beta2_ReplicaSetCondition_To_apps_ReplicaSetCondition(in, out, s) } -func autoConvert_extensions_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(in *extensions.ReplicaSetCondition, out *v1beta2.ReplicaSetCondition, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(in *apps.ReplicaSetCondition, out *v1beta2.ReplicaSetCondition, s conversion.Scope) error { out.Type = v1beta2.ReplicaSetConditionType(in.Type) out.Status = v1.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime @@ -988,18 +987,18 @@ func autoConvert_extensions_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(i return nil } -// Convert_extensions_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition is an autogenerated conversion function. -func Convert_extensions_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(in *extensions.ReplicaSetCondition, out *v1beta2.ReplicaSetCondition, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(in, out, s) +// Convert_apps_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition is an autogenerated conversion function. +func Convert_apps_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(in *apps.ReplicaSetCondition, out *v1beta2.ReplicaSetCondition, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetCondition_To_v1beta2_ReplicaSetCondition(in, out, s) } -func autoConvert_v1beta2_ReplicaSetList_To_extensions_ReplicaSetList(in *v1beta2.ReplicaSetList, out *extensions.ReplicaSetList, s conversion.Scope) error { +func autoConvert_v1beta2_ReplicaSetList_To_apps_ReplicaSetList(in *v1beta2.ReplicaSetList, out *apps.ReplicaSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.ReplicaSet, len(*in)) + *out = make([]apps.ReplicaSet, len(*in)) for i := range *in { - if err := Convert_v1beta2_ReplicaSet_To_extensions_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1beta2_ReplicaSet_To_apps_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -1009,18 +1008,18 @@ func autoConvert_v1beta2_ReplicaSetList_To_extensions_ReplicaSetList(in *v1beta2 return nil } -// Convert_v1beta2_ReplicaSetList_To_extensions_ReplicaSetList is an autogenerated conversion function. -func Convert_v1beta2_ReplicaSetList_To_extensions_ReplicaSetList(in *v1beta2.ReplicaSetList, out *extensions.ReplicaSetList, s conversion.Scope) error { - return autoConvert_v1beta2_ReplicaSetList_To_extensions_ReplicaSetList(in, out, s) +// Convert_v1beta2_ReplicaSetList_To_apps_ReplicaSetList is an autogenerated conversion function. +func Convert_v1beta2_ReplicaSetList_To_apps_ReplicaSetList(in *v1beta2.ReplicaSetList, out *apps.ReplicaSetList, s conversion.Scope) error { + return autoConvert_v1beta2_ReplicaSetList_To_apps_ReplicaSetList(in, out, s) } -func autoConvert_extensions_ReplicaSetList_To_v1beta2_ReplicaSetList(in *extensions.ReplicaSetList, out *v1beta2.ReplicaSetList, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetList_To_v1beta2_ReplicaSetList(in *apps.ReplicaSetList, out *v1beta2.ReplicaSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1beta2.ReplicaSet, len(*in)) for i := range *in { - if err := Convert_extensions_ReplicaSet_To_v1beta2_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_ReplicaSet_To_v1beta2_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -1030,12 +1029,12 @@ func autoConvert_extensions_ReplicaSetList_To_v1beta2_ReplicaSetList(in *extensi return nil } -// Convert_extensions_ReplicaSetList_To_v1beta2_ReplicaSetList is an autogenerated conversion function. -func Convert_extensions_ReplicaSetList_To_v1beta2_ReplicaSetList(in *extensions.ReplicaSetList, out *v1beta2.ReplicaSetList, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetList_To_v1beta2_ReplicaSetList(in, out, s) +// Convert_apps_ReplicaSetList_To_v1beta2_ReplicaSetList is an autogenerated conversion function. +func Convert_apps_ReplicaSetList_To_v1beta2_ReplicaSetList(in *apps.ReplicaSetList, out *v1beta2.ReplicaSetList, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetList_To_v1beta2_ReplicaSetList(in, out, s) } -func autoConvert_v1beta2_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *v1beta2.ReplicaSetSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error { +func autoConvert_v1beta2_ReplicaSetSpec_To_apps_ReplicaSetSpec(in *v1beta2.ReplicaSetSpec, out *apps.ReplicaSetSpec, s conversion.Scope) error { if err := metav1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -1047,7 +1046,7 @@ func autoConvert_v1beta2_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *v1beta2 return nil } -func autoConvert_extensions_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(in *extensions.ReplicaSetSpec, out *v1beta2.ReplicaSetSpec, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(in *apps.ReplicaSetSpec, out *v1beta2.ReplicaSetSpec, s conversion.Scope) error { if err := metav1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -1059,22 +1058,22 @@ func autoConvert_extensions_ReplicaSetSpec_To_v1beta2_ReplicaSetSpec(in *extensi return nil } -func autoConvert_v1beta2_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in *v1beta2.ReplicaSetStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error { +func autoConvert_v1beta2_ReplicaSetStatus_To_apps_ReplicaSetStatus(in *v1beta2.ReplicaSetStatus, out *apps.ReplicaSetStatus, s conversion.Scope) error { out.Replicas = in.Replicas out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ReadyReplicas = in.ReadyReplicas out.AvailableReplicas = in.AvailableReplicas out.ObservedGeneration = in.ObservedGeneration - out.Conditions = *(*[]extensions.ReplicaSetCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.ReplicaSetCondition)(unsafe.Pointer(&in.Conditions)) return nil } -// Convert_v1beta2_ReplicaSetStatus_To_extensions_ReplicaSetStatus is an autogenerated conversion function. -func Convert_v1beta2_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in *v1beta2.ReplicaSetStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error { - return autoConvert_v1beta2_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in, out, s) +// Convert_v1beta2_ReplicaSetStatus_To_apps_ReplicaSetStatus is an autogenerated conversion function. +func Convert_v1beta2_ReplicaSetStatus_To_apps_ReplicaSetStatus(in *v1beta2.ReplicaSetStatus, out *apps.ReplicaSetStatus, s conversion.Scope) error { + return autoConvert_v1beta2_ReplicaSetStatus_To_apps_ReplicaSetStatus(in, out, s) } -func autoConvert_extensions_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(in *extensions.ReplicaSetStatus, out *v1beta2.ReplicaSetStatus, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(in *apps.ReplicaSetStatus, out *v1beta2.ReplicaSetStatus, s conversion.Scope) error { out.Replicas = in.Replicas out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ReadyReplicas = in.ReadyReplicas @@ -1084,28 +1083,28 @@ func autoConvert_extensions_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(in *ext return nil } -// Convert_extensions_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus is an autogenerated conversion function. -func Convert_extensions_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(in *extensions.ReplicaSetStatus, out *v1beta2.ReplicaSetStatus, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(in, out, s) +// Convert_apps_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus is an autogenerated conversion function. +func Convert_apps_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(in *apps.ReplicaSetStatus, out *v1beta2.ReplicaSetStatus, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetStatus_To_v1beta2_ReplicaSetStatus(in, out, s) } -func autoConvert_v1beta2_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in *v1beta2.RollingUpdateDaemonSet, out *extensions.RollingUpdateDaemonSet, s conversion.Scope) error { +func autoConvert_v1beta2_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(in *v1beta2.RollingUpdateDaemonSet, out *apps.RollingUpdateDaemonSet, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_extensions_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *v1beta2.RollingUpdateDaemonSet, s conversion.Scope) error { +func autoConvert_apps_RollingUpdateDaemonSet_To_v1beta2_RollingUpdateDaemonSet(in *apps.RollingUpdateDaemonSet, out *v1beta2.RollingUpdateDaemonSet, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_v1beta2_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *v1beta2.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { +func autoConvert_v1beta2_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in *v1beta2.RollingUpdateDeployment, out *apps.RollingUpdateDeployment, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) // WARNING: in.MaxSurge requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_extensions_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *v1beta2.RollingUpdateDeployment, s conversion.Scope) error { +func autoConvert_apps_RollingUpdateDeployment_To_v1beta2_RollingUpdateDeployment(in *apps.RollingUpdateDeployment, out *v1beta2.RollingUpdateDeployment, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) // WARNING: in.MaxSurge requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil diff --git a/pkg/apis/apps/validation/BUILD b/pkg/apis/apps/validation/BUILD index b1468e1f9303c..507558c158abc 100644 --- a/pkg/apis/apps/validation/BUILD +++ b/pkg/apis/apps/validation/BUILD @@ -19,6 +19,8 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", ], ) @@ -32,7 +34,9 @@ go_test( "//pkg/apis/core:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", + "//vendor/github.com/davecgh/go-spew/spew:go_default_library", ], ) diff --git a/pkg/apis/apps/validation/validation.go b/pkg/apis/apps/validation/validation.go index 5653d7cad75de..7cdf4c2dc27f6 100644 --- a/pkg/apis/apps/validation/validation.go +++ b/pkg/apis/apps/validation/validation.go @@ -18,12 +18,15 @@ package validation import ( "fmt" + "strconv" apiequality "k8s.io/apimachinery/pkg/api/equality" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" @@ -236,3 +239,433 @@ func ValidateControllerRevisionUpdate(newHistory, oldHistory *apps.ControllerRev errs = append(errs, apivalidation.ValidateImmutableField(newHistory.Data, oldHistory.Data, field.NewPath("data"))...) return errs } + +// ValidateDaemonSet tests if required fields in the DaemonSet are set. +func ValidateDaemonSet(ds *apps.DaemonSet) field.ErrorList { + allErrs := apivalidation.ValidateObjectMeta(&ds.ObjectMeta, true, ValidateDaemonSetName, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateDaemonSetSpec(&ds.Spec, field.NewPath("spec"))...) + return allErrs +} + +// ValidateDaemonSetUpdate tests if required fields in the DaemonSet are set. +func ValidateDaemonSetUpdate(ds, oldDS *apps.DaemonSet) field.ErrorList { + allErrs := apivalidation.ValidateObjectMetaUpdate(&ds.ObjectMeta, &oldDS.ObjectMeta, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateDaemonSetSpecUpdate(&ds.Spec, &oldDS.Spec, field.NewPath("spec"))...) + allErrs = append(allErrs, ValidateDaemonSetSpec(&ds.Spec, field.NewPath("spec"))...) + return allErrs +} + +func ValidateDaemonSetSpecUpdate(newSpec, oldSpec *apps.DaemonSetSpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + // TemplateGeneration shouldn't be decremented + if newSpec.TemplateGeneration < oldSpec.TemplateGeneration { + allErrs = append(allErrs, field.Invalid(fldPath.Child("templateGeneration"), newSpec.TemplateGeneration, "must not be decremented")) + } + + // TemplateGeneration should be increased when and only when template is changed + templateUpdated := !apiequality.Semantic.DeepEqual(newSpec.Template, oldSpec.Template) + if newSpec.TemplateGeneration == oldSpec.TemplateGeneration && templateUpdated { + allErrs = append(allErrs, field.Invalid(fldPath.Child("templateGeneration"), newSpec.TemplateGeneration, "must be incremented upon template update")) + } else if newSpec.TemplateGeneration > oldSpec.TemplateGeneration && !templateUpdated { + allErrs = append(allErrs, field.Invalid(fldPath.Child("templateGeneration"), newSpec.TemplateGeneration, "must not be incremented without template update")) + } + + return allErrs +} + +// validateDaemonSetStatus validates a DaemonSetStatus +func validateDaemonSetStatus(status *apps.DaemonSetStatus, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.CurrentNumberScheduled), fldPath.Child("currentNumberScheduled"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.NumberMisscheduled), fldPath.Child("numberMisscheduled"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.DesiredNumberScheduled), fldPath.Child("desiredNumberScheduled"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.NumberReady), fldPath.Child("numberReady"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(status.ObservedGeneration, fldPath.Child("observedGeneration"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UpdatedNumberScheduled), fldPath.Child("updatedNumberScheduled"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.NumberAvailable), fldPath.Child("numberAvailable"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.NumberUnavailable), fldPath.Child("numberUnavailable"))...) + if status.CollisionCount != nil { + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*status.CollisionCount), fldPath.Child("collisionCount"))...) + } + return allErrs +} + +// ValidateDaemonSetStatus validates tests if required fields in the DaemonSet Status section +func ValidateDaemonSetStatusUpdate(ds, oldDS *apps.DaemonSet) field.ErrorList { + allErrs := apivalidation.ValidateObjectMetaUpdate(&ds.ObjectMeta, &oldDS.ObjectMeta, field.NewPath("metadata")) + allErrs = append(allErrs, validateDaemonSetStatus(&ds.Status, field.NewPath("status"))...) + if apivalidation.IsDecremented(ds.Status.CollisionCount, oldDS.Status.CollisionCount) { + value := int32(0) + if ds.Status.CollisionCount != nil { + value = *ds.Status.CollisionCount + } + allErrs = append(allErrs, field.Invalid(field.NewPath("status").Child("collisionCount"), value, "cannot be decremented")) + } + return allErrs +} + +// ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set. +func ValidateDaemonSetSpec(spec *apps.DaemonSetSpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) + + selector, err := metav1.LabelSelectorAsSelector(spec.Selector) + if err == nil && !selector.Matches(labels.Set(spec.Template.Labels)) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "metadata", "labels"), spec.Template.Labels, "`selector` does not match template `labels`")) + } + if spec.Selector != nil && len(spec.Selector.MatchLabels)+len(spec.Selector.MatchExpressions) == 0 { + allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "empty selector is invalid for daemonset")) + } + + allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(&spec.Template, fldPath.Child("template"))...) + // Daemons typically run on more than one node, so mark Read-Write persistent disks as invalid. + allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(spec.Template.Spec.Volumes, fldPath.Child("template", "spec", "volumes"))...) + // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). + if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways { + allErrs = append(allErrs, field.NotSupported(fldPath.Child("template", "spec", "restartPolicy"), spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) + } + if spec.Template.Spec.ActiveDeadlineSeconds != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "spec", "activeDeadlineSeconds"), spec.Template.Spec.ActiveDeadlineSeconds, "must not be specified")) + } + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.TemplateGeneration), fldPath.Child("templateGeneration"))...) + + allErrs = append(allErrs, ValidateDaemonSetUpdateStrategy(&spec.UpdateStrategy, fldPath.Child("updateStrategy"))...) + if spec.RevisionHistoryLimit != nil { + // zero is a valid RevisionHistoryLimit + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.RevisionHistoryLimit), fldPath.Child("revisionHistoryLimit"))...) + } + return allErrs +} + +func ValidateRollingUpdateDaemonSet(rollingUpdate *apps.RollingUpdateDaemonSet, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) + if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 { + // MaxUnavailable cannot be 0. + allErrs = append(allErrs, field.Invalid(fldPath.Child("maxUnavailable"), rollingUpdate.MaxUnavailable, "cannot be 0")) + } + // Validate that MaxUnavailable is not more than 100%. + allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) + return allErrs +} + +func ValidateDaemonSetUpdateStrategy(strategy *apps.DaemonSetUpdateStrategy, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + switch strategy.Type { + case apps.OnDeleteDaemonSetStrategyType: + case apps.RollingUpdateDaemonSetStrategyType: + // Make sure RollingUpdate field isn't nil. + if strategy.RollingUpdate == nil { + allErrs = append(allErrs, field.Required(fldPath.Child("rollingUpdate"), "")) + return allErrs + } + allErrs = append(allErrs, ValidateRollingUpdateDaemonSet(strategy.RollingUpdate, fldPath.Child("rollingUpdate"))...) + default: + validValues := []string{string(apps.RollingUpdateDaemonSetStrategyType), string(apps.OnDeleteDaemonSetStrategyType)} + allErrs = append(allErrs, field.NotSupported(fldPath, strategy, validValues)) + } + return allErrs +} + +// ValidateDaemonSetName can be used to check whether the given daemon set name is valid. +// Prefix indicates this name will be used as part of generation, in which case +// trailing dashes are allowed. +var ValidateDaemonSetName = apimachineryvalidation.NameIsDNSSubdomain + +// Validates that the given name can be used as a deployment name. +var ValidateDeploymentName = apimachineryvalidation.NameIsDNSSubdomain + +func ValidatePositiveIntOrPercent(intOrPercent intstr.IntOrString, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + switch intOrPercent.Type { + case intstr.String: + for _, msg := range validation.IsValidPercent(intOrPercent.StrVal) { + allErrs = append(allErrs, field.Invalid(fldPath, intOrPercent, msg)) + } + case intstr.Int: + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(intOrPercent.IntValue()), fldPath)...) + default: + allErrs = append(allErrs, field.Invalid(fldPath, intOrPercent, "must be an integer or percentage (e.g '5%%')")) + } + return allErrs +} + +func getPercentValue(intOrStringValue intstr.IntOrString) (int, bool) { + if intOrStringValue.Type != intstr.String { + return 0, false + } + if len(validation.IsValidPercent(intOrStringValue.StrVal)) != 0 { + return 0, false + } + value, _ := strconv.Atoi(intOrStringValue.StrVal[:len(intOrStringValue.StrVal)-1]) + return value, true +} + +func getIntOrPercentValue(intOrStringValue intstr.IntOrString) int { + value, isPercent := getPercentValue(intOrStringValue) + if isPercent { + return value + } + return intOrStringValue.IntValue() +} + +func IsNotMoreThan100Percent(intOrStringValue intstr.IntOrString, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + value, isPercent := getPercentValue(intOrStringValue) + if !isPercent || value <= 100 { + return nil + } + allErrs = append(allErrs, field.Invalid(fldPath, intOrStringValue, "must not be greater than 100%")) + return allErrs +} + +func ValidateRollingUpdateDeployment(rollingUpdate *apps.RollingUpdateDeployment, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) + allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxSurge, fldPath.Child("maxSurge"))...) + if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 && getIntOrPercentValue(rollingUpdate.MaxSurge) == 0 { + // Both MaxSurge and MaxUnavailable cannot be zero. + allErrs = append(allErrs, field.Invalid(fldPath.Child("maxUnavailable"), rollingUpdate.MaxUnavailable, "may not be 0 when `maxSurge` is 0")) + } + // Validate that MaxUnavailable is not more than 100%. + allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) + return allErrs +} + +func ValidateDeploymentStrategy(strategy *apps.DeploymentStrategy, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + switch strategy.Type { + case apps.RecreateDeploymentStrategyType: + if strategy.RollingUpdate != nil { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("rollingUpdate"), "may not be specified when strategy `type` is '"+string(apps.RecreateDeploymentStrategyType+"'"))) + } + case apps.RollingUpdateDeploymentStrategyType: + // This should never happen since it's set and checked in defaults.go + if strategy.RollingUpdate == nil { + allErrs = append(allErrs, field.Required(fldPath.Child("rollingUpdate"), "this should be defaulted and never be nil")) + } else { + allErrs = append(allErrs, ValidateRollingUpdateDeployment(strategy.RollingUpdate, fldPath.Child("rollingUpdate"))...) + } + default: + validValues := []string{string(apps.RecreateDeploymentStrategyType), string(apps.RollingUpdateDeploymentStrategyType)} + allErrs = append(allErrs, field.NotSupported(fldPath, strategy, validValues)) + } + return allErrs +} + +func ValidateRollback(rollback *apps.RollbackConfig, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + v := rollback.Revision + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(v), fldPath.Child("version"))...) + return allErrs +} + +// Validates given deployment spec. +func ValidateDeploymentSpec(spec *apps.DeploymentSpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) + + if spec.Selector == nil { + allErrs = append(allErrs, field.Required(fldPath.Child("selector"), "")) + } else { + allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) + if len(spec.Selector.MatchLabels)+len(spec.Selector.MatchExpressions) == 0 { + allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "empty selector is invalid for deployment")) + } + } + + selector, err := metav1.LabelSelectorAsSelector(spec.Selector) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector")) + } else { + allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"))...) + } + + allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, fldPath.Child("strategy"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) + if spec.RevisionHistoryLimit != nil { + // zero is a valid RevisionHistoryLimit + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.RevisionHistoryLimit), fldPath.Child("revisionHistoryLimit"))...) + } + if spec.RollbackTo != nil { + allErrs = append(allErrs, ValidateRollback(spec.RollbackTo, fldPath.Child("rollback"))...) + } + if spec.ProgressDeadlineSeconds != nil { + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.ProgressDeadlineSeconds), fldPath.Child("progressDeadlineSeconds"))...) + if *spec.ProgressDeadlineSeconds <= spec.MinReadySeconds { + allErrs = append(allErrs, field.Invalid(fldPath.Child("progressDeadlineSeconds"), spec.ProgressDeadlineSeconds, "must be greater than minReadySeconds")) + } + } + return allErrs +} + +// Validates given deployment status. +func ValidateDeploymentStatus(status *apps.DeploymentStatus, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(status.ObservedGeneration, fldPath.Child("observedGeneration"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Replicas), fldPath.Child("replicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UpdatedReplicas), fldPath.Child("updatedReplicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ReadyReplicas), fldPath.Child("readyReplicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.AvailableReplicas), fldPath.Child("availableReplicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UnavailableReplicas), fldPath.Child("unavailableReplicas"))...) + if status.CollisionCount != nil { + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*status.CollisionCount), fldPath.Child("collisionCount"))...) + } + msg := "cannot be greater than status.replicas" + if status.UpdatedReplicas > status.Replicas { + allErrs = append(allErrs, field.Invalid(fldPath.Child("updatedReplicas"), status.UpdatedReplicas, msg)) + } + if status.ReadyReplicas > status.Replicas { + allErrs = append(allErrs, field.Invalid(fldPath.Child("readyReplicas"), status.ReadyReplicas, msg)) + } + if status.AvailableReplicas > status.Replicas { + allErrs = append(allErrs, field.Invalid(fldPath.Child("availableReplicas"), status.AvailableReplicas, msg)) + } + if status.AvailableReplicas > status.ReadyReplicas { + allErrs = append(allErrs, field.Invalid(fldPath.Child("availableReplicas"), status.AvailableReplicas, "cannot be greater than readyReplicas")) + } + return allErrs +} + +func ValidateDeploymentUpdate(update, old *apps.Deployment) field.ErrorList { + allErrs := apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateDeploymentSpec(&update.Spec, field.NewPath("spec"))...) + return allErrs +} + +func ValidateDeploymentStatusUpdate(update, old *apps.Deployment) field.ErrorList { + allErrs := apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata")) + fldPath := field.NewPath("status") + allErrs = append(allErrs, ValidateDeploymentStatus(&update.Status, fldPath)...) + if apivalidation.IsDecremented(update.Status.CollisionCount, old.Status.CollisionCount) { + value := int32(0) + if update.Status.CollisionCount != nil { + value = *update.Status.CollisionCount + } + allErrs = append(allErrs, field.Invalid(fldPath.Child("collisionCount"), value, "cannot be decremented")) + } + return allErrs +} + +func ValidateDeployment(obj *apps.Deployment) field.ErrorList { + allErrs := apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, ValidateDeploymentName, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateDeploymentSpec(&obj.Spec, field.NewPath("spec"))...) + return allErrs +} + +func ValidateDeploymentRollback(obj *apps.DeploymentRollback) field.ErrorList { + allErrs := apivalidation.ValidateAnnotations(obj.UpdatedAnnotations, field.NewPath("updatedAnnotations")) + if len(obj.Name) == 0 { + allErrs = append(allErrs, field.Required(field.NewPath("name"), "name is required")) + } + allErrs = append(allErrs, ValidateRollback(&obj.RollbackTo, field.NewPath("rollback"))...) + return allErrs +} + +// ValidateReplicaSetName can be used to check whether the given ReplicaSet +// name is valid. +// Prefix indicates this name will be used as part of generation, in which case +// trailing dashes are allowed. +var ValidateReplicaSetName = apimachineryvalidation.NameIsDNSSubdomain + +// ValidateReplicaSet tests if required fields in the ReplicaSet are set. +func ValidateReplicaSet(rs *apps.ReplicaSet) field.ErrorList { + allErrs := apivalidation.ValidateObjectMeta(&rs.ObjectMeta, true, ValidateReplicaSetName, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateReplicaSetSpec(&rs.Spec, field.NewPath("spec"))...) + return allErrs +} + +// ValidateReplicaSetUpdate tests if required fields in the ReplicaSet are set. +func ValidateReplicaSetUpdate(rs, oldRs *apps.ReplicaSet) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&rs.ObjectMeta, &oldRs.ObjectMeta, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateReplicaSetSpec(&rs.Spec, field.NewPath("spec"))...) + return allErrs +} + +// ValidateReplicaSetStatusUpdate tests if required fields in the ReplicaSet are set. +func ValidateReplicaSetStatusUpdate(rs, oldRs *apps.ReplicaSet) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&rs.ObjectMeta, &oldRs.ObjectMeta, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateReplicaSetStatus(rs.Status, field.NewPath("status"))...) + return allErrs +} + +func ValidateReplicaSetStatus(status apps.ReplicaSetStatus, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Replicas), fldPath.Child("replicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.FullyLabeledReplicas), fldPath.Child("fullyLabeledReplicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ReadyReplicas), fldPath.Child("readyReplicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.AvailableReplicas), fldPath.Child("availableReplicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ObservedGeneration), fldPath.Child("observedGeneration"))...) + msg := "cannot be greater than status.replicas" + if status.FullyLabeledReplicas > status.Replicas { + allErrs = append(allErrs, field.Invalid(fldPath.Child("fullyLabeledReplicas"), status.FullyLabeledReplicas, msg)) + } + if status.ReadyReplicas > status.Replicas { + allErrs = append(allErrs, field.Invalid(fldPath.Child("readyReplicas"), status.ReadyReplicas, msg)) + } + if status.AvailableReplicas > status.Replicas { + allErrs = append(allErrs, field.Invalid(fldPath.Child("availableReplicas"), status.AvailableReplicas, msg)) + } + if status.AvailableReplicas > status.ReadyReplicas { + allErrs = append(allErrs, field.Invalid(fldPath.Child("availableReplicas"), status.AvailableReplicas, "cannot be greater than readyReplicas")) + } + return allErrs +} + +// ValidateReplicaSetSpec tests if required fields in the ReplicaSet spec are set. +func ValidateReplicaSetSpec(spec *apps.ReplicaSetSpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) + + if spec.Selector == nil { + allErrs = append(allErrs, field.Required(fldPath.Child("selector"), "")) + } else { + allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) + if len(spec.Selector.MatchLabels)+len(spec.Selector.MatchExpressions) == 0 { + allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "empty selector is invalid for deployment")) + } + } + + selector, err := metav1.LabelSelectorAsSelector(spec.Selector) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector")) + } else { + allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"))...) + } + return allErrs +} + +// Validates the given template and ensures that it is in accordance with the desired selector and replicas. +func ValidatePodTemplateSpecForReplicaSet(template *api.PodTemplateSpec, selector labels.Selector, replicas int32, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + if template == nil { + allErrs = append(allErrs, field.Required(fldPath, "")) + } else { + if !selector.Empty() { + // Verify that the ReplicaSet selector matches the labels in template. + labels := labels.Set(template.Labels) + if !selector.Matches(labels) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("metadata", "labels"), template.Labels, "`selector` does not match template `labels`")) + } + } + allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(template, fldPath)...) + if replicas > 1 { + allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(template.Spec.Volumes, fldPath.Child("spec", "volumes"))...) + } + // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). + if template.Spec.RestartPolicy != api.RestartPolicyAlways { + allErrs = append(allErrs, field.NotSupported(fldPath.Child("spec", "restartPolicy"), template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) + } + if template.Spec.ActiveDeadlineSeconds != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("spec", "activeDeadlineSeconds"), template.Spec.ActiveDeadlineSeconds, "must not be specified")) + } + } + return allErrs +} diff --git a/pkg/apis/apps/validation/validation_test.go b/pkg/apis/apps/validation/validation_test.go index 35b67f018275d..a4c8791f03311 100644 --- a/pkg/apis/apps/validation/validation_test.go +++ b/pkg/apis/apps/validation/validation_test.go @@ -21,8 +21,10 @@ import ( "strings" "testing" + "github.com/davecgh/go-spew/spew" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" @@ -911,3 +913,2022 @@ func TestValidateControllerRevisionUpdate(t *testing.T) { }) } } + +func TestValidateDaemonSetStatusUpdate(t *testing.T) { + type dsUpdateTest struct { + old apps.DaemonSet + update apps.DaemonSet + } + + successCases := []dsUpdateTest{ + { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 1, + DesiredNumberScheduled: 3, + NumberReady: 1, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + }, + } + + for _, successCase := range successCases { + successCase.old.ObjectMeta.ResourceVersion = "1" + successCase.update.ObjectMeta.ResourceVersion = "1" + if errs := ValidateDaemonSetStatusUpdate(&successCase.update, &successCase.old); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + errorCases := map[string]dsUpdateTest{ + "negative values": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: -1, + NumberMisscheduled: -1, + DesiredNumberScheduled: -3, + NumberReady: -1, + ObservedGeneration: -3, + UpdatedNumberScheduled: -1, + NumberAvailable: -1, + NumberUnavailable: -2, + }, + }, + }, + "negative CurrentNumberScheduled": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: -1, + NumberMisscheduled: 1, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + }, + "negative NumberMisscheduled": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: -1, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + }, + "negative DesiredNumberScheduled": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 1, + DesiredNumberScheduled: -3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + }, + "negative NumberReady": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 1, + DesiredNumberScheduled: 3, + NumberReady: -1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + }, + "negative ObservedGeneration": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 1, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: -3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + }, + "negative UpdatedNumberScheduled": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 1, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: -1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + }, + "negative NumberAvailable": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 1, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: -1, + NumberUnavailable: 2, + }, + }, + }, + "negative NumberUnavailable": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: 2, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + ResourceVersion: "10", + }, + Status: apps.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 1, + DesiredNumberScheduled: 3, + NumberReady: 1, + ObservedGeneration: 3, + UpdatedNumberScheduled: 1, + NumberAvailable: 1, + NumberUnavailable: -2, + }, + }, + }, + } + + for testName, errorCase := range errorCases { + if errs := ValidateDaemonSetStatusUpdate(&errorCase.update, &errorCase.old); len(errs) == 0 { + t.Errorf("expected failure: %s", testName) + } + } +} + +func TestValidateDaemonSetUpdate(t *testing.T) { + validSelector := map[string]string{"a": "b"} + validSelector2 := map[string]string{"c": "d"} + invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} + + validPodSpecAbc := api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + } + validPodSpecDef := api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + } + validPodSpecNodeSelector := api.PodSpec{ + NodeSelector: validSelector, + NodeName: "xyz", + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + } + validPodSpecVolume := api.PodSpec{ + Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + } + + validPodTemplateAbc := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + Spec: validPodSpecAbc, + }, + } + validPodTemplateAbcSemanticallyEqual := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + Spec: validPodSpecAbc, + }, + } + validPodTemplateAbcSemanticallyEqual.Template.Spec.ImagePullSecrets = []api.LocalObjectReference{} + validPodTemplateNodeSelector := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + Spec: validPodSpecNodeSelector, + }, + } + validPodTemplateAbc2 := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector2, + }, + Spec: validPodSpecAbc, + }, + } + validPodTemplateDef := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector2, + }, + Spec: validPodSpecDef, + }, + } + invalidPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + Spec: api.PodSpec{ + // no containers specified + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + }, + } + readWriteVolumePodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + Spec: validPodSpecVolume, + }, + } + + type dsUpdateTest struct { + old apps.DaemonSet + update apps.DaemonSet + expectedErrNum int + } + successCases := map[string]dsUpdateTest{ + "no change": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + }, + "change template and selector": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 2, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector2}, + TemplateGeneration: 3, + Template: validPodTemplateAbc2.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + }, + "change template": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 3, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 4, + Template: validPodTemplateNodeSelector.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + }, + "change container image name": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector2}, + TemplateGeneration: 2, + Template: validPodTemplateDef.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + }, + "change update strategy": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 4, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 4, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.RollingUpdateDaemonSetStrategyType, + RollingUpdate: &apps.RollingUpdateDaemonSet{ + MaxUnavailable: intstr.FromInt(1), + }, + }, + }, + }, + }, + "unchanged templateGeneration upon semantically equal template update": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 4, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 4, + Template: validPodTemplateAbcSemanticallyEqual.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.RollingUpdateDaemonSetStrategyType, + RollingUpdate: &apps.RollingUpdateDaemonSet{ + MaxUnavailable: intstr.FromInt(1), + }, + }, + }, + }, + }, + } + for testName, successCase := range successCases { + // ResourceVersion is required for updates. + successCase.old.ObjectMeta.ResourceVersion = "1" + successCase.update.ObjectMeta.ResourceVersion = "2" + // Check test setup + if successCase.expectedErrNum > 0 { + t.Errorf("%q has incorrect test setup with expectedErrNum %d, expected no error", testName, successCase.expectedErrNum) + } + if len(successCase.old.ObjectMeta.ResourceVersion) == 0 || len(successCase.update.ObjectMeta.ResourceVersion) == 0 { + t.Errorf("%q has incorrect test setup with no resource version set", testName) + } + if errs := ValidateDaemonSetUpdate(&successCase.update, &successCase.old); len(errs) != 0 { + t.Errorf("%q expected no error, but got: %v", testName, errs) + } + } + errorCases := map[string]dsUpdateTest{ + "change daemon name": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + expectedErrNum: 1, + }, + "invalid selector": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: invalidSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + expectedErrNum: 1, + }, + "invalid pod": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 2, + Template: invalidPodTemplate.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + expectedErrNum: 1, + }, + "invalid read-write volume": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 2, + Template: readWriteVolumePodTemplate.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + expectedErrNum: 1, + }, + "invalid update strategy": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: "Random", + }, + }, + }, + expectedErrNum: 1, + }, + "negative templateGeneration": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: -1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: -1, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + expectedErrNum: 1, + }, + "decreased templateGeneration": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + TemplateGeneration: 2, + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + TemplateGeneration: 1, + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + expectedErrNum: 1, + }, + "unchanged templateGeneration upon template update": { + old: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + TemplateGeneration: 2, + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplateAbc.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: apps.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + TemplateGeneration: 2, + Selector: &metav1.LabelSelector{MatchLabels: validSelector2}, + Template: validPodTemplateAbc2.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + expectedErrNum: 1, + }, + } + for testName, errorCase := range errorCases { + // ResourceVersion is required for updates. + errorCase.old.ObjectMeta.ResourceVersion = "1" + errorCase.update.ObjectMeta.ResourceVersion = "2" + // Check test setup + if errorCase.expectedErrNum <= 0 { + t.Errorf("%q has incorrect test setup with expectedErrNum %d, expected at least one error", testName, errorCase.expectedErrNum) + } + if len(errorCase.old.ObjectMeta.ResourceVersion) == 0 || len(errorCase.update.ObjectMeta.ResourceVersion) == 0 { + t.Errorf("%q has incorrect test setup with no resource version set", testName) + } + // Run the tests + if errs := ValidateDaemonSetUpdate(&errorCase.update, &errorCase.old); len(errs) != errorCase.expectedErrNum { + t.Errorf("%q expected %d errors, but got %d error: %v", testName, errorCase.expectedErrNum, len(errs), errs) + } else { + t.Logf("(PASS) %q got errors %v", testName, errs) + } + } +} + +func TestValidateDaemonSet(t *testing.T) { + validSelector := map[string]string{"a": "b"} + validPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + }, + } + invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} + invalidPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: invalidSelector, + }, + }, + } + successCases := []apps.DaemonSet{ + { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplate.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplate.Template, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, + }, + }, + }, + } + for _, successCase := range successCases { + if errs := ValidateDaemonSet(&successCase); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := map[string]apps.DaemonSet{ + "zero-length ID": { + ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplate.Template, + }, + }, + "missing-namespace": { + ObjectMeta: metav1.ObjectMeta{Name: "abc-123"}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplate.Template, + }, + }, + "nil selector": { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Template: validPodTemplate.Template, + }, + }, + "empty selector": { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{}, + Template: validPodTemplate.Template, + }, + }, + "selector_doesnt_match": { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, + Template: validPodTemplate.Template, + }, + }, + "invalid template": { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + }, + }, + "invalid_label": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + Labels: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplate.Template, + }, + }, + "invalid_label 2": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + Labels: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + Spec: apps.DaemonSetSpec{ + Template: invalidPodTemplate.Template, + }, + }, + "invalid_annotation": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + Annotations: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: validPodTemplate.Template, + }, + }, + "invalid restart policy 1": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + }, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: api.PodTemplateSpec{ + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyOnFailure, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + }, + }, + }, + "invalid restart policy 2": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + }, + Spec: apps.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + Template: api.PodTemplateSpec{ + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyNever, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + }, + }, + }, + } + for k, v := range errorCases { + errs := ValidateDaemonSet(&v) + if len(errs) == 0 { + t.Errorf("expected failure for %s", k) + } + for i := range errs { + field := errs[i].Field + if !strings.HasPrefix(field, "spec.template.") && + !strings.HasPrefix(field, "spec.updateStrategy") && + field != "metadata.name" && + field != "metadata.namespace" && + field != "spec.selector" && + field != "spec.template" && + field != "GCEPersistentDisk.ReadOnly" && + field != "spec.template.labels" && + field != "metadata.annotations" && + field != "metadata.labels" { + t.Errorf("%s: missing prefix for: %v", k, errs[i]) + } + } + } +} + +func validDeployment() *apps.Deployment { + return &apps.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + }, + Spec: apps.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "abc", + }, + }, + Strategy: apps.DeploymentStrategy{ + Type: apps.RollingUpdateDeploymentStrategyType, + RollingUpdate: &apps.RollingUpdateDeployment{ + MaxSurge: intstr.FromInt(1), + MaxUnavailable: intstr.FromInt(1), + }, + }, + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: "abc", + Namespace: metav1.NamespaceDefault, + Labels: map[string]string{ + "name": "abc", + }, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSDefault, + Containers: []api.Container{ + { + Name: "nginx", + Image: "image", + ImagePullPolicy: api.PullNever, + TerminationMessagePolicy: api.TerminationMessageReadFile, + }, + }, + }, + }, + RollbackTo: &apps.RollbackConfig{ + Revision: 1, + }, + }, + } +} + +func TestValidateDeployment(t *testing.T) { + successCases := []*apps.Deployment{ + validDeployment(), + } + for _, successCase := range successCases { + if errs := ValidateDeployment(successCase); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := map[string]*apps.Deployment{} + errorCases["metadata.name: Required value"] = &apps.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: metav1.NamespaceDefault, + }, + } + // selector should match the labels in pod template. + invalidSelectorDeployment := validDeployment() + invalidSelectorDeployment.Spec.Selector = &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "def", + }, + } + errorCases["`selector` does not match template `labels`"] = invalidSelectorDeployment + + // RestartPolicy should be always. + invalidRestartPolicyDeployment := validDeployment() + invalidRestartPolicyDeployment.Spec.Template.Spec.RestartPolicy = api.RestartPolicyNever + errorCases["Unsupported value: \"Never\""] = invalidRestartPolicyDeployment + + // must have valid strategy type + invalidStrategyDeployment := validDeployment() + invalidStrategyDeployment.Spec.Strategy.Type = apps.DeploymentStrategyType("randomType") + errorCases[`supported values: "Recreate", "RollingUpdate"`] = invalidStrategyDeployment + + // rollingUpdate should be nil for recreate. + invalidRecreateDeployment := validDeployment() + invalidRecreateDeployment.Spec.Strategy = apps.DeploymentStrategy{ + Type: apps.RecreateDeploymentStrategyType, + RollingUpdate: &apps.RollingUpdateDeployment{}, + } + errorCases["may not be specified when strategy `type` is 'Recreate'"] = invalidRecreateDeployment + + // MaxSurge should be in the form of 20%. + invalidMaxSurgeDeployment := validDeployment() + invalidMaxSurgeDeployment.Spec.Strategy = apps.DeploymentStrategy{ + Type: apps.RollingUpdateDeploymentStrategyType, + RollingUpdate: &apps.RollingUpdateDeployment{ + MaxSurge: intstr.FromString("20Percent"), + }, + } + errorCases["a valid percent string must be"] = invalidMaxSurgeDeployment + + // MaxSurge and MaxUnavailable cannot both be zero. + invalidRollingUpdateDeployment := validDeployment() + invalidRollingUpdateDeployment.Spec.Strategy = apps.DeploymentStrategy{ + Type: apps.RollingUpdateDeploymentStrategyType, + RollingUpdate: &apps.RollingUpdateDeployment{ + MaxSurge: intstr.FromString("0%"), + MaxUnavailable: intstr.FromInt(0), + }, + } + errorCases["may not be 0 when `maxSurge` is 0"] = invalidRollingUpdateDeployment + + // MaxUnavailable should not be more than 100%. + invalidMaxUnavailableDeployment := validDeployment() + invalidMaxUnavailableDeployment.Spec.Strategy = apps.DeploymentStrategy{ + Type: apps.RollingUpdateDeploymentStrategyType, + RollingUpdate: &apps.RollingUpdateDeployment{ + MaxUnavailable: intstr.FromString("110%"), + }, + } + errorCases["must not be greater than 100%"] = invalidMaxUnavailableDeployment + + // Rollback.Revision must be non-negative + invalidRollbackRevisionDeployment := validDeployment() + invalidRollbackRevisionDeployment.Spec.RollbackTo.Revision = -3 + errorCases["must be greater than or equal to 0"] = invalidRollbackRevisionDeployment + + // ProgressDeadlineSeconds should be greater than MinReadySeconds + invalidProgressDeadlineDeployment := validDeployment() + seconds := int32(600) + invalidProgressDeadlineDeployment.Spec.ProgressDeadlineSeconds = &seconds + invalidProgressDeadlineDeployment.Spec.MinReadySeconds = seconds + errorCases["must be greater than minReadySeconds"] = invalidProgressDeadlineDeployment + + for k, v := range errorCases { + errs := ValidateDeployment(v) + if len(errs) == 0 { + t.Errorf("[%s] expected failure", k) + } else if !strings.Contains(errs[0].Error(), k) { + t.Errorf("unexpected error: %q, expected: %q", errs[0].Error(), k) + } + } +} + +func TestValidateDeploymentStatus(t *testing.T) { + collisionCount := int32(-3) + tests := []struct { + name string + + replicas int32 + updatedReplicas int32 + readyReplicas int32 + availableReplicas int32 + observedGeneration int64 + collisionCount *int32 + + expectedErr bool + }{ + { + name: "valid status", + replicas: 3, + updatedReplicas: 3, + readyReplicas: 2, + availableReplicas: 1, + observedGeneration: 2, + expectedErr: false, + }, + { + name: "invalid replicas", + replicas: -1, + updatedReplicas: 2, + readyReplicas: 2, + availableReplicas: 1, + observedGeneration: 2, + expectedErr: true, + }, + { + name: "invalid updatedReplicas", + replicas: 2, + updatedReplicas: -1, + readyReplicas: 2, + availableReplicas: 1, + observedGeneration: 2, + expectedErr: true, + }, + { + name: "invalid readyReplicas", + replicas: 3, + readyReplicas: -1, + availableReplicas: 1, + observedGeneration: 2, + expectedErr: true, + }, + { + name: "invalid availableReplicas", + replicas: 3, + readyReplicas: 3, + availableReplicas: -1, + observedGeneration: 2, + expectedErr: true, + }, + { + name: "invalid observedGeneration", + replicas: 3, + readyReplicas: 3, + availableReplicas: 3, + observedGeneration: -1, + expectedErr: true, + }, + { + name: "updatedReplicas greater than replicas", + replicas: 3, + updatedReplicas: 4, + readyReplicas: 3, + availableReplicas: 3, + observedGeneration: 1, + expectedErr: true, + }, + { + name: "readyReplicas greater than replicas", + replicas: 3, + readyReplicas: 4, + availableReplicas: 3, + observedGeneration: 1, + expectedErr: true, + }, + { + name: "availableReplicas greater than replicas", + replicas: 3, + readyReplicas: 3, + availableReplicas: 4, + observedGeneration: 1, + expectedErr: true, + }, + { + name: "availableReplicas greater than readyReplicas", + replicas: 3, + readyReplicas: 2, + availableReplicas: 3, + observedGeneration: 1, + expectedErr: true, + }, + { + name: "invalid collisionCount", + replicas: 3, + observedGeneration: 1, + collisionCount: &collisionCount, + expectedErr: true, + }, + } + + for _, test := range tests { + status := apps.DeploymentStatus{ + Replicas: test.replicas, + UpdatedReplicas: test.updatedReplicas, + ReadyReplicas: test.readyReplicas, + AvailableReplicas: test.availableReplicas, + ObservedGeneration: test.observedGeneration, + CollisionCount: test.collisionCount, + } + + errs := ValidateDeploymentStatus(&status, field.NewPath("status")) + if hasErr := len(errs) > 0; hasErr != test.expectedErr { + errString := spew.Sprintf("%#v", errs) + t.Errorf("%s: expected error: %t, got error: %t\nerrors: %s", test.name, test.expectedErr, hasErr, errString) + } + } +} + +func TestValidateDeploymentStatusUpdate(t *testing.T) { + collisionCount := int32(1) + otherCollisionCount := int32(2) + tests := []struct { + name string + + from, to apps.DeploymentStatus + + expectedErr bool + }{ + { + name: "increase: valid update", + from: apps.DeploymentStatus{ + CollisionCount: nil, + }, + to: apps.DeploymentStatus{ + CollisionCount: &collisionCount, + }, + expectedErr: false, + }, + { + name: "stable: valid update", + from: apps.DeploymentStatus{ + CollisionCount: &collisionCount, + }, + to: apps.DeploymentStatus{ + CollisionCount: &collisionCount, + }, + expectedErr: false, + }, + { + name: "unset: invalid update", + from: apps.DeploymentStatus{ + CollisionCount: &collisionCount, + }, + to: apps.DeploymentStatus{ + CollisionCount: nil, + }, + expectedErr: true, + }, + { + name: "decrease: invalid update", + from: apps.DeploymentStatus{ + CollisionCount: &otherCollisionCount, + }, + to: apps.DeploymentStatus{ + CollisionCount: &collisionCount, + }, + expectedErr: true, + }, + } + + for _, test := range tests { + meta := metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault, ResourceVersion: "1"} + from := &apps.Deployment{ + ObjectMeta: meta, + Status: test.from, + } + to := &apps.Deployment{ + ObjectMeta: meta, + Status: test.to, + } + + errs := ValidateDeploymentStatusUpdate(to, from) + if hasErr := len(errs) > 0; hasErr != test.expectedErr { + errString := spew.Sprintf("%#v", errs) + t.Errorf("%s: expected error: %t, got error: %t\nerrors: %s", test.name, test.expectedErr, hasErr, errString) + } + } +} + +func validDeploymentRollback() *apps.DeploymentRollback { + return &apps.DeploymentRollback{ + Name: "abc", + UpdatedAnnotations: map[string]string{ + "created-by": "abc", + }, + RollbackTo: apps.RollbackConfig{ + Revision: 1, + }, + } +} + +func TestValidateDeploymentRollback(t *testing.T) { + noAnnotation := validDeploymentRollback() + noAnnotation.UpdatedAnnotations = nil + successCases := []*apps.DeploymentRollback{ + validDeploymentRollback(), + noAnnotation, + } + for _, successCase := range successCases { + if errs := ValidateDeploymentRollback(successCase); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := map[string]*apps.DeploymentRollback{} + invalidNoName := validDeploymentRollback() + invalidNoName.Name = "" + errorCases["name: Required value"] = invalidNoName + + for k, v := range errorCases { + errs := ValidateDeploymentRollback(v) + if len(errs) == 0 { + t.Errorf("[%s] expected failure", k) + } else if !strings.Contains(errs[0].Error(), k) { + t.Errorf("unexpected error: %q, expected: %q", errs[0].Error(), k) + } + } +} + +func TestValidateReplicaSetStatus(t *testing.T) { + tests := []struct { + name string + + replicas int32 + fullyLabeledReplicas int32 + readyReplicas int32 + availableReplicas int32 + observedGeneration int64 + + expectedErr bool + }{ + { + name: "valid status", + replicas: 3, + fullyLabeledReplicas: 3, + readyReplicas: 2, + availableReplicas: 1, + observedGeneration: 2, + expectedErr: false, + }, + { + name: "invalid replicas", + replicas: -1, + fullyLabeledReplicas: 3, + readyReplicas: 2, + availableReplicas: 1, + observedGeneration: 2, + expectedErr: true, + }, + { + name: "invalid fullyLabeledReplicas", + replicas: 3, + fullyLabeledReplicas: -1, + readyReplicas: 2, + availableReplicas: 1, + observedGeneration: 2, + expectedErr: true, + }, + { + name: "invalid readyReplicas", + replicas: 3, + fullyLabeledReplicas: 3, + readyReplicas: -1, + availableReplicas: 1, + observedGeneration: 2, + expectedErr: true, + }, + { + name: "invalid availableReplicas", + replicas: 3, + fullyLabeledReplicas: 3, + readyReplicas: 3, + availableReplicas: -1, + observedGeneration: 2, + expectedErr: true, + }, + { + name: "invalid observedGeneration", + replicas: 3, + fullyLabeledReplicas: 3, + readyReplicas: 3, + availableReplicas: 3, + observedGeneration: -1, + expectedErr: true, + }, + { + name: "fullyLabeledReplicas greater than replicas", + replicas: 3, + fullyLabeledReplicas: 4, + readyReplicas: 3, + availableReplicas: 3, + observedGeneration: 1, + expectedErr: true, + }, + { + name: "readyReplicas greater than replicas", + replicas: 3, + fullyLabeledReplicas: 3, + readyReplicas: 4, + availableReplicas: 3, + observedGeneration: 1, + expectedErr: true, + }, + { + name: "availableReplicas greater than replicas", + replicas: 3, + fullyLabeledReplicas: 3, + readyReplicas: 3, + availableReplicas: 4, + observedGeneration: 1, + expectedErr: true, + }, + { + name: "availableReplicas greater than readyReplicas", + replicas: 3, + fullyLabeledReplicas: 3, + readyReplicas: 2, + availableReplicas: 3, + observedGeneration: 1, + expectedErr: true, + }, + } + + for _, test := range tests { + status := apps.ReplicaSetStatus{ + Replicas: test.replicas, + FullyLabeledReplicas: test.fullyLabeledReplicas, + ReadyReplicas: test.readyReplicas, + AvailableReplicas: test.availableReplicas, + ObservedGeneration: test.observedGeneration, + } + + if hasErr := len(ValidateReplicaSetStatus(status, field.NewPath("status"))) > 0; hasErr != test.expectedErr { + t.Errorf("%s: expected error: %t, got error: %t", test.name, test.expectedErr, hasErr) + } + } +} + +func TestValidateReplicaSetStatusUpdate(t *testing.T) { + validLabels := map[string]string{"a": "b"} + validPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validLabels, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + }, + } + type rcUpdateTest struct { + old apps.ReplicaSet + update apps.ReplicaSet + } + successCases := []rcUpdateTest{ + { + old: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + Status: apps.ReplicaSetStatus{ + Replicas: 2, + }, + }, + update: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: 3, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + Status: apps.ReplicaSetStatus{ + Replicas: 4, + }, + }, + }, + } + for _, successCase := range successCases { + successCase.old.ObjectMeta.ResourceVersion = "1" + successCase.update.ObjectMeta.ResourceVersion = "1" + if errs := ValidateReplicaSetStatusUpdate(&successCase.update, &successCase.old); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + errorCases := map[string]rcUpdateTest{ + "negative replicas": { + old: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + Status: apps.ReplicaSetStatus{ + Replicas: 3, + }, + }, + update: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: 2, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + Status: apps.ReplicaSetStatus{ + Replicas: -3, + }, + }, + }, + } + for testName, errorCase := range errorCases { + if errs := ValidateReplicaSetStatusUpdate(&errorCase.update, &errorCase.old); len(errs) == 0 { + t.Errorf("expected failure: %s", testName) + } + } + +} + +func TestValidateReplicaSetUpdate(t *testing.T) { + validLabels := map[string]string{"a": "b"} + validPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validLabels, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + }, + } + readWriteVolumePodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validLabels, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, + }, + }, + } + invalidLabels := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} + invalidPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: invalidLabels, + }, + }, + } + type rcUpdateTest struct { + old apps.ReplicaSet + update apps.ReplicaSet + } + successCases := []rcUpdateTest{ + { + old: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + update: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: 3, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + }, + { + old: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + update: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: 1, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: readWriteVolumePodTemplate.Template, + }, + }, + }, + } + for _, successCase := range successCases { + successCase.old.ObjectMeta.ResourceVersion = "1" + successCase.update.ObjectMeta.ResourceVersion = "1" + if errs := ValidateReplicaSetUpdate(&successCase.update, &successCase.old); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + errorCases := map[string]rcUpdateTest{ + "more than one read/write": { + old: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + update: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: 2, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: readWriteVolumePodTemplate.Template, + }, + }, + }, + "invalid selector": { + old: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + update: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: 2, + Selector: &metav1.LabelSelector{MatchLabels: invalidLabels}, + Template: validPodTemplate.Template, + }, + }, + }, + "invalid pod": { + old: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + update: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: 2, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: invalidPodTemplate.Template, + }, + }, + }, + "negative replicas": { + old: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + update: apps.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: -1, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + }, + } + for testName, errorCase := range errorCases { + if errs := ValidateReplicaSetUpdate(&errorCase.update, &errorCase.old); len(errs) == 0 { + t.Errorf("expected failure: %s", testName) + } + } +} + +func TestValidateReplicaSet(t *testing.T) { + validLabels := map[string]string{"a": "b"} + validPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validLabels, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + }, + } + readWriteVolumePodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validLabels, + }, + Spec: api.PodSpec{ + Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + }, + } + invalidLabels := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} + invalidPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: invalidLabels, + }, + }, + } + successCases := []apps.ReplicaSet{ + { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: 1, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: readWriteVolumePodTemplate.Template, + }, + }, + } + for _, successCase := range successCases { + if errs := ValidateReplicaSet(&successCase); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := map[string]apps.ReplicaSet{ + "zero-length ID": { + ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + "missing-namespace": { + ObjectMeta: metav1.ObjectMeta{Name: "abc-123"}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + "empty selector": { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Template: validPodTemplate.Template, + }, + }, + "selector_doesnt_match": { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, + Template: validPodTemplate.Template, + }, + }, + "invalid manifest": { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + }, + }, + "read-write persistent disk with > 1 pod": { + ObjectMeta: metav1.ObjectMeta{Name: "abc"}, + Spec: apps.ReplicaSetSpec{ + Replicas: 2, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: readWriteVolumePodTemplate.Template, + }, + }, + "negative_replicas": { + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: apps.ReplicaSetSpec{ + Replicas: -1, + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + }, + }, + "invalid_label": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + Labels: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + "invalid_label 2": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + Labels: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + Spec: apps.ReplicaSetSpec{ + Template: invalidPodTemplate.Template, + }, + }, + "invalid_annotation": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + Annotations: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: validPodTemplate.Template, + }, + }, + "invalid restart policy 1": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + }, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: api.PodTemplateSpec{ + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyOnFailure, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: validLabels, + }, + }, + }, + }, + "invalid restart policy 2": { + ObjectMeta: metav1.ObjectMeta{ + Name: "abc-123", + Namespace: metav1.NamespaceDefault, + }, + Spec: apps.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validLabels}, + Template: api.PodTemplateSpec{ + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyNever, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: validLabels, + }, + }, + }, + }, + } + for k, v := range errorCases { + errs := ValidateReplicaSet(&v) + if len(errs) == 0 { + t.Errorf("expected failure for %s", k) + } + for i := range errs { + field := errs[i].Field + if !strings.HasPrefix(field, "spec.template.") && + field != "metadata.name" && + field != "metadata.namespace" && + field != "spec.selector" && + field != "spec.template" && + field != "GCEPersistentDisk.ReadOnly" && + field != "spec.replicas" && + field != "spec.template.labels" && + field != "metadata.annotations" && + field != "metadata.labels" && + field != "status.replicas" { + t.Errorf("%s: missing prefix for: %v", k, errs[i]) + } + } + } +} diff --git a/pkg/apis/apps/zz_generated.deepcopy.go b/pkg/apis/apps/zz_generated.deepcopy.go index ac64c5c12e6e4..4b4e0e6634f7c 100644 --- a/pkg/apis/apps/zz_generated.deepcopy.go +++ b/pkg/apis/apps/zz_generated.deepcopy.go @@ -88,6 +88,534 @@ func (in *ControllerRevisionList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DaemonSet) DeepCopyInto(out *DaemonSet) { + *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 DaemonSet. +func (in *DaemonSet) DeepCopy() *DaemonSet { + if in == nil { + return nil + } + out := new(DaemonSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DaemonSet) 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 *DaemonSetCondition) DeepCopyInto(out *DaemonSetCondition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetCondition. +func (in *DaemonSetCondition) DeepCopy() *DaemonSetCondition { + if in == nil { + return nil + } + out := new(DaemonSetCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DaemonSetList) DeepCopyInto(out *DaemonSetList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DaemonSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetList. +func (in *DaemonSetList) DeepCopy() *DaemonSetList { + if in == nil { + return nil + } + out := new(DaemonSetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DaemonSetList) 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 *DaemonSetSpec) DeepCopyInto(out *DaemonSetSpec) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + in.Template.DeepCopyInto(&out.Template) + in.UpdateStrategy.DeepCopyInto(&out.UpdateStrategy) + if in.RevisionHistoryLimit != nil { + in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetSpec. +func (in *DaemonSetSpec) DeepCopy() *DaemonSetSpec { + if in == nil { + return nil + } + out := new(DaemonSetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DaemonSetStatus) DeepCopyInto(out *DaemonSetStatus) { + *out = *in + if in.CollisionCount != nil { + in, out := &in.CollisionCount, &out.CollisionCount + *out = new(int32) + **out = **in + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]DaemonSetCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetStatus. +func (in *DaemonSetStatus) DeepCopy() *DaemonSetStatus { + if in == nil { + return nil + } + out := new(DaemonSetStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DaemonSetUpdateStrategy) DeepCopyInto(out *DaemonSetUpdateStrategy) { + *out = *in + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(RollingUpdateDaemonSet) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetUpdateStrategy. +func (in *DaemonSetUpdateStrategy) DeepCopy() *DaemonSetUpdateStrategy { + if in == nil { + return nil + } + out := new(DaemonSetUpdateStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Deployment) DeepCopyInto(out *Deployment) { + *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 Deployment. +func (in *Deployment) DeepCopy() *Deployment { + if in == nil { + return nil + } + out := new(Deployment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Deployment) 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 *DeploymentCondition) DeepCopyInto(out *DeploymentCondition) { + *out = *in + in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentCondition. +func (in *DeploymentCondition) DeepCopy() *DeploymentCondition { + if in == nil { + return nil + } + out := new(DeploymentCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentList) DeepCopyInto(out *DeploymentList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Deployment, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentList. +func (in *DeploymentList) DeepCopy() *DeploymentList { + if in == nil { + return nil + } + out := new(DeploymentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DeploymentList) 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 *DeploymentRollback) DeepCopyInto(out *DeploymentRollback) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.UpdatedAnnotations != nil { + in, out := &in.UpdatedAnnotations, &out.UpdatedAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + out.RollbackTo = in.RollbackTo + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentRollback. +func (in *DeploymentRollback) DeepCopy() *DeploymentRollback { + if in == nil { + return nil + } + out := new(DeploymentRollback) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DeploymentRollback) 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 *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + in.Template.DeepCopyInto(&out.Template) + in.Strategy.DeepCopyInto(&out.Strategy) + if in.RevisionHistoryLimit != nil { + in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit + *out = new(int32) + **out = **in + } + if in.RollbackTo != nil { + in, out := &in.RollbackTo, &out.RollbackTo + *out = new(RollbackConfig) + **out = **in + } + if in.ProgressDeadlineSeconds != nil { + in, out := &in.ProgressDeadlineSeconds, &out.ProgressDeadlineSeconds + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentSpec. +func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { + if in == nil { + return nil + } + out := new(DeploymentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]DeploymentCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CollisionCount != nil { + in, out := &in.CollisionCount, &out.CollisionCount + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatus. +func (in *DeploymentStatus) DeepCopy() *DeploymentStatus { + if in == nil { + return nil + } + out := new(DeploymentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentStrategy) DeepCopyInto(out *DeploymentStrategy) { + *out = *in + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(RollingUpdateDeployment) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStrategy. +func (in *DeploymentStrategy) DeepCopy() *DeploymentStrategy { + if in == nil { + return nil + } + out := new(DeploymentStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplicaSet) DeepCopyInto(out *ReplicaSet) { + *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 ReplicaSet. +func (in *ReplicaSet) DeepCopy() *ReplicaSet { + if in == nil { + return nil + } + out := new(ReplicaSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ReplicaSet) 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 *ReplicaSetCondition) DeepCopyInto(out *ReplicaSetCondition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetCondition. +func (in *ReplicaSetCondition) DeepCopy() *ReplicaSetCondition { + if in == nil { + return nil + } + out := new(ReplicaSetCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplicaSetList) DeepCopyInto(out *ReplicaSetList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ReplicaSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetList. +func (in *ReplicaSetList) DeepCopy() *ReplicaSetList { + if in == nil { + return nil + } + out := new(ReplicaSetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ReplicaSetList) 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 *ReplicaSetSpec) DeepCopyInto(out *ReplicaSetSpec) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + in.Template.DeepCopyInto(&out.Template) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetSpec. +func (in *ReplicaSetSpec) DeepCopy() *ReplicaSetSpec { + if in == nil { + return nil + } + out := new(ReplicaSetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplicaSetStatus) DeepCopyInto(out *ReplicaSetStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]ReplicaSetCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetStatus. +func (in *ReplicaSetStatus) DeepCopy() *ReplicaSetStatus { + if in == nil { + return nil + } + out := new(ReplicaSetStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RollbackConfig) DeepCopyInto(out *RollbackConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollbackConfig. +func (in *RollbackConfig) DeepCopy() *RollbackConfig { + if in == nil { + return nil + } + out := new(RollbackConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RollingUpdateDaemonSet) DeepCopyInto(out *RollingUpdateDaemonSet) { + *out = *in + out.MaxUnavailable = in.MaxUnavailable + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdateDaemonSet. +func (in *RollingUpdateDaemonSet) DeepCopy() *RollingUpdateDaemonSet { + if in == nil { + return nil + } + out := new(RollingUpdateDaemonSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RollingUpdateDeployment) DeepCopyInto(out *RollingUpdateDeployment) { + *out = *in + out.MaxUnavailable = in.MaxUnavailable + out.MaxSurge = in.MaxSurge + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdateDeployment. +func (in *RollingUpdateDeployment) DeepCopy() *RollingUpdateDeployment { + if in == nil { + return nil + } + out := new(RollingUpdateDeployment) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RollingUpdateStatefulSetStrategy) DeepCopyInto(out *RollingUpdateStatefulSetStrategy) { *out = *in diff --git a/pkg/apis/auditregistration/types.go b/pkg/apis/auditregistration/types.go index bc6ede7c3d6e4..5ae4aa51336e0 100644 --- a/pkg/apis/auditregistration/types.go +++ b/pkg/apis/auditregistration/types.go @@ -135,7 +135,7 @@ type WebhookThrottleConfig struct { // WebhookClientConfig contains the information to make a connection with the webhook type WebhookClientConfig struct { // `url` gives the location of the webhook, in standard URL form - // (`[scheme://]host:port/path`). Exactly one of `url` or `service` + // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // // The `host` should not refer to a service running in the cluster; use diff --git a/pkg/apis/auditregistration/validation/BUILD b/pkg/apis/auditregistration/validation/BUILD index 42e821cf0b718..212861d9225af 100644 --- a/pkg/apis/auditregistration/validation/BUILD +++ b/pkg/apis/auditregistration/validation/BUILD @@ -9,8 +9,8 @@ go_library( "//pkg/apis/auditregistration:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", ], ) diff --git a/pkg/apis/auditregistration/validation/validation.go b/pkg/apis/auditregistration/validation/validation.go index 693a657418189..101b1fd6aa969 100644 --- a/pkg/apis/auditregistration/validation/validation.go +++ b/pkg/apis/auditregistration/validation/validation.go @@ -17,14 +17,12 @@ limitations under the License. package validation import ( - "fmt" - "net/url" "strings" genericvalidation "k8s.io/apimachinery/pkg/api/validation" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/util/webhook" "k8s.io/kubernetes/pkg/apis/auditregistration" ) @@ -49,7 +47,16 @@ func ValidateWebhook(w auditregistration.Webhook, fldPath *field.Path) field.Err if w.Throttle != nil { allErrs = append(allErrs, ValidateWebhookThrottleConfig(w.Throttle, fldPath.Child("throttle"))...) } - allErrs = append(allErrs, ValidateWebhookClientConfig(&w.ClientConfig, fldPath.Child("clientConfig"))...) + + cc := w.ClientConfig + switch { + case (cc.URL == nil) == (cc.Service == nil): + allErrs = append(allErrs, field.Required(fldPath.Child("clientConfig"), "exactly one of url or service is required")) + case cc.URL != nil: + allErrs = append(allErrs, webhook.ValidateWebhookURL(fldPath.Child("clientConfig").Child("url"), *cc.URL, false)...) + case cc.Service != nil: + allErrs = append(allErrs, webhook.ValidateWebhookService(fldPath.Child("clientConfig").Child("service"), cc.Service.Name, cc.Service.Namespace, cc.Service.Path)...) + } return allErrs } @@ -65,90 +72,6 @@ func ValidateWebhookThrottleConfig(c *auditregistration.WebhookThrottleConfig, f return allErrs } -// ValidateWebhookClientConfig validates the WebhookClientConfig -// note: this is largely copy/paste inheritance from admissionregistration with subtle changes -func ValidateWebhookClientConfig(cc *auditregistration.WebhookClientConfig, fldPath *field.Path) field.ErrorList { - var allErrors field.ErrorList - if (cc.URL == nil) == (cc.Service == nil) { - allErrors = append(allErrors, field.Required(fldPath.Child("url"), "exactly one of url or service is required")) - } - - if cc.URL != nil { - const form = "; desired format: https://host[/path]" - if u, err := url.Parse(*cc.URL); err != nil { - allErrors = append(allErrors, field.Required(fldPath.Child("url"), "url must be a valid URL: "+err.Error()+form)) - } else { - if len(u.Host) == 0 { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.Host, "host must be provided"+form)) - } - if u.User != nil { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.User.String(), "user information is not permitted in the URL")) - } - if len(u.Fragment) != 0 { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.Fragment, "fragments are not permitted in the URL")) - } - if len(u.RawQuery) != 0 { - allErrors = append(allErrors, field.Invalid(fldPath.Child("url"), u.RawQuery, "query parameters are not permitted in the URL")) - } - } - } - - if cc.Service != nil { - allErrors = append(allErrors, validateWebhookService(cc.Service, fldPath.Child("service"))...) - } - return allErrors -} - -// note: this is copy/paste inheritance from admissionregistration -func validateWebhookService(svc *auditregistration.ServiceReference, fldPath *field.Path) field.ErrorList { - var allErrors field.ErrorList - - if len(svc.Name) == 0 { - allErrors = append(allErrors, field.Required(fldPath.Child("name"), "service name is required")) - } - - if len(svc.Namespace) == 0 { - allErrors = append(allErrors, field.Required(fldPath.Child("namespace"), "service namespace is required")) - } - - if svc.Path == nil { - return allErrors - } - - // TODO: replace below with url.Parse + verifying that host is empty? - - urlPath := *svc.Path - if urlPath == "/" || len(urlPath) == 0 { - return allErrors - } - if urlPath == "//" { - allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, "segment[0] may not be empty")) - return allErrors - } - - if !strings.HasPrefix(urlPath, "/") { - allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, "must start with a '/'")) - } - - urlPathToCheck := urlPath[1:] - if strings.HasSuffix(urlPathToCheck, "/") { - urlPathToCheck = urlPathToCheck[:len(urlPathToCheck)-1] - } - steps := strings.Split(urlPathToCheck, "/") - for i, step := range steps { - if len(step) == 0 { - allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, fmt.Sprintf("segment[%d] may not be empty", i))) - continue - } - failures := validation.IsDNS1123Subdomain(step) - for _, failure := range failures { - allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, fmt.Sprintf("segment[%d]: %v", i, failure))) - } - } - - return allErrors -} - // ValidatePolicy validates the audit policy func ValidatePolicy(policy auditregistration.Policy, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList diff --git a/pkg/apis/auditregistration/validation/validation_test.go b/pkg/apis/auditregistration/validation/validation_test.go index 522fb246ce824..96c6a882c5d6d 100644 --- a/pkg/apis/auditregistration/validation/validation_test.go +++ b/pkg/apis/auditregistration/validation/validation_test.go @@ -159,7 +159,7 @@ func TestValidateWebhookConfiguration(t *testing.T) { URL: strPtr("example.com/k8s/webhook"), }, }, - expectedError: `webhook.clientConfig.url: Required value: exactly one of url or service is required`, + expectedError: `webhook.clientConfig: Required value: exactly one of url or service is required`, }, { name: "blank URL", diff --git a/pkg/apis/authentication/OWNERS b/pkg/apis/authentication/OWNERS index 2bdfd0ce5bc59..3b7ea1b131f25 100755 --- a/pkg/apis/authentication/OWNERS +++ b/pkg/apis/authentication/OWNERS @@ -1,9 +1,7 @@ +# approval on api packages bubbles to api-approvers reviewers: -- liggitt -- lavalamp -- wojtek-t -- deads2k -- sttts -- mbohlool -- jianhuiz -- enj +- sig-auth-authenticators-approvers +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/pkg/apis/authorization/OWNERS b/pkg/apis/authorization/OWNERS index c1613fc2e0263..ff4a7f4bf9ad0 100755 --- a/pkg/apis/authorization/OWNERS +++ b/pkg/apis/authorization/OWNERS @@ -1,17 +1,7 @@ +# approval on api packages bubbles to api-approvers reviewers: -- thockin -- lavalamp -- smarterclayton -- wojtek-t -- deads2k -- liggitt -- nikhiljindal -- erictune -- sttts -- ncdc -- dims -- mml -- mbohlool -- david-mcmahon -- jianhuiz -- enj +- sig-auth-authorizers-approvers +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/pkg/apis/certificates/OWNERS b/pkg/apis/certificates/OWNERS index 1d1ab36e75604..796d862bd9c37 100755 --- a/pkg/apis/certificates/OWNERS +++ b/pkg/apis/certificates/OWNERS @@ -1,14 +1,7 @@ +# approval on api packages bubbles to api-approvers reviewers: -- thockin -- lavalamp -- smarterclayton -- deads2k -- caesarxuchao -- liggitt -- sttts -- dims -- errordeveloper -- mbohlool -- david-mcmahon -- jianhuiz -- enj +- sig-auth-certificates-approvers +- sig-auth-certificates-reviewers +labels: +- sig/auth + diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go index b6ea32da4ad8e..7d1f3df6a233a 100644 --- a/pkg/apis/core/types.go +++ b/pkg/apis/core/types.go @@ -26,19 +26,19 @@ import ( const ( // NamespaceDefault means the object is in the default namespace which is applied when not specified by clients - NamespaceDefault string = "default" + NamespaceDefault = "default" // NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces - NamespaceAll string = "" + NamespaceAll = "" // NamespaceNone is the argument for a context when there is no namespace. - NamespaceNone string = "" + NamespaceNone = "" // NamespaceSystem is the system namespace where we place system components. - NamespaceSystem string = "kube-system" + NamespaceSystem = "kube-system" // NamespacePublic is the namespace where we place public info (ConfigMaps) - NamespacePublic string = "kube-public" + NamespacePublic = "kube-public" // NamespaceNodeLease is the namespace where we place node lease objects (used for node heartbeats) - NamespaceNodeLease string = "kube-node-lease" + NamespaceNodeLease = "kube-node-lease" // TerminationMessagePathDefault means the default path to capture the application termination message running in a container - TerminationMessagePathDefault string = "/dev/termination-log" + TerminationMessagePathDefault = "/dev/termination-log" ) // Volume represents a named volume in a pod that may be accessed by any containers in the pod. diff --git a/pkg/apis/core/v1/BUILD b/pkg/apis/core/v1/BUILD index 180f0bad98b7d..16e3e13d8f0fc 100644 --- a/pkg/apis/core/v1/BUILD +++ b/pkg/apis/core/v1/BUILD @@ -13,8 +13,8 @@ go_library( importpath = "k8s.io/kubernetes/pkg/apis/core/v1", visibility = ["//visibility:public"], deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/features:go_default_library", "//pkg/util/parsers:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", @@ -41,11 +41,11 @@ go_test( deps = [ "//pkg/api/legacyscheme:go_default_library", "//pkg/api/testapi:go_default_library", + "//pkg/apis/apps:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/fuzzer:go_default_library", - "//pkg/apis/extensions:go_default_library", + "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", - "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/apitesting/fuzzer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", diff --git a/pkg/apis/core/v1/conversion.go b/pkg/apis/core/v1/conversion.go index bab07f1950c77..926a39789ea96 100644 --- a/pkg/apis/core/v1/conversion.go +++ b/pkg/apis/core/v1/conversion.go @@ -26,8 +26,8 @@ import ( "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" ) func addConversionFuncs(scheme *runtime.Scheme) error { @@ -43,12 +43,12 @@ func addConversionFuncs(scheme *runtime.Scheme) error { Convert_v1_Secret_To_core_Secret, Convert_v1_ServiceSpec_To_core_ServiceSpec, Convert_v1_ResourceList_To_core_ResourceList, - Convert_v1_ReplicationController_To_extensions_ReplicaSet, - Convert_v1_ReplicationControllerSpec_To_extensions_ReplicaSetSpec, - Convert_v1_ReplicationControllerStatus_To_extensions_ReplicaSetStatus, - Convert_extensions_ReplicaSet_To_v1_ReplicationController, - Convert_extensions_ReplicaSetSpec_To_v1_ReplicationControllerSpec, - Convert_extensions_ReplicaSetStatus_To_v1_ReplicationControllerStatus, + Convert_v1_ReplicationController_To_apps_ReplicaSet, + Convert_v1_ReplicationControllerSpec_To_apps_ReplicaSetSpec, + Convert_v1_ReplicationControllerStatus_To_apps_ReplicaSetStatus, + Convert_apps_ReplicaSet_To_v1_ReplicationController, + Convert_apps_ReplicaSetSpec_To_v1_ReplicationControllerSpec, + Convert_apps_ReplicaSetStatus_To_v1_ReplicationControllerStatus, ) if err != nil { return err @@ -120,18 +120,18 @@ func addConversionFuncs(scheme *runtime.Scheme) error { return nil } -func Convert_v1_ReplicationController_To_extensions_ReplicaSet(in *v1.ReplicationController, out *extensions.ReplicaSet, s conversion.Scope) error { +func Convert_v1_ReplicationController_To_apps_ReplicaSet(in *v1.ReplicationController, out *apps.ReplicaSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1_ReplicationControllerSpec_To_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1_ReplicationControllerSpec_To_apps_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1_ReplicationControllerStatus_To_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1_ReplicationControllerStatus_To_apps_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func Convert_v1_ReplicationControllerSpec_To_extensions_ReplicaSetSpec(in *v1.ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error { +func Convert_v1_ReplicationControllerSpec_To_apps_ReplicaSetSpec(in *v1.ReplicationControllerSpec, out *apps.ReplicaSetSpec, s conversion.Scope) error { out.Replicas = *in.Replicas out.MinReadySeconds = in.MinReadySeconds if in.Selector != nil { @@ -146,15 +146,15 @@ func Convert_v1_ReplicationControllerSpec_To_extensions_ReplicaSetSpec(in *v1.Re return nil } -func Convert_v1_ReplicationControllerStatus_To_extensions_ReplicaSetStatus(in *v1.ReplicationControllerStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error { +func Convert_v1_ReplicationControllerStatus_To_apps_ReplicaSetStatus(in *v1.ReplicationControllerStatus, out *apps.ReplicaSetStatus, s conversion.Scope) error { out.Replicas = in.Replicas out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ReadyReplicas = in.ReadyReplicas out.AvailableReplicas = in.AvailableReplicas out.ObservedGeneration = in.ObservedGeneration for _, cond := range in.Conditions { - out.Conditions = append(out.Conditions, extensions.ReplicaSetCondition{ - Type: extensions.ReplicaSetConditionType(cond.Type), + out.Conditions = append(out.Conditions, apps.ReplicaSetCondition{ + Type: apps.ReplicaSetConditionType(cond.Type), Status: core.ConditionStatus(cond.Status), LastTransitionTime: cond.LastTransitionTime, Reason: cond.Reason, @@ -164,9 +164,9 @@ func Convert_v1_ReplicationControllerStatus_To_extensions_ReplicaSetStatus(in *v return nil } -func Convert_extensions_ReplicaSet_To_v1_ReplicationController(in *extensions.ReplicaSet, out *v1.ReplicationController, s conversion.Scope) error { +func Convert_apps_ReplicaSet_To_v1_ReplicationController(in *apps.ReplicaSet, out *v1.ReplicationController, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_ReplicaSetSpec_To_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_ReplicaSetSpec_To_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil { fieldErr, ok := err.(*field.Error) if !ok { return err @@ -176,13 +176,13 @@ func Convert_extensions_ReplicaSet_To_v1_ReplicationController(in *extensions.Re } out.Annotations[v1.NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String() } - if err := Convert_extensions_ReplicaSetStatus_To_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_ReplicaSetStatus_To_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -func Convert_extensions_ReplicaSetSpec_To_v1_ReplicationControllerSpec(in *extensions.ReplicaSetSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error { +func Convert_apps_ReplicaSetSpec_To_v1_ReplicationControllerSpec(in *apps.ReplicaSetSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error { out.Replicas = new(int32) *out.Replicas = in.Replicas out.MinReadySeconds = in.MinReadySeconds @@ -197,7 +197,7 @@ func Convert_extensions_ReplicaSetSpec_To_v1_ReplicationControllerSpec(in *exten return invalidErr } -func Convert_extensions_ReplicaSetStatus_To_v1_ReplicationControllerStatus(in *extensions.ReplicaSetStatus, out *v1.ReplicationControllerStatus, s conversion.Scope) error { +func Convert_apps_ReplicaSetStatus_To_v1_ReplicationControllerStatus(in *apps.ReplicaSetStatus, out *v1.ReplicationControllerStatus, s conversion.Scope) error { out.Replicas = in.Replicas out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ReadyReplicas = in.ReadyReplicas diff --git a/pkg/apis/core/v1/conversion_test.go b/pkg/apis/core/v1/conversion_test.go index 3e82415d80b9c..f05ec14de526c 100644 --- a/pkg/apis/core/v1/conversion_test.go +++ b/pkg/apis/core/v1/conversion_test.go @@ -24,8 +24,8 @@ import ( "testing" "time" + appsv1 "k8s.io/api/apps/v1" "k8s.io/api/core/v1" - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/resource" @@ -34,10 +34,10 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/kubernetes/pkg/api/legacyscheme" + apps "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/core" corefuzzer "k8s.io/kubernetes/pkg/apis/core/fuzzer" corev1 "k8s.io/kubernetes/pkg/apis/core/v1" - "k8s.io/kubernetes/pkg/apis/extensions" utilpointer "k8s.io/utils/pointer" // enforce that all types are installed @@ -305,16 +305,16 @@ func TestReplicationControllerConversion(t *testing.T) { } for _, in := range inputs { - rs := &extensions.ReplicaSet{} + rs := &apps.ReplicaSet{} // Use in.DeepCopy() to avoid sharing pointers with `in`. - if err := corev1.Convert_v1_ReplicationController_To_extensions_ReplicaSet(in.DeepCopy(), rs, nil); err != nil { + if err := corev1.Convert_v1_ReplicationController_To_apps_ReplicaSet(in.DeepCopy(), rs, nil); err != nil { t.Errorf("can't convert RC to RS: %v", err) continue } // Round-trip RS before converting back to RC. rs = roundTripRS(t, rs) out := &v1.ReplicationController{} - if err := corev1.Convert_extensions_ReplicaSet_To_v1_ReplicationController(rs, out, nil); err != nil { + if err := corev1.Convert_apps_ReplicaSet_To_v1_ReplicationController(rs, out, nil); err != nil { t.Errorf("can't convert RS to RC: %v", err) continue } @@ -326,8 +326,8 @@ func TestReplicationControllerConversion(t *testing.T) { } } -func roundTripRS(t *testing.T, rs *extensions.ReplicaSet) *extensions.ReplicaSet { - codec := legacyscheme.Codecs.LegacyCodec(extensionsv1beta1.SchemeGroupVersion) +func roundTripRS(t *testing.T, rs *apps.ReplicaSet) *apps.ReplicaSet { + codec := legacyscheme.Codecs.LegacyCodec(appsv1.SchemeGroupVersion) data, err := runtime.Encode(codec, rs) if err != nil { t.Errorf("%v\n %#v", err, rs) @@ -338,7 +338,7 @@ func roundTripRS(t *testing.T, rs *extensions.ReplicaSet) *extensions.ReplicaSet t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), rs) return nil } - obj3 := &extensions.ReplicaSet{} + obj3 := &apps.ReplicaSet{} err = legacyscheme.Scheme.Convert(obj2, obj3, nil) if err != nil { t.Errorf("%v\nSource: %#v", err, obj2) diff --git a/pkg/apis/core/v1/zz_generated.conversion.go b/pkg/apis/core/v1/zz_generated.conversion.go index 45f9454fd8d20..d56c950d7343f 100644 --- a/pkg/apis/core/v1/zz_generated.conversion.go +++ b/pkg/apis/core/v1/zz_generated.conversion.go @@ -29,8 +29,8 @@ import ( conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" types "k8s.io/apimachinery/pkg/types" + apps "k8s.io/kubernetes/pkg/apis/apps" core "k8s.io/kubernetes/pkg/apis/core" - extensions "k8s.io/kubernetes/pkg/apis/extensions" ) func init() { @@ -1990,6 +1990,21 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*apps.ReplicaSetSpec)(nil), (*v1.ReplicationControllerSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetSpec_To_v1_ReplicationControllerSpec(a.(*apps.ReplicaSetSpec), b.(*v1.ReplicationControllerSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*apps.ReplicaSetStatus)(nil), (*v1.ReplicationControllerStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetStatus_To_v1_ReplicationControllerStatus(a.(*apps.ReplicaSetStatus), b.(*v1.ReplicationControllerStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*apps.ReplicaSet)(nil), (*v1.ReplicationController)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSet_To_v1_ReplicationController(a.(*apps.ReplicaSet), b.(*v1.ReplicationController), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*core.PodSecurityContext)(nil), (*v1.PodSecurityContext)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_core_PodSecurityContext_To_v1_PodSecurityContext(a.(*core.PodSecurityContext), b.(*v1.PodSecurityContext), scope) }); err != nil { @@ -2020,21 +2035,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.ReplicaSetSpec)(nil), (*v1.ReplicationControllerSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetSpec_To_v1_ReplicationControllerSpec(a.(*extensions.ReplicaSetSpec), b.(*v1.ReplicationControllerSpec), scope) - }); err != nil { - return err - } - if err := s.AddConversionFunc((*extensions.ReplicaSetStatus)(nil), (*v1.ReplicationControllerStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetStatus_To_v1_ReplicationControllerStatus(a.(*extensions.ReplicaSetStatus), b.(*v1.ReplicationControllerStatus), scope) - }); err != nil { - return err - } - if err := s.AddConversionFunc((*extensions.ReplicaSet)(nil), (*v1.ReplicationController)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSet_To_v1_ReplicationController(a.(*extensions.ReplicaSet), b.(*v1.ReplicationController), scope) - }); err != nil { - return err - } if err := s.AddConversionFunc((*v1.PodSecurityContext)(nil), (*core.PodSecurityContext)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_PodSecurityContext_To_core_PodSecurityContext(a.(*v1.PodSecurityContext), b.(*core.PodSecurityContext), scope) }); err != nil { @@ -2055,23 +2055,23 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*v1.ReplicationControllerSpec)(nil), (*core.ReplicationControllerSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicationControllerSpec_To_core_ReplicationControllerSpec(a.(*v1.ReplicationControllerSpec), b.(*core.ReplicationControllerSpec), scope) + if err := s.AddConversionFunc((*v1.ReplicationControllerSpec)(nil), (*apps.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicationControllerSpec_To_apps_ReplicaSetSpec(a.(*v1.ReplicationControllerSpec), b.(*apps.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.ReplicationControllerSpec)(nil), (*extensions.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicationControllerSpec_To_extensions_ReplicaSetSpec(a.(*v1.ReplicationControllerSpec), b.(*extensions.ReplicaSetSpec), scope) + if err := s.AddConversionFunc((*v1.ReplicationControllerSpec)(nil), (*core.ReplicationControllerSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicationControllerSpec_To_core_ReplicationControllerSpec(a.(*v1.ReplicationControllerSpec), b.(*core.ReplicationControllerSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.ReplicationControllerStatus)(nil), (*extensions.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicationControllerStatus_To_extensions_ReplicaSetStatus(a.(*v1.ReplicationControllerStatus), b.(*extensions.ReplicaSetStatus), scope) + if err := s.AddConversionFunc((*v1.ReplicationControllerStatus)(nil), (*apps.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicationControllerStatus_To_apps_ReplicaSetStatus(a.(*v1.ReplicationControllerStatus), b.(*apps.ReplicaSetStatus), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1.ReplicationController)(nil), (*extensions.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ReplicationController_To_extensions_ReplicaSet(a.(*v1.ReplicationController), b.(*extensions.ReplicaSet), scope) + if err := s.AddConversionFunc((*v1.ReplicationController)(nil), (*apps.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ReplicationController_To_apps_ReplicaSet(a.(*v1.ReplicationController), b.(*apps.ReplicaSet), scope) }); err != nil { return err } diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index 1f26f3e1df3c2..7af94bd42f76d 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -1115,10 +1115,6 @@ func validateMountPropagation(mountPropagation *core.MountPropagationMode, conta if mountPropagation == nil { return allErrs } - if !utilfeature.DefaultFeatureGate.Enabled(features.MountPropagation) { - allErrs = append(allErrs, field.Forbidden(fldPath, "mount propagation is disabled by feature-gate")) - return allErrs - } supportedMountPropagations := sets.NewString(string(core.MountPropagationBidirectional), string(core.MountPropagationHostToContainer), string(core.MountPropagationNone)) if !supportedMountPropagations.Has(string(*mountPropagation)) { diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index 858b6e0a1c483..0ec84db586216 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -1750,7 +1750,7 @@ func TestValidateGlusterfs(t *testing.T) { errfield: "path", }, { - name: "missing endpintname and path", + name: "missing endpointname and path", gfs: &core.GlusterfsVolumeSource{EndpointsName: "", Path: ""}, errtype: field.ErrorTypeRequired, errfield: "endpoints", @@ -5038,26 +5038,6 @@ func TestValidateMountPropagation(t *testing.T) { }, } - // Enable MountPropagation for this test - priorityEnabled := utilfeature.DefaultFeatureGate.Enabled("MountPropagation") - defer func() { - var err error - // restoring the old value - if priorityEnabled { - err = utilfeature.DefaultFeatureGate.Set("MountPropagation=true") - } else { - err = utilfeature.DefaultFeatureGate.Set("MountPropagation=false") - } - if err != nil { - t.Errorf("Failed to restore feature gate for MountPropagation: %v", err) - } - }() - err := utilfeature.DefaultFeatureGate.Set("MountPropagation=true") - if err != nil { - t.Errorf("Failed to enable feature gate for MountPropagation: %v", err) - return - } - volumes := []core.Volume{ {Name: "foo", VolumeSource: core.VolumeSource{HostPath: &core.HostPathVolumeSource{Path: "/foo/baz", Type: newHostPathType(string(core.HostPathUnset))}}}, } diff --git a/pkg/apis/extensions/BUILD b/pkg/apis/extensions/BUILD index 764a5af867f80..d1d43ed5a1b80 100644 --- a/pkg/apis/extensions/BUILD +++ b/pkg/apis/extensions/BUILD @@ -15,11 +15,11 @@ go_library( ], importpath = "k8s.io/kubernetes/pkg/apis/extensions", deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/networking:go_default_library", "//pkg/apis/policy:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/pkg/apis/extensions/fuzzer/BUILD b/pkg/apis/extensions/fuzzer/BUILD index 20615635d820a..f4cbae281903a 100644 --- a/pkg/apis/extensions/fuzzer/BUILD +++ b/pkg/apis/extensions/fuzzer/BUILD @@ -9,13 +9,7 @@ go_library( name = "go_default_library", srcs = ["fuzzer.go"], importpath = "k8s.io/kubernetes/pkg/apis/extensions/fuzzer", - deps = [ - "//pkg/apis/extensions:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", - "//vendor/github.com/google/gofuzz:go_default_library", - ], + deps = ["//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], ) filegroup( diff --git a/pkg/apis/extensions/fuzzer/fuzzer.go b/pkg/apis/extensions/fuzzer/fuzzer.go index 277a327c9448d..bc16daf1f3534 100644 --- a/pkg/apis/extensions/fuzzer/fuzzer.go +++ b/pkg/apis/extensions/fuzzer/fuzzer.go @@ -17,98 +17,10 @@ limitations under the License. package fuzzer import ( - "fmt" - - fuzz "github.com/google/gofuzz" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/kubernetes/pkg/apis/extensions" ) // Funcs returns the fuzzer functions for the extensions api group. var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(j *extensions.Deployment, c fuzz.Continue) { - c.FuzzNoCustom(j) - - // match defaulting - if j.Spec.Selector == nil { - j.Spec.Selector = &metav1.LabelSelector{MatchLabels: j.Spec.Template.Labels} - } - if len(j.Labels) == 0 { - j.Labels = j.Spec.Template.Labels - } - }, - func(j *extensions.DeploymentSpec, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - rhl := int32(c.Rand.Int31()) - pds := int32(c.Rand.Int31()) - j.RevisionHistoryLimit = &rhl - j.ProgressDeadlineSeconds = &pds - }, - func(j *extensions.DeploymentStrategy, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - // Ensure that strategyType is one of valid values. - strategyTypes := []extensions.DeploymentStrategyType{extensions.RecreateDeploymentStrategyType, extensions.RollingUpdateDeploymentStrategyType} - j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] - if j.Type != extensions.RollingUpdateDeploymentStrategyType { - j.RollingUpdate = nil - } else { - rollingUpdate := extensions.RollingUpdateDeployment{} - if c.RandBool() { - rollingUpdate.MaxUnavailable = intstr.FromInt(int(c.Rand.Int31())) - rollingUpdate.MaxSurge = intstr.FromInt(int(c.Rand.Int31())) - } else { - rollingUpdate.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.Rand.Int31())) - } - j.RollingUpdate = &rollingUpdate - } - }, - func(j *extensions.DaemonSet, c fuzz.Continue) { - c.FuzzNoCustom(j) - - // match defaulter - j.Spec.Template.Generation = 0 - if len(j.ObjectMeta.Labels) == 0 { - j.ObjectMeta.Labels = j.Spec.Template.ObjectMeta.Labels - } - }, - func(j *extensions.DaemonSetSpec, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - rhl := int32(c.Rand.Int31()) - j.RevisionHistoryLimit = &rhl - }, - func(j *extensions.DaemonSetUpdateStrategy, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - // Ensure that strategyType is one of valid values. - strategyTypes := []extensions.DaemonSetUpdateStrategyType{extensions.RollingUpdateDaemonSetStrategyType, extensions.OnDeleteDaemonSetStrategyType} - j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] - if j.Type != extensions.RollingUpdateDaemonSetStrategyType { - j.RollingUpdate = nil - } else { - rollingUpdate := extensions.RollingUpdateDaemonSet{} - if c.RandBool() { - if c.RandBool() { - rollingUpdate.MaxUnavailable = intstr.FromInt(1 + int(c.Rand.Int31())) - } else { - rollingUpdate.MaxUnavailable = intstr.FromString(fmt.Sprintf("%d%%", 1+c.Rand.Int31())) - } - } - j.RollingUpdate = &rollingUpdate - } - }, - func(j *extensions.ReplicaSet, c fuzz.Continue) { - c.FuzzNoCustom(j) - - // match defaulter - if j.Spec.Selector == nil { - j.Spec.Selector = &metav1.LabelSelector{MatchLabels: j.Spec.Template.Labels} - } - if len(j.Labels) == 0 { - j.Labels = j.Spec.Template.Labels - } - }, - } + return []interface{}{} } diff --git a/pkg/apis/extensions/register.go b/pkg/apis/extensions/register.go index 84c2071ae664e..d4644ffaee318 100644 --- a/pkg/apis/extensions/register.go +++ b/pkg/apis/extensions/register.go @@ -19,6 +19,7 @@ package extensions import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/networking" "k8s.io/kubernetes/pkg/apis/policy" @@ -49,16 +50,16 @@ var ( func addKnownTypes(scheme *runtime.Scheme) error { // TODO this gets cleaned up when the types are fixed scheme.AddKnownTypes(SchemeGroupVersion, - &Deployment{}, - &DeploymentList{}, - &DeploymentRollback{}, + &apps.Deployment{}, + &apps.DeploymentList{}, + &apps.DeploymentRollback{}, &ReplicationControllerDummy{}, - &DaemonSetList{}, - &DaemonSet{}, + &apps.DaemonSetList{}, + &apps.DaemonSet{}, &Ingress{}, &IngressList{}, - &ReplicaSet{}, - &ReplicaSetList{}, + &apps.ReplicaSet{}, + &apps.ReplicaSetList{}, &policy.PodSecurityPolicy{}, &policy.PodSecurityPolicyList{}, &autoscaling.Scale{}, diff --git a/pkg/apis/extensions/types.go b/pkg/apis/extensions/types.go index 8ac06701daa8d..20637e74e4607 100644 --- a/pkg/apis/extensions/types.go +++ b/pkg/apis/extensions/types.go @@ -29,7 +29,6 @@ support is experimental. package extensions import ( - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" api "k8s.io/kubernetes/pkg/apis/core" @@ -42,460 +41,6 @@ type ReplicationControllerDummy struct { metav1.TypeMeta } -// Alpha-level support for Custom Metrics in HPA (as annotations). -type CustomMetricTarget struct { - // Custom Metric name. - Name string - // Custom Metric value (average). - TargetValue resource.Quantity -} - -type CustomMetricTargetList struct { - Items []CustomMetricTarget -} - -type CustomMetricCurrentStatus struct { - // Custom Metric name. - Name string - // Custom Metric value (average). - CurrentValue resource.Quantity -} - -type CustomMetricCurrentStatusList struct { - Items []CustomMetricCurrentStatus -} - -// +genclient -// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/autoscaling.Scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -type Deployment struct { - metav1.TypeMeta - // +optional - metav1.ObjectMeta - - // Specification of the desired behavior of the Deployment. - // +optional - Spec DeploymentSpec - - // Most recently observed status of the Deployment. - // +optional - Status DeploymentStatus -} - -type DeploymentSpec struct { - // Number of desired pods. This is a pointer to distinguish between explicit - // zero and not specified. Defaults to 1. - // +optional - Replicas int32 - - // Label selector for pods. Existing ReplicaSets whose pods are - // selected by this will be the ones affected by this deployment. - // +optional - Selector *metav1.LabelSelector - - // Template describes the pods that will be created. - Template api.PodTemplateSpec - - // The deployment strategy to use to replace existing pods with new ones. - // +optional - Strategy DeploymentStrategy - - // Minimum number of seconds for which a newly created pod should be ready - // without any of its container crashing, for it to be considered available. - // Defaults to 0 (pod will be considered available as soon as it is ready) - // +optional - MinReadySeconds int32 - - // The number of old ReplicaSets to retain to allow rollback. - // This is a pointer to distinguish between explicit zero and not specified. - // This is set to the max value of int32 (i.e. 2147483647) by default, which means - // "retaining all old ReplicaSets". - // +optional - RevisionHistoryLimit *int32 - - // Indicates that the deployment is paused and will not be processed by the - // deployment controller. - // +optional - Paused bool - - // DEPRECATED. - // The config this deployment is rolling back to. Will be cleared after rollback is done. - // +optional - RollbackTo *RollbackConfig - - // The maximum time in seconds for a deployment to make progress before it - // is considered to be failed. The deployment controller will continue to - // process failed deployments and a condition with a ProgressDeadlineExceeded - // reason will be surfaced in the deployment status. Note that progress will - // not be estimated during the time a deployment is paused. This is set to - // the max value of int32 (i.e. 2147483647) by default, which means "no deadline". - // +optional - ProgressDeadlineSeconds *int32 -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// DEPRECATED. -// DeploymentRollback stores the information required to rollback a deployment. -type DeploymentRollback struct { - metav1.TypeMeta - // Required: This must match the Name of a deployment. - Name string - // The annotations to be updated to a deployment - // +optional - UpdatedAnnotations map[string]string - // The config of this deployment rollback. - RollbackTo RollbackConfig -} - -// DEPRECATED. -type RollbackConfig struct { - // The revision to rollback to. If set to 0, rollback to the last revision. - // +optional - Revision int64 -} - -const ( - // DefaultDeploymentUniqueLabelKey is the default key of the selector that is added - // to existing RCs (and label key that is added to its pods) to prevent the existing RCs - // to select new pods (and old pods being select by new RC). - DefaultDeploymentUniqueLabelKey string = "pod-template-hash" -) - -type DeploymentStrategy struct { - // Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate. - // +optional - Type DeploymentStrategyType - - // Rolling update config params. Present only if DeploymentStrategyType = - // RollingUpdate. - //--- - // TODO: Update this to follow our convention for oneOf, whatever we decide it - // to be. - // +optional - RollingUpdate *RollingUpdateDeployment -} - -type DeploymentStrategyType string - -const ( - // Kill all existing pods before creating new ones. - RecreateDeploymentStrategyType DeploymentStrategyType = "Recreate" - - // Replace the old RCs by new one using rolling update i.e gradually scale down the old RCs and scale up the new one. - RollingUpdateDeploymentStrategyType DeploymentStrategyType = "RollingUpdate" -) - -// Spec to control the desired behavior of rolling update. -type RollingUpdateDeployment struct { - // The maximum number of pods that can be unavailable during the update. - // Value can be an absolute number (ex: 5) or a percentage of total pods at the start of update (ex: 10%). - // Absolute number is calculated from percentage by rounding down. - // This can not be 0 if MaxSurge is 0. - // By default, a fixed value of 1 is used. - // Example: when this is set to 30%, the old RC can be scaled down by 30% - // immediately when the rolling update starts. Once new pods are ready, old RC - // can be scaled down further, followed by scaling up the new RC, ensuring - // that at least 70% of original number of pods are available at all times - // during the update. - // +optional - MaxUnavailable intstr.IntOrString - - // The maximum number of pods that can be scheduled above the original number of - // pods. - // Value can be an absolute number (ex: 5) or a percentage of total pods at - // the start of the update (ex: 10%). This can not be 0 if MaxUnavailable is 0. - // Absolute number is calculated from percentage by rounding up. - // By default, a value of 1 is used. - // Example: when this is set to 30%, the new RC can be scaled up by 30% - // immediately when the rolling update starts. Once old pods have been killed, - // new RC can be scaled up further, ensuring that total number of pods running - // at any time during the update is atmost 130% of original pods. - // +optional - MaxSurge intstr.IntOrString -} - -type DeploymentStatus struct { - // The generation observed by the deployment controller. - // +optional - ObservedGeneration int64 - - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). - // +optional - Replicas int32 - - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. - // +optional - UpdatedReplicas int32 - - // Total number of ready pods targeted by this deployment. - // +optional - ReadyReplicas int32 - - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. - // +optional - AvailableReplicas int32 - - // Total number of unavailable pods targeted by this deployment. This is the total number of - // pods that are still required for the deployment to have 100% available capacity. They may - // either be pods that are running but not yet available or pods that still have not been created. - // +optional - UnavailableReplicas int32 - - // Represents the latest available observations of a deployment's current state. - Conditions []DeploymentCondition - - // Count of hash collisions for the Deployment. The Deployment controller uses this - // field as a collision avoidance mechanism when it needs to create the name for the - // newest ReplicaSet. - // +optional - CollisionCount *int32 -} - -type DeploymentConditionType string - -// These are valid conditions of a deployment. -const ( - // Available means the deployment is available, ie. at least the minimum available - // replicas required are up and running for at least minReadySeconds. - DeploymentAvailable DeploymentConditionType = "Available" - // Progressing means the deployment is progressing. Progress for a deployment is - // considered when a new replica set is created or adopted, and when new pods scale - // up or old pods scale down. Progress is not estimated for paused deployments or - // when progressDeadlineSeconds is not specified. - DeploymentProgressing DeploymentConditionType = "Progressing" - // ReplicaFailure is added in a deployment when one of its pods fails to be created - // or deleted. - DeploymentReplicaFailure DeploymentConditionType = "ReplicaFailure" -) - -// DeploymentCondition describes the state of a deployment at a certain point. -type DeploymentCondition struct { - // Type of deployment condition. - Type DeploymentConditionType - // Status of the condition, one of True, False, Unknown. - Status api.ConditionStatus - // The last time this condition was updated. - LastUpdateTime metav1.Time - // Last time the condition transitioned from one status to another. - LastTransitionTime metav1.Time - // The reason for the condition's last transition. - Reason string - // A human readable message indicating details about the transition. - Message string -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -type DeploymentList struct { - metav1.TypeMeta - // +optional - metav1.ListMeta - - // Items is the list of deployments. - Items []Deployment -} - -type DaemonSetUpdateStrategy struct { - // Type of daemon set update. Can be "RollingUpdate" or "OnDelete". - // Default is OnDelete. - // +optional - Type DaemonSetUpdateStrategyType - - // Rolling update config params. Present only if type = "RollingUpdate". - //--- - // TODO: Update this to follow our convention for oneOf, whatever we decide it - // to be. Same as Deployment `strategy.rollingUpdate`. - // See https://github.com/kubernetes/kubernetes/issues/35345 - // +optional - RollingUpdate *RollingUpdateDaemonSet -} - -type DaemonSetUpdateStrategyType string - -const ( - // Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other. - RollingUpdateDaemonSetStrategyType DaemonSetUpdateStrategyType = "RollingUpdate" - - // Replace the old daemons only when it's killed - OnDeleteDaemonSetStrategyType DaemonSetUpdateStrategyType = "OnDelete" -) - -// Spec to control the desired behavior of daemon set rolling update. -type RollingUpdateDaemonSet struct { - // The maximum number of DaemonSet pods that can be unavailable during the - // update. Value can be an absolute number (ex: 5) or a percentage of total - // number of DaemonSet pods at the start of the update (ex: 10%). Absolute - // number is calculated from percentage by rounding up. - // This cannot be 0. - // Default value is 1. - // Example: when this is set to 30%, at most 30% of the total number of nodes - // that should be running the daemon pod (i.e. status.desiredNumberScheduled) - // can have their pods stopped for an update at any given - // time. The update starts by stopping at most 30% of those DaemonSet pods - // and then brings up new DaemonSet pods in their place. Once the new pods - // are available, it then proceeds onto other DaemonSet pods, thus ensuring - // that at least 70% of original number of DaemonSet pods are available at - // all times during the update. - // +optional - MaxUnavailable intstr.IntOrString -} - -// DaemonSetSpec is the specification of a daemon set. -type DaemonSetSpec struct { - // A label query over pods that are managed by the daemon set. - // Must match in order to be controlled. - // If empty, defaulted to labels on Pod template. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors - // +optional - Selector *metav1.LabelSelector - - // An object that describes the pod that will be created. - // The DaemonSet will create exactly one copy of this pod on every node - // that matches the template's node selector (or on every node if no node - // selector is specified). - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template - Template api.PodTemplateSpec - - // An update strategy to replace existing DaemonSet pods with new pods. - // +optional - UpdateStrategy DaemonSetUpdateStrategy - - // The minimum number of seconds for which a newly created DaemonSet pod should - // be ready without any of its container crashing, for it to be considered - // available. Defaults to 0 (pod will be considered available as soon as it - // is ready). - // +optional - MinReadySeconds int32 - - // DEPRECATED. - // A sequence number representing a specific generation of the template. - // Populated by the system. It can be set only during the creation. - // +optional - TemplateGeneration int64 - - // The number of old history to retain to allow rollback. - // This is a pointer to distinguish between explicit zero and not specified. - // Defaults to 10. - // +optional - RevisionHistoryLimit *int32 -} - -// DaemonSetStatus represents the current status of a daemon set. -type DaemonSetStatus struct { - // The number of nodes that are running at least 1 - // daemon pod and are supposed to run the daemon pod. - CurrentNumberScheduled int32 - - // The number of nodes that are running the daemon pod, but are - // not supposed to run the daemon pod. - NumberMisscheduled int32 - - // The total number of nodes that should be running the daemon - // pod (including nodes correctly running the daemon pod). - DesiredNumberScheduled int32 - - // The number of nodes that should be running the daemon pod and have one - // or more of the daemon pod running and ready. - NumberReady int32 - - // The most recent generation observed by the daemon set controller. - // +optional - ObservedGeneration int64 - - // The total number of nodes that are running updated daemon pod - // +optional - UpdatedNumberScheduled int32 - - // The number of nodes that should be running the - // daemon pod and have one or more of the daemon pod running and - // available (ready for at least spec.minReadySeconds) - // +optional - NumberAvailable int32 - - // The number of nodes that should be running the - // daemon pod and have none of the daemon pod running and available - // (ready for at least spec.minReadySeconds) - // +optional - NumberUnavailable int32 - - // Count of hash collisions for the DaemonSet. The DaemonSet controller - // uses this field as a collision avoidance mechanism when it needs to - // create the name for the newest ControllerRevision. - // +optional - CollisionCount *int32 - - // Represents the latest available observations of a DaemonSet's current state. - Conditions []DaemonSetCondition -} - -type DaemonSetConditionType string - -// TODO: Add valid condition types of a DaemonSet. - -// DaemonSetCondition describes the state of a DaemonSet at a certain point. -type DaemonSetCondition struct { - // Type of DaemonSet condition. - Type DaemonSetConditionType - // Status of the condition, one of True, False, Unknown. - Status api.ConditionStatus - // Last time the condition transitioned from one status to another. - LastTransitionTime metav1.Time - // The reason for the condition's last transition. - Reason string - // A human readable message indicating details about the transition. - Message string -} - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// DaemonSet represents the configuration of a daemon set. -type DaemonSet struct { - metav1.TypeMeta - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - // +optional - metav1.ObjectMeta - - // The desired behavior of this daemon set. - // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status - // +optional - Spec DaemonSetSpec - - // The current status of this daemon set. This data may be - // out of date by some window of time. - // Populated by the system. - // Read-only. - // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status - // +optional - Status DaemonSetStatus -} - -const ( - // DEPRECATED: DefaultDaemonSetUniqueLabelKey is used instead. - // DaemonSetTemplateGenerationKey is the key of the labels that is added - // to daemon set pods to distinguish between old and new pod templates - // during DaemonSet template update. - DaemonSetTemplateGenerationKey string = "pod-template-generation" -) - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// DaemonSetList is a collection of daemon sets. -type DaemonSetList struct { - metav1.TypeMeta - // Standard list metadata. - // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata - // +optional - metav1.ListMeta - - // A list of daemon sets. - Items []DaemonSet -} - // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -664,114 +209,3 @@ type IngressBackend struct { // Specifies the port of the referenced service. ServicePort intstr.IntOrString } - -// +genclient -// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/autoscaling.Scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ReplicaSet ensures that a specified number of pod replicas are running at any given time. -type ReplicaSet struct { - metav1.TypeMeta - // +optional - metav1.ObjectMeta - - // Spec defines the desired behavior of this ReplicaSet. - // +optional - Spec ReplicaSetSpec - - // Status is the current status of this ReplicaSet. This data may be - // out of date by some window of time. - // +optional - Status ReplicaSetStatus -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ReplicaSetList is a collection of ReplicaSets. -type ReplicaSetList struct { - metav1.TypeMeta - // +optional - metav1.ListMeta - - Items []ReplicaSet -} - -// ReplicaSetSpec is the specification of a ReplicaSet. -// As the internal representation of a ReplicaSet, it must have -// a Template set. -type ReplicaSetSpec struct { - // Replicas is the number of desired replicas. - Replicas int32 - - // Minimum number of seconds for which a newly created pod should be ready - // without any of its container crashing, for it to be considered available. - // Defaults to 0 (pod will be considered available as soon as it is ready) - // +optional - MinReadySeconds int32 - - // Selector is a label query over pods that should match the replica count. - // Must match in order to be controlled. - // If empty, defaulted to labels on pod template. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors - // +optional - Selector *metav1.LabelSelector - - // Template is the object that describes the pod that will be created if - // insufficient replicas are detected. - // +optional - Template api.PodTemplateSpec -} - -// ReplicaSetStatus represents the current status of a ReplicaSet. -type ReplicaSetStatus struct { - // Replicas is the number of actual replicas. - Replicas int32 - - // The number of pods that have labels matching the labels of the pod template of the replicaset. - // +optional - FullyLabeledReplicas int32 - - // The number of ready replicas for this replica set. - // +optional - ReadyReplicas int32 - - // The number of available replicas (ready for at least minReadySeconds) for this replica set. - // +optional - AvailableReplicas int32 - - // ObservedGeneration is the most recent generation observed by the controller. - // +optional - ObservedGeneration int64 - - // Represents the latest available observations of a replica set's current state. - // +optional - Conditions []ReplicaSetCondition -} - -type ReplicaSetConditionType string - -// These are valid conditions of a replica set. -const ( - // ReplicaSetReplicaFailure is added in a replica set when one of its pods fails to be created - // due to insufficient quota, limit ranges, pod security policy, node selectors, etc. or deleted - // due to kubelet being down or finalizers are failing. - ReplicaSetReplicaFailure ReplicaSetConditionType = "ReplicaFailure" -) - -// ReplicaSetCondition describes the state of a replica set at a certain point. -type ReplicaSetCondition struct { - // Type of replica set condition. - Type ReplicaSetConditionType - // Status of the condition, one of True, False, Unknown. - Status api.ConditionStatus - // The last time the condition transitioned from one status to another. - // +optional - LastTransitionTime metav1.Time - // The reason for the condition's last transition. - // +optional - Reason string - // A human readable message indicating details about the transition. - // +optional - Message string -} diff --git a/pkg/apis/extensions/v1beta1/BUILD b/pkg/apis/extensions/v1beta1/BUILD index af78736d3d0da..3f6c91a1966b0 100644 --- a/pkg/apis/extensions/v1beta1/BUILD +++ b/pkg/apis/extensions/v1beta1/BUILD @@ -18,6 +18,7 @@ go_library( ], importpath = "k8s.io/kubernetes/pkg/apis/extensions/v1beta1", deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/v1:go_default_library", diff --git a/pkg/apis/extensions/v1beta1/conversion.go b/pkg/apis/extensions/v1beta1/conversion.go index ce7b78ae20bf7..80a83b9b289a5 100644 --- a/pkg/apis/extensions/v1beta1/conversion.go +++ b/pkg/apis/extensions/v1beta1/conversion.go @@ -27,10 +27,10 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/networking" ) @@ -39,16 +39,16 @@ func addConversionFuncs(scheme *runtime.Scheme) error { err := scheme.AddConversionFuncs( Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus, Convert_v1beta1_ScaleStatus_To_autoscaling_ScaleStatus, - Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec, - Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec, - Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy, - Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy, - Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment, - Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment, - Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet, - Convert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet, - Convert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec, - Convert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec, + Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec, + Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec, + Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy, + Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy, + Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment, + Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment, + Convert_apps_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet, + Convert_v1beta1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet, + Convert_apps_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec, + Convert_v1beta1_ReplicaSetSpec_To_apps_ReplicaSetSpec, Convert_v1beta1_NetworkPolicy_To_networking_NetworkPolicy, Convert_networking_NetworkPolicy_To_v1beta1_NetworkPolicy, Convert_v1beta1_NetworkPolicyIngressRule_To_networking_NetworkPolicyIngressRule, @@ -106,13 +106,13 @@ func Convert_v1beta1_ScaleStatus_To_autoscaling_ScaleStatus(in *extensionsv1beta return nil } -func Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.DeploymentSpec, out *extensionsv1beta1.DeploymentSpec, s conversion.Scope) error { +func Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(in *apps.DeploymentSpec, out *extensionsv1beta1.DeploymentSpec, s conversion.Scope) error { out.Replicas = &in.Replicas out.Selector = in.Selector if err := k8s_api_v1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } if in.RevisionHistoryLimit != nil { @@ -134,7 +134,7 @@ func Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions. return nil } -func Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *extensionsv1beta1.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { +func Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(in *extensionsv1beta1.DeploymentSpec, out *apps.DeploymentSpec, s conversion.Scope) error { if in.Replicas != nil { out.Replicas = *in.Replicas } @@ -142,14 +142,14 @@ func Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *extensionsv if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.RevisionHistoryLimit = in.RevisionHistoryLimit out.MinReadySeconds = in.MinReadySeconds out.Paused = in.Paused if in.RollbackTo != nil { - out.RollbackTo = new(extensions.RollbackConfig) + out.RollbackTo = new(apps.RollbackConfig) out.RollbackTo.Revision = in.RollbackTo.Revision } else { out.RollbackTo = nil @@ -161,11 +161,11 @@ func Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *extensionsv return nil } -func Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *extensionsv1beta1.DeploymentStrategy, s conversion.Scope) error { +func Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *apps.DeploymentStrategy, out *extensionsv1beta1.DeploymentStrategy, s conversion.Scope) error { out.Type = extensionsv1beta1.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { out.RollingUpdate = new(extensionsv1beta1.RollingUpdateDeployment) - if err := Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + if err := Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -174,11 +174,11 @@ func Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *ext return nil } -func Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *extensionsv1beta1.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { - out.Type = extensions.DeploymentStrategyType(in.Type) +func Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(in *extensionsv1beta1.DeploymentStrategy, out *apps.DeploymentStrategy, s conversion.Scope) error { + out.Type = apps.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { - out.RollingUpdate = new(extensions.RollingUpdateDeployment) - if err := Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + out.RollingUpdate = new(apps.RollingUpdateDeployment) + if err := Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -187,7 +187,7 @@ func Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *ext return nil } -func Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *extensionsv1beta1.RollingUpdateDeployment, s conversion.Scope) error { +func Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *apps.RollingUpdateDeployment, out *extensionsv1beta1.RollingUpdateDeployment, s conversion.Scope) error { if out.MaxUnavailable == nil { out.MaxUnavailable = &intstr.IntOrString{} } @@ -203,7 +203,7 @@ func Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployme return nil } -func Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *extensionsv1beta1.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { +func Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in *extensionsv1beta1.RollingUpdateDeployment, out *apps.RollingUpdateDeployment, s conversion.Scope) error { if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { return err } @@ -213,7 +213,7 @@ func Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployme return nil } -func Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *extensionsv1beta1.RollingUpdateDaemonSet, s conversion.Scope) error { +func Convert_apps_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(in *apps.RollingUpdateDaemonSet, out *extensionsv1beta1.RollingUpdateDaemonSet, s conversion.Scope) error { if out.MaxUnavailable == nil { out.MaxUnavailable = &intstr.IntOrString{} } @@ -223,14 +223,14 @@ func Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet return nil } -func Convert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in *extensionsv1beta1.RollingUpdateDaemonSet, out *extensions.RollingUpdateDaemonSet, s conversion.Scope) error { +func Convert_v1beta1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(in *extensionsv1beta1.RollingUpdateDaemonSet, out *apps.RollingUpdateDaemonSet, s conversion.Scope) error { if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { return err } return nil } -func Convert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(in *extensions.ReplicaSetSpec, out *extensionsv1beta1.ReplicaSetSpec, s conversion.Scope) error { +func Convert_apps_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(in *apps.ReplicaSetSpec, out *extensionsv1beta1.ReplicaSetSpec, s conversion.Scope) error { out.Replicas = new(int32) *out.Replicas = int32(in.Replicas) out.MinReadySeconds = in.MinReadySeconds @@ -241,7 +241,7 @@ func Convert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(in *extensions. return nil } -func Convert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *extensionsv1beta1.ReplicaSetSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error { +func Convert_v1beta1_ReplicaSetSpec_To_apps_ReplicaSetSpec(in *extensionsv1beta1.ReplicaSetSpec, out *apps.ReplicaSetSpec, s conversion.Scope) error { if in.Replicas != nil { out.Replicas = *in.Replicas } diff --git a/pkg/apis/extensions/v1beta1/doc.go b/pkg/apis/extensions/v1beta1/doc.go index 96f579d1ebab7..463bceb1a9a8c 100644 --- a/pkg/apis/extensions/v1beta1/doc.go +++ b/pkg/apis/extensions/v1beta1/doc.go @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/apps // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/policy // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/extensions // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/autoscaling diff --git a/pkg/apis/extensions/v1beta1/zz_generated.conversion.go b/pkg/apis/extensions/v1beta1/zz_generated.conversion.go index 3e6764af44732..3159bdc69e9a2 100644 --- a/pkg/apis/extensions/v1beta1/zz_generated.conversion.go +++ b/pkg/apis/extensions/v1beta1/zz_generated.conversion.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" + apps "k8s.io/kubernetes/pkg/apis/apps" autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" core "k8s.io/kubernetes/pkg/apis/core" corev1 "k8s.io/kubernetes/pkg/apis/core/v1" @@ -63,173 +64,133 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.CustomMetricCurrentStatus)(nil), (*extensions.CustomMetricCurrentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_CustomMetricCurrentStatus_To_extensions_CustomMetricCurrentStatus(a.(*v1beta1.CustomMetricCurrentStatus), b.(*extensions.CustomMetricCurrentStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSet)(nil), (*apps.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DaemonSet_To_apps_DaemonSet(a.(*v1beta1.DaemonSet), b.(*apps.DaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.CustomMetricCurrentStatus)(nil), (*v1beta1.CustomMetricCurrentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_CustomMetricCurrentStatus_To_v1beta1_CustomMetricCurrentStatus(a.(*extensions.CustomMetricCurrentStatus), b.(*v1beta1.CustomMetricCurrentStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSet)(nil), (*v1beta1.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSet_To_v1beta1_DaemonSet(a.(*apps.DaemonSet), b.(*v1beta1.DaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.CustomMetricCurrentStatusList)(nil), (*extensions.CustomMetricCurrentStatusList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_CustomMetricCurrentStatusList_To_extensions_CustomMetricCurrentStatusList(a.(*v1beta1.CustomMetricCurrentStatusList), b.(*extensions.CustomMetricCurrentStatusList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetCondition)(nil), (*apps.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DaemonSetCondition_To_apps_DaemonSetCondition(a.(*v1beta1.DaemonSetCondition), b.(*apps.DaemonSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.CustomMetricCurrentStatusList)(nil), (*v1beta1.CustomMetricCurrentStatusList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_CustomMetricCurrentStatusList_To_v1beta1_CustomMetricCurrentStatusList(a.(*extensions.CustomMetricCurrentStatusList), b.(*v1beta1.CustomMetricCurrentStatusList), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetCondition)(nil), (*v1beta1.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetCondition_To_v1beta1_DaemonSetCondition(a.(*apps.DaemonSetCondition), b.(*v1beta1.DaemonSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.CustomMetricTarget)(nil), (*extensions.CustomMetricTarget)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_CustomMetricTarget_To_extensions_CustomMetricTarget(a.(*v1beta1.CustomMetricTarget), b.(*extensions.CustomMetricTarget), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetList)(nil), (*apps.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DaemonSetList_To_apps_DaemonSetList(a.(*v1beta1.DaemonSetList), b.(*apps.DaemonSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.CustomMetricTarget)(nil), (*v1beta1.CustomMetricTarget)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_CustomMetricTarget_To_v1beta1_CustomMetricTarget(a.(*extensions.CustomMetricTarget), b.(*v1beta1.CustomMetricTarget), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetList)(nil), (*v1beta1.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetList_To_v1beta1_DaemonSetList(a.(*apps.DaemonSetList), b.(*v1beta1.DaemonSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.CustomMetricTargetList)(nil), (*extensions.CustomMetricTargetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_CustomMetricTargetList_To_extensions_CustomMetricTargetList(a.(*v1beta1.CustomMetricTargetList), b.(*extensions.CustomMetricTargetList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetSpec)(nil), (*apps.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DaemonSetSpec_To_apps_DaemonSetSpec(a.(*v1beta1.DaemonSetSpec), b.(*apps.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.CustomMetricTargetList)(nil), (*v1beta1.CustomMetricTargetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_CustomMetricTargetList_To_v1beta1_CustomMetricTargetList(a.(*extensions.CustomMetricTargetList), b.(*v1beta1.CustomMetricTargetList), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetSpec)(nil), (*v1beta1.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetSpec_To_v1beta1_DaemonSetSpec(a.(*apps.DaemonSetSpec), b.(*v1beta1.DaemonSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSet)(nil), (*extensions.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DaemonSet_To_extensions_DaemonSet(a.(*v1beta1.DaemonSet), b.(*extensions.DaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetStatus)(nil), (*apps.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DaemonSetStatus_To_apps_DaemonSetStatus(a.(*v1beta1.DaemonSetStatus), b.(*apps.DaemonSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSet)(nil), (*v1beta1.DaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSet_To_v1beta1_DaemonSet(a.(*extensions.DaemonSet), b.(*v1beta1.DaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetStatus)(nil), (*v1beta1.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetStatus_To_v1beta1_DaemonSetStatus(a.(*apps.DaemonSetStatus), b.(*v1beta1.DaemonSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetCondition)(nil), (*extensions.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DaemonSetCondition_To_extensions_DaemonSetCondition(a.(*v1beta1.DaemonSetCondition), b.(*extensions.DaemonSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetUpdateStrategy)(nil), (*apps.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(a.(*v1beta1.DaemonSetUpdateStrategy), b.(*apps.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetCondition)(nil), (*v1beta1.DaemonSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetCondition_To_v1beta1_DaemonSetCondition(a.(*extensions.DaemonSetCondition), b.(*v1beta1.DaemonSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.DaemonSetUpdateStrategy)(nil), (*v1beta1.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(a.(*apps.DaemonSetUpdateStrategy), b.(*v1beta1.DaemonSetUpdateStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetList)(nil), (*extensions.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DaemonSetList_To_extensions_DaemonSetList(a.(*v1beta1.DaemonSetList), b.(*extensions.DaemonSetList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.Deployment)(nil), (*apps.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Deployment_To_apps_Deployment(a.(*v1beta1.Deployment), b.(*apps.Deployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetList)(nil), (*v1beta1.DaemonSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetList_To_v1beta1_DaemonSetList(a.(*extensions.DaemonSetList), b.(*v1beta1.DaemonSetList), scope) + if err := s.AddGeneratedConversionFunc((*apps.Deployment)(nil), (*v1beta1.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_Deployment_To_v1beta1_Deployment(a.(*apps.Deployment), b.(*v1beta1.Deployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetSpec)(nil), (*extensions.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(a.(*v1beta1.DaemonSetSpec), b.(*extensions.DaemonSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentCondition)(nil), (*apps.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition(a.(*v1beta1.DeploymentCondition), b.(*apps.DeploymentCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetSpec)(nil), (*v1beta1.DaemonSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(a.(*extensions.DaemonSetSpec), b.(*v1beta1.DaemonSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentCondition)(nil), (*v1beta1.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition(a.(*apps.DeploymentCondition), b.(*v1beta1.DeploymentCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetStatus)(nil), (*extensions.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(a.(*v1beta1.DaemonSetStatus), b.(*extensions.DaemonSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentList)(nil), (*apps.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentList_To_apps_DeploymentList(a.(*v1beta1.DeploymentList), b.(*apps.DeploymentList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetStatus)(nil), (*v1beta1.DaemonSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(a.(*extensions.DaemonSetStatus), b.(*v1beta1.DaemonSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentList)(nil), (*v1beta1.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentList_To_v1beta1_DeploymentList(a.(*apps.DeploymentList), b.(*v1beta1.DeploymentList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DaemonSetUpdateStrategy)(nil), (*extensions.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(a.(*v1beta1.DaemonSetUpdateStrategy), b.(*extensions.DaemonSetUpdateStrategy), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentRollback)(nil), (*apps.DeploymentRollback)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback(a.(*v1beta1.DeploymentRollback), b.(*apps.DeploymentRollback), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DaemonSetUpdateStrategy)(nil), (*v1beta1.DaemonSetUpdateStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(a.(*extensions.DaemonSetUpdateStrategy), b.(*v1beta1.DaemonSetUpdateStrategy), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentRollback)(nil), (*v1beta1.DeploymentRollback)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback(a.(*apps.DeploymentRollback), b.(*v1beta1.DeploymentRollback), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.Deployment)(nil), (*extensions.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_Deployment_To_extensions_Deployment(a.(*v1beta1.Deployment), b.(*extensions.Deployment), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentSpec)(nil), (*apps.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(a.(*v1beta1.DeploymentSpec), b.(*apps.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.Deployment)(nil), (*v1beta1.Deployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_Deployment_To_v1beta1_Deployment(a.(*extensions.Deployment), b.(*v1beta1.Deployment), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentSpec)(nil), (*v1beta1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(a.(*apps.DeploymentSpec), b.(*v1beta1.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentCondition)(nil), (*extensions.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(a.(*v1beta1.DeploymentCondition), b.(*extensions.DeploymentCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentStatus)(nil), (*apps.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(a.(*v1beta1.DeploymentStatus), b.(*apps.DeploymentStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentCondition)(nil), (*v1beta1.DeploymentCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(a.(*extensions.DeploymentCondition), b.(*v1beta1.DeploymentCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentStatus)(nil), (*v1beta1.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(a.(*apps.DeploymentStatus), b.(*v1beta1.DeploymentStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentList)(nil), (*extensions.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentList_To_extensions_DeploymentList(a.(*v1beta1.DeploymentList), b.(*extensions.DeploymentList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentStrategy)(nil), (*apps.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(a.(*v1beta1.DeploymentStrategy), b.(*apps.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentList)(nil), (*v1beta1.DeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentList_To_v1beta1_DeploymentList(a.(*extensions.DeploymentList), b.(*v1beta1.DeploymentList), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentRollback)(nil), (*extensions.DeploymentRollback)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback(a.(*v1beta1.DeploymentRollback), b.(*extensions.DeploymentRollback), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentRollback)(nil), (*v1beta1.DeploymentRollback)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback(a.(*extensions.DeploymentRollback), b.(*v1beta1.DeploymentRollback), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentSpec)(nil), (*extensions.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(a.(*v1beta1.DeploymentSpec), b.(*extensions.DeploymentSpec), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentSpec)(nil), (*v1beta1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(a.(*extensions.DeploymentSpec), b.(*v1beta1.DeploymentSpec), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentStatus)(nil), (*extensions.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(a.(*v1beta1.DeploymentStatus), b.(*extensions.DeploymentStatus), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentStatus)(nil), (*v1beta1.DeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(a.(*extensions.DeploymentStatus), b.(*v1beta1.DeploymentStatus), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*v1beta1.DeploymentStrategy)(nil), (*extensions.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(a.(*v1beta1.DeploymentStrategy), b.(*extensions.DeploymentStrategy), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*extensions.DeploymentStrategy)(nil), (*v1beta1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(a.(*extensions.DeploymentStrategy), b.(*v1beta1.DeploymentStrategy), scope) + if err := s.AddGeneratedConversionFunc((*apps.DeploymentStrategy)(nil), (*v1beta1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(a.(*apps.DeploymentStrategy), b.(*v1beta1.DeploymentStrategy), scope) }); err != nil { return err } @@ -393,53 +354,53 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSet)(nil), (*extensions.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_ReplicaSet_To_extensions_ReplicaSet(a.(*v1beta1.ReplicaSet), b.(*extensions.ReplicaSet), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSet)(nil), (*apps.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ReplicaSet_To_apps_ReplicaSet(a.(*v1beta1.ReplicaSet), b.(*apps.ReplicaSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSet)(nil), (*v1beta1.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSet_To_v1beta1_ReplicaSet(a.(*extensions.ReplicaSet), b.(*v1beta1.ReplicaSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSet)(nil), (*v1beta1.ReplicaSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSet_To_v1beta1_ReplicaSet(a.(*apps.ReplicaSet), b.(*v1beta1.ReplicaSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSetCondition)(nil), (*extensions.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(a.(*v1beta1.ReplicaSetCondition), b.(*extensions.ReplicaSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSetCondition)(nil), (*apps.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ReplicaSetCondition_To_apps_ReplicaSetCondition(a.(*v1beta1.ReplicaSetCondition), b.(*apps.ReplicaSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetCondition)(nil), (*v1beta1.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(a.(*extensions.ReplicaSetCondition), b.(*v1beta1.ReplicaSetCondition), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetCondition)(nil), (*v1beta1.ReplicaSetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(a.(*apps.ReplicaSetCondition), b.(*v1beta1.ReplicaSetCondition), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSetList)(nil), (*extensions.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_ReplicaSetList_To_extensions_ReplicaSetList(a.(*v1beta1.ReplicaSetList), b.(*extensions.ReplicaSetList), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSetList)(nil), (*apps.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ReplicaSetList_To_apps_ReplicaSetList(a.(*v1beta1.ReplicaSetList), b.(*apps.ReplicaSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetList)(nil), (*v1beta1.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetList_To_v1beta1_ReplicaSetList(a.(*extensions.ReplicaSetList), b.(*v1beta1.ReplicaSetList), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetList)(nil), (*v1beta1.ReplicaSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetList_To_v1beta1_ReplicaSetList(a.(*apps.ReplicaSetList), b.(*v1beta1.ReplicaSetList), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSetSpec)(nil), (*extensions.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(a.(*v1beta1.ReplicaSetSpec), b.(*extensions.ReplicaSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSetSpec)(nil), (*apps.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ReplicaSetSpec_To_apps_ReplicaSetSpec(a.(*v1beta1.ReplicaSetSpec), b.(*apps.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetSpec)(nil), (*v1beta1.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(a.(*extensions.ReplicaSetSpec), b.(*v1beta1.ReplicaSetSpec), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetSpec)(nil), (*v1beta1.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(a.(*apps.ReplicaSetSpec), b.(*v1beta1.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSetStatus)(nil), (*extensions.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(a.(*v1beta1.ReplicaSetStatus), b.(*extensions.ReplicaSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.ReplicaSetStatus)(nil), (*apps.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ReplicaSetStatus_To_apps_ReplicaSetStatus(a.(*v1beta1.ReplicaSetStatus), b.(*apps.ReplicaSetStatus), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.ReplicaSetStatus)(nil), (*v1beta1.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(a.(*extensions.ReplicaSetStatus), b.(*v1beta1.ReplicaSetStatus), scope) + if err := s.AddGeneratedConversionFunc((*apps.ReplicaSetStatus)(nil), (*v1beta1.ReplicaSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(a.(*apps.ReplicaSetStatus), b.(*v1beta1.ReplicaSetStatus), scope) }); err != nil { return err } @@ -453,33 +414,33 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.RollbackConfig)(nil), (*extensions.RollbackConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(a.(*v1beta1.RollbackConfig), b.(*extensions.RollbackConfig), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.RollbackConfig)(nil), (*apps.RollbackConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollbackConfig_To_apps_RollbackConfig(a.(*v1beta1.RollbackConfig), b.(*apps.RollbackConfig), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollbackConfig)(nil), (*v1beta1.RollbackConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(a.(*extensions.RollbackConfig), b.(*v1beta1.RollbackConfig), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollbackConfig)(nil), (*v1beta1.RollbackConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollbackConfig_To_v1beta1_RollbackConfig(a.(*apps.RollbackConfig), b.(*v1beta1.RollbackConfig), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.RollingUpdateDaemonSet)(nil), (*extensions.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(a.(*v1beta1.RollingUpdateDaemonSet), b.(*extensions.RollingUpdateDaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.RollingUpdateDaemonSet)(nil), (*apps.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(a.(*v1beta1.RollingUpdateDaemonSet), b.(*apps.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollingUpdateDaemonSet)(nil), (*v1beta1.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(a.(*extensions.RollingUpdateDaemonSet), b.(*v1beta1.RollingUpdateDaemonSet), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollingUpdateDaemonSet)(nil), (*v1beta1.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(a.(*apps.RollingUpdateDaemonSet), b.(*v1beta1.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.RollingUpdateDeployment)(nil), (*extensions.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(a.(*v1beta1.RollingUpdateDeployment), b.(*extensions.RollingUpdateDeployment), scope) + if err := s.AddGeneratedConversionFunc((*v1beta1.RollingUpdateDeployment)(nil), (*apps.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(a.(*v1beta1.RollingUpdateDeployment), b.(*apps.RollingUpdateDeployment), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*extensions.RollingUpdateDeployment)(nil), (*v1beta1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(a.(*extensions.RollingUpdateDeployment), b.(*v1beta1.RollingUpdateDeployment), scope) + if err := s.AddGeneratedConversionFunc((*apps.RollingUpdateDeployment)(nil), (*v1beta1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(a.(*apps.RollingUpdateDeployment), b.(*v1beta1.RollingUpdateDeployment), scope) }); err != nil { return err } @@ -553,33 +514,33 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*autoscaling.ScaleStatus)(nil), (*v1beta1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus(a.(*autoscaling.ScaleStatus), b.(*v1beta1.ScaleStatus), scope) + if err := s.AddConversionFunc((*apps.DeploymentSpec)(nil), (*v1beta1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(a.(*apps.DeploymentSpec), b.(*v1beta1.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DeploymentSpec)(nil), (*v1beta1.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(a.(*extensions.DeploymentSpec), b.(*v1beta1.DeploymentSpec), scope) + if err := s.AddConversionFunc((*apps.DeploymentStrategy)(nil), (*v1beta1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(a.(*apps.DeploymentStrategy), b.(*v1beta1.DeploymentStrategy), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.DeploymentStrategy)(nil), (*v1beta1.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(a.(*extensions.DeploymentStrategy), b.(*v1beta1.DeploymentStrategy), scope) + if err := s.AddConversionFunc((*apps.ReplicaSetSpec)(nil), (*v1beta1.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(a.(*apps.ReplicaSetSpec), b.(*v1beta1.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.ReplicaSetSpec)(nil), (*v1beta1.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(a.(*extensions.ReplicaSetSpec), b.(*v1beta1.ReplicaSetSpec), scope) + if err := s.AddConversionFunc((*apps.RollingUpdateDaemonSet)(nil), (*v1beta1.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(a.(*apps.RollingUpdateDaemonSet), b.(*v1beta1.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.RollingUpdateDaemonSet)(nil), (*v1beta1.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(a.(*extensions.RollingUpdateDaemonSet), b.(*v1beta1.RollingUpdateDaemonSet), scope) + if err := s.AddConversionFunc((*apps.RollingUpdateDeployment)(nil), (*v1beta1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(a.(*apps.RollingUpdateDeployment), b.(*v1beta1.RollingUpdateDeployment), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*extensions.RollingUpdateDeployment)(nil), (*v1beta1.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(a.(*extensions.RollingUpdateDeployment), b.(*v1beta1.RollingUpdateDeployment), scope) + if err := s.AddConversionFunc((*autoscaling.ScaleStatus)(nil), (*v1beta1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus(a.(*autoscaling.ScaleStatus), b.(*v1beta1.ScaleStatus), scope) }); err != nil { return err } @@ -623,13 +584,13 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.DeploymentSpec)(nil), (*extensions.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(a.(*v1beta1.DeploymentSpec), b.(*extensions.DeploymentSpec), scope) + if err := s.AddConversionFunc((*v1beta1.DeploymentSpec)(nil), (*apps.DeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(a.(*v1beta1.DeploymentSpec), b.(*apps.DeploymentSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.DeploymentStrategy)(nil), (*extensions.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(a.(*v1beta1.DeploymentStrategy), b.(*extensions.DeploymentStrategy), scope) + if err := s.AddConversionFunc((*v1beta1.DeploymentStrategy)(nil), (*apps.DeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(a.(*v1beta1.DeploymentStrategy), b.(*apps.DeploymentStrategy), scope) }); err != nil { return err } @@ -673,18 +634,18 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.ReplicaSetSpec)(nil), (*extensions.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(a.(*v1beta1.ReplicaSetSpec), b.(*extensions.ReplicaSetSpec), scope) + if err := s.AddConversionFunc((*v1beta1.ReplicaSetSpec)(nil), (*apps.ReplicaSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ReplicaSetSpec_To_apps_ReplicaSetSpec(a.(*v1beta1.ReplicaSetSpec), b.(*apps.ReplicaSetSpec), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.RollingUpdateDaemonSet)(nil), (*extensions.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(a.(*v1beta1.RollingUpdateDaemonSet), b.(*extensions.RollingUpdateDaemonSet), scope) + if err := s.AddConversionFunc((*v1beta1.RollingUpdateDaemonSet)(nil), (*apps.RollingUpdateDaemonSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(a.(*v1beta1.RollingUpdateDaemonSet), b.(*apps.RollingUpdateDaemonSet), scope) }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.RollingUpdateDeployment)(nil), (*extensions.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(a.(*v1beta1.RollingUpdateDeployment), b.(*extensions.RollingUpdateDeployment), scope) + if err := s.AddConversionFunc((*v1beta1.RollingUpdateDeployment)(nil), (*apps.RollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(a.(*v1beta1.RollingUpdateDeployment), b.(*apps.RollingUpdateDeployment), scope) }); err != nil { return err } @@ -738,124 +699,40 @@ func Convert_policy_AllowedHostPath_To_v1beta1_AllowedHostPath(in *policy.Allowe return autoConvert_policy_AllowedHostPath_To_v1beta1_AllowedHostPath(in, out, s) } -func autoConvert_v1beta1_CustomMetricCurrentStatus_To_extensions_CustomMetricCurrentStatus(in *v1beta1.CustomMetricCurrentStatus, out *extensions.CustomMetricCurrentStatus, s conversion.Scope) error { - out.Name = in.Name - out.CurrentValue = in.CurrentValue - return nil -} - -// Convert_v1beta1_CustomMetricCurrentStatus_To_extensions_CustomMetricCurrentStatus is an autogenerated conversion function. -func Convert_v1beta1_CustomMetricCurrentStatus_To_extensions_CustomMetricCurrentStatus(in *v1beta1.CustomMetricCurrentStatus, out *extensions.CustomMetricCurrentStatus, s conversion.Scope) error { - return autoConvert_v1beta1_CustomMetricCurrentStatus_To_extensions_CustomMetricCurrentStatus(in, out, s) -} - -func autoConvert_extensions_CustomMetricCurrentStatus_To_v1beta1_CustomMetricCurrentStatus(in *extensions.CustomMetricCurrentStatus, out *v1beta1.CustomMetricCurrentStatus, s conversion.Scope) error { - out.Name = in.Name - out.CurrentValue = in.CurrentValue - return nil -} - -// Convert_extensions_CustomMetricCurrentStatus_To_v1beta1_CustomMetricCurrentStatus is an autogenerated conversion function. -func Convert_extensions_CustomMetricCurrentStatus_To_v1beta1_CustomMetricCurrentStatus(in *extensions.CustomMetricCurrentStatus, out *v1beta1.CustomMetricCurrentStatus, s conversion.Scope) error { - return autoConvert_extensions_CustomMetricCurrentStatus_To_v1beta1_CustomMetricCurrentStatus(in, out, s) -} - -func autoConvert_v1beta1_CustomMetricCurrentStatusList_To_extensions_CustomMetricCurrentStatusList(in *v1beta1.CustomMetricCurrentStatusList, out *extensions.CustomMetricCurrentStatusList, s conversion.Scope) error { - out.Items = *(*[]extensions.CustomMetricCurrentStatus)(unsafe.Pointer(&in.Items)) - return nil -} - -// Convert_v1beta1_CustomMetricCurrentStatusList_To_extensions_CustomMetricCurrentStatusList is an autogenerated conversion function. -func Convert_v1beta1_CustomMetricCurrentStatusList_To_extensions_CustomMetricCurrentStatusList(in *v1beta1.CustomMetricCurrentStatusList, out *extensions.CustomMetricCurrentStatusList, s conversion.Scope) error { - return autoConvert_v1beta1_CustomMetricCurrentStatusList_To_extensions_CustomMetricCurrentStatusList(in, out, s) -} - -func autoConvert_extensions_CustomMetricCurrentStatusList_To_v1beta1_CustomMetricCurrentStatusList(in *extensions.CustomMetricCurrentStatusList, out *v1beta1.CustomMetricCurrentStatusList, s conversion.Scope) error { - out.Items = *(*[]v1beta1.CustomMetricCurrentStatus)(unsafe.Pointer(&in.Items)) - return nil -} - -// Convert_extensions_CustomMetricCurrentStatusList_To_v1beta1_CustomMetricCurrentStatusList is an autogenerated conversion function. -func Convert_extensions_CustomMetricCurrentStatusList_To_v1beta1_CustomMetricCurrentStatusList(in *extensions.CustomMetricCurrentStatusList, out *v1beta1.CustomMetricCurrentStatusList, s conversion.Scope) error { - return autoConvert_extensions_CustomMetricCurrentStatusList_To_v1beta1_CustomMetricCurrentStatusList(in, out, s) -} - -func autoConvert_v1beta1_CustomMetricTarget_To_extensions_CustomMetricTarget(in *v1beta1.CustomMetricTarget, out *extensions.CustomMetricTarget, s conversion.Scope) error { - out.Name = in.Name - out.TargetValue = in.TargetValue - return nil -} - -// Convert_v1beta1_CustomMetricTarget_To_extensions_CustomMetricTarget is an autogenerated conversion function. -func Convert_v1beta1_CustomMetricTarget_To_extensions_CustomMetricTarget(in *v1beta1.CustomMetricTarget, out *extensions.CustomMetricTarget, s conversion.Scope) error { - return autoConvert_v1beta1_CustomMetricTarget_To_extensions_CustomMetricTarget(in, out, s) -} - -func autoConvert_extensions_CustomMetricTarget_To_v1beta1_CustomMetricTarget(in *extensions.CustomMetricTarget, out *v1beta1.CustomMetricTarget, s conversion.Scope) error { - out.Name = in.Name - out.TargetValue = in.TargetValue - return nil -} - -// Convert_extensions_CustomMetricTarget_To_v1beta1_CustomMetricTarget is an autogenerated conversion function. -func Convert_extensions_CustomMetricTarget_To_v1beta1_CustomMetricTarget(in *extensions.CustomMetricTarget, out *v1beta1.CustomMetricTarget, s conversion.Scope) error { - return autoConvert_extensions_CustomMetricTarget_To_v1beta1_CustomMetricTarget(in, out, s) -} - -func autoConvert_v1beta1_CustomMetricTargetList_To_extensions_CustomMetricTargetList(in *v1beta1.CustomMetricTargetList, out *extensions.CustomMetricTargetList, s conversion.Scope) error { - out.Items = *(*[]extensions.CustomMetricTarget)(unsafe.Pointer(&in.Items)) - return nil -} - -// Convert_v1beta1_CustomMetricTargetList_To_extensions_CustomMetricTargetList is an autogenerated conversion function. -func Convert_v1beta1_CustomMetricTargetList_To_extensions_CustomMetricTargetList(in *v1beta1.CustomMetricTargetList, out *extensions.CustomMetricTargetList, s conversion.Scope) error { - return autoConvert_v1beta1_CustomMetricTargetList_To_extensions_CustomMetricTargetList(in, out, s) -} - -func autoConvert_extensions_CustomMetricTargetList_To_v1beta1_CustomMetricTargetList(in *extensions.CustomMetricTargetList, out *v1beta1.CustomMetricTargetList, s conversion.Scope) error { - out.Items = *(*[]v1beta1.CustomMetricTarget)(unsafe.Pointer(&in.Items)) - return nil -} - -// Convert_extensions_CustomMetricTargetList_To_v1beta1_CustomMetricTargetList is an autogenerated conversion function. -func Convert_extensions_CustomMetricTargetList_To_v1beta1_CustomMetricTargetList(in *extensions.CustomMetricTargetList, out *v1beta1.CustomMetricTargetList, s conversion.Scope) error { - return autoConvert_extensions_CustomMetricTargetList_To_v1beta1_CustomMetricTargetList(in, out, s) -} - -func autoConvert_v1beta1_DaemonSet_To_extensions_DaemonSet(in *v1beta1.DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error { +func autoConvert_v1beta1_DaemonSet_To_apps_DaemonSet(in *v1beta1.DaemonSet, out *apps.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta1_DaemonSetSpec_To_apps_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1beta1_DaemonSetStatus_To_apps_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_v1beta1_DaemonSet_To_extensions_DaemonSet is an autogenerated conversion function. -func Convert_v1beta1_DaemonSet_To_extensions_DaemonSet(in *v1beta1.DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error { - return autoConvert_v1beta1_DaemonSet_To_extensions_DaemonSet(in, out, s) +// Convert_v1beta1_DaemonSet_To_apps_DaemonSet is an autogenerated conversion function. +func Convert_v1beta1_DaemonSet_To_apps_DaemonSet(in *v1beta1.DaemonSet, out *apps.DaemonSet, s conversion.Scope) error { + return autoConvert_v1beta1_DaemonSet_To_apps_DaemonSet(in, out, s) } -func autoConvert_extensions_DaemonSet_To_v1beta1_DaemonSet(in *extensions.DaemonSet, out *v1beta1.DaemonSet, s conversion.Scope) error { +func autoConvert_apps_DaemonSet_To_v1beta1_DaemonSet(in *apps.DaemonSet, out *v1beta1.DaemonSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DaemonSetSpec_To_v1beta1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DaemonSetStatus_To_v1beta1_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_extensions_DaemonSet_To_v1beta1_DaemonSet is an autogenerated conversion function. -func Convert_extensions_DaemonSet_To_v1beta1_DaemonSet(in *extensions.DaemonSet, out *v1beta1.DaemonSet, s conversion.Scope) error { - return autoConvert_extensions_DaemonSet_To_v1beta1_DaemonSet(in, out, s) +// Convert_apps_DaemonSet_To_v1beta1_DaemonSet is an autogenerated conversion function. +func Convert_apps_DaemonSet_To_v1beta1_DaemonSet(in *apps.DaemonSet, out *v1beta1.DaemonSet, s conversion.Scope) error { + return autoConvert_apps_DaemonSet_To_v1beta1_DaemonSet(in, out, s) } -func autoConvert_v1beta1_DaemonSetCondition_To_extensions_DaemonSetCondition(in *v1beta1.DaemonSetCondition, out *extensions.DaemonSetCondition, s conversion.Scope) error { - out.Type = extensions.DaemonSetConditionType(in.Type) +func autoConvert_v1beta1_DaemonSetCondition_To_apps_DaemonSetCondition(in *v1beta1.DaemonSetCondition, out *apps.DaemonSetCondition, s conversion.Scope) error { + out.Type = apps.DaemonSetConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime out.Reason = in.Reason @@ -863,12 +740,12 @@ func autoConvert_v1beta1_DaemonSetCondition_To_extensions_DaemonSetCondition(in return nil } -// Convert_v1beta1_DaemonSetCondition_To_extensions_DaemonSetCondition is an autogenerated conversion function. -func Convert_v1beta1_DaemonSetCondition_To_extensions_DaemonSetCondition(in *v1beta1.DaemonSetCondition, out *extensions.DaemonSetCondition, s conversion.Scope) error { - return autoConvert_v1beta1_DaemonSetCondition_To_extensions_DaemonSetCondition(in, out, s) +// Convert_v1beta1_DaemonSetCondition_To_apps_DaemonSetCondition is an autogenerated conversion function. +func Convert_v1beta1_DaemonSetCondition_To_apps_DaemonSetCondition(in *v1beta1.DaemonSetCondition, out *apps.DaemonSetCondition, s conversion.Scope) error { + return autoConvert_v1beta1_DaemonSetCondition_To_apps_DaemonSetCondition(in, out, s) } -func autoConvert_extensions_DaemonSetCondition_To_v1beta1_DaemonSetCondition(in *extensions.DaemonSetCondition, out *v1beta1.DaemonSetCondition, s conversion.Scope) error { +func autoConvert_apps_DaemonSetCondition_To_v1beta1_DaemonSetCondition(in *apps.DaemonSetCondition, out *v1beta1.DaemonSetCondition, s conversion.Scope) error { out.Type = v1beta1.DaemonSetConditionType(in.Type) out.Status = v1.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime @@ -877,18 +754,18 @@ func autoConvert_extensions_DaemonSetCondition_To_v1beta1_DaemonSetCondition(in return nil } -// Convert_extensions_DaemonSetCondition_To_v1beta1_DaemonSetCondition is an autogenerated conversion function. -func Convert_extensions_DaemonSetCondition_To_v1beta1_DaemonSetCondition(in *extensions.DaemonSetCondition, out *v1beta1.DaemonSetCondition, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetCondition_To_v1beta1_DaemonSetCondition(in, out, s) +// Convert_apps_DaemonSetCondition_To_v1beta1_DaemonSetCondition is an autogenerated conversion function. +func Convert_apps_DaemonSetCondition_To_v1beta1_DaemonSetCondition(in *apps.DaemonSetCondition, out *v1beta1.DaemonSetCondition, s conversion.Scope) error { + return autoConvert_apps_DaemonSetCondition_To_v1beta1_DaemonSetCondition(in, out, s) } -func autoConvert_v1beta1_DaemonSetList_To_extensions_DaemonSetList(in *v1beta1.DaemonSetList, out *extensions.DaemonSetList, s conversion.Scope) error { +func autoConvert_v1beta1_DaemonSetList_To_apps_DaemonSetList(in *v1beta1.DaemonSetList, out *apps.DaemonSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.DaemonSet, len(*in)) + *out = make([]apps.DaemonSet, len(*in)) for i := range *in { - if err := Convert_v1beta1_DaemonSet_To_extensions_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1beta1_DaemonSet_To_apps_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -898,18 +775,18 @@ func autoConvert_v1beta1_DaemonSetList_To_extensions_DaemonSetList(in *v1beta1.D return nil } -// Convert_v1beta1_DaemonSetList_To_extensions_DaemonSetList is an autogenerated conversion function. -func Convert_v1beta1_DaemonSetList_To_extensions_DaemonSetList(in *v1beta1.DaemonSetList, out *extensions.DaemonSetList, s conversion.Scope) error { - return autoConvert_v1beta1_DaemonSetList_To_extensions_DaemonSetList(in, out, s) +// Convert_v1beta1_DaemonSetList_To_apps_DaemonSetList is an autogenerated conversion function. +func Convert_v1beta1_DaemonSetList_To_apps_DaemonSetList(in *v1beta1.DaemonSetList, out *apps.DaemonSetList, s conversion.Scope) error { + return autoConvert_v1beta1_DaemonSetList_To_apps_DaemonSetList(in, out, s) } -func autoConvert_extensions_DaemonSetList_To_v1beta1_DaemonSetList(in *extensions.DaemonSetList, out *v1beta1.DaemonSetList, s conversion.Scope) error { +func autoConvert_apps_DaemonSetList_To_v1beta1_DaemonSetList(in *apps.DaemonSetList, out *v1beta1.DaemonSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1beta1.DaemonSet, len(*in)) for i := range *in { - if err := Convert_extensions_DaemonSet_To_v1beta1_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_DaemonSet_To_v1beta1_DaemonSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -919,17 +796,17 @@ func autoConvert_extensions_DaemonSetList_To_v1beta1_DaemonSetList(in *extension return nil } -// Convert_extensions_DaemonSetList_To_v1beta1_DaemonSetList is an autogenerated conversion function. -func Convert_extensions_DaemonSetList_To_v1beta1_DaemonSetList(in *extensions.DaemonSetList, out *v1beta1.DaemonSetList, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetList_To_v1beta1_DaemonSetList(in, out, s) +// Convert_apps_DaemonSetList_To_v1beta1_DaemonSetList is an autogenerated conversion function. +func Convert_apps_DaemonSetList_To_v1beta1_DaemonSetList(in *apps.DaemonSetList, out *v1beta1.DaemonSetList, s conversion.Scope) error { + return autoConvert_apps_DaemonSetList_To_v1beta1_DaemonSetList(in, out, s) } -func autoConvert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *v1beta1.DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error { +func autoConvert_v1beta1_DaemonSetSpec_To_apps_DaemonSetSpec(in *v1beta1.DaemonSetSpec, out *apps.DaemonSetSpec, s conversion.Scope) error { out.Selector = (*metav1.LabelSelector)(unsafe.Pointer(in.Selector)) if err := corev1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_v1beta1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -938,17 +815,17 @@ func autoConvert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *v1beta1.D return nil } -// Convert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec is an autogenerated conversion function. -func Convert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *v1beta1.DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error { - return autoConvert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in, out, s) +// Convert_v1beta1_DaemonSetSpec_To_apps_DaemonSetSpec is an autogenerated conversion function. +func Convert_v1beta1_DaemonSetSpec_To_apps_DaemonSetSpec(in *v1beta1.DaemonSetSpec, out *apps.DaemonSetSpec, s conversion.Scope) error { + return autoConvert_v1beta1_DaemonSetSpec_To_apps_DaemonSetSpec(in, out, s) } -func autoConvert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *extensions.DaemonSetSpec, out *v1beta1.DaemonSetSpec, s conversion.Scope) error { +func autoConvert_apps_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *apps.DaemonSetSpec, out *v1beta1.DaemonSetSpec, s conversion.Scope) error { out.Selector = (*metav1.LabelSelector)(unsafe.Pointer(in.Selector)) if err := corev1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { + if err := Convert_apps_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -957,12 +834,12 @@ func autoConvert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *extension return nil } -// Convert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec is an autogenerated conversion function. -func Convert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *extensions.DaemonSetSpec, out *v1beta1.DaemonSetSpec, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in, out, s) +// Convert_apps_DaemonSetSpec_To_v1beta1_DaemonSetSpec is an autogenerated conversion function. +func Convert_apps_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *apps.DaemonSetSpec, out *v1beta1.DaemonSetSpec, s conversion.Scope) error { + return autoConvert_apps_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in, out, s) } -func autoConvert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1beta1.DaemonSetStatus, out *extensions.DaemonSetStatus, s conversion.Scope) error { +func autoConvert_v1beta1_DaemonSetStatus_To_apps_DaemonSetStatus(in *v1beta1.DaemonSetStatus, out *apps.DaemonSetStatus, s conversion.Scope) error { out.CurrentNumberScheduled = in.CurrentNumberScheduled out.NumberMisscheduled = in.NumberMisscheduled out.DesiredNumberScheduled = in.DesiredNumberScheduled @@ -972,16 +849,16 @@ func autoConvert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1bet out.NumberAvailable = in.NumberAvailable out.NumberUnavailable = in.NumberUnavailable out.CollisionCount = (*int32)(unsafe.Pointer(in.CollisionCount)) - out.Conditions = *(*[]extensions.DaemonSetCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.DaemonSetCondition)(unsafe.Pointer(&in.Conditions)) return nil } -// Convert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus is an autogenerated conversion function. -func Convert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(in *v1beta1.DaemonSetStatus, out *extensions.DaemonSetStatus, s conversion.Scope) error { - return autoConvert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(in, out, s) +// Convert_v1beta1_DaemonSetStatus_To_apps_DaemonSetStatus is an autogenerated conversion function. +func Convert_v1beta1_DaemonSetStatus_To_apps_DaemonSetStatus(in *v1beta1.DaemonSetStatus, out *apps.DaemonSetStatus, s conversion.Scope) error { + return autoConvert_v1beta1_DaemonSetStatus_To_apps_DaemonSetStatus(in, out, s) } -func autoConvert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in *extensions.DaemonSetStatus, out *v1beta1.DaemonSetStatus, s conversion.Scope) error { +func autoConvert_apps_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in *apps.DaemonSetStatus, out *v1beta1.DaemonSetStatus, s conversion.Scope) error { out.CurrentNumberScheduled = in.CurrentNumberScheduled out.NumberMisscheduled = in.NumberMisscheduled out.DesiredNumberScheduled = in.DesiredNumberScheduled @@ -995,17 +872,17 @@ func autoConvert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in *exten return nil } -// Convert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus is an autogenerated conversion function. -func Convert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in *extensions.DaemonSetStatus, out *v1beta1.DaemonSetStatus, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in, out, s) +// Convert_apps_DaemonSetStatus_To_v1beta1_DaemonSetStatus is an autogenerated conversion function. +func Convert_apps_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in *apps.DaemonSetStatus, out *v1beta1.DaemonSetStatus, s conversion.Scope) error { + return autoConvert_apps_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in, out, s) } -func autoConvert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in *v1beta1.DaemonSetUpdateStrategy, out *extensions.DaemonSetUpdateStrategy, s conversion.Scope) error { - out.Type = extensions.DaemonSetUpdateStrategyType(in.Type) +func autoConvert_v1beta1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(in *v1beta1.DaemonSetUpdateStrategy, out *apps.DaemonSetUpdateStrategy, s conversion.Scope) error { + out.Type = apps.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(extensions.RollingUpdateDaemonSet) - if err := Convert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(*in, *out, s); err != nil { + *out = new(apps.RollingUpdateDaemonSet) + if err := Convert_v1beta1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(*in, *out, s); err != nil { return err } } else { @@ -1014,17 +891,17 @@ func autoConvert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateSt return nil } -// Convert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy is an autogenerated conversion function. -func Convert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in *v1beta1.DaemonSetUpdateStrategy, out *extensions.DaemonSetUpdateStrategy, s conversion.Scope) error { - return autoConvert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in, out, s) +// Convert_v1beta1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy is an autogenerated conversion function. +func Convert_v1beta1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(in *v1beta1.DaemonSetUpdateStrategy, out *apps.DaemonSetUpdateStrategy, s conversion.Scope) error { + return autoConvert_v1beta1_DaemonSetUpdateStrategy_To_apps_DaemonSetUpdateStrategy(in, out, s) } -func autoConvert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(in *extensions.DaemonSetUpdateStrategy, out *v1beta1.DaemonSetUpdateStrategy, s conversion.Scope) error { +func autoConvert_apps_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(in *apps.DaemonSetUpdateStrategy, out *v1beta1.DaemonSetUpdateStrategy, s conversion.Scope) error { out.Type = v1beta1.DaemonSetUpdateStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate *out = new(v1beta1.RollingUpdateDaemonSet) - if err := Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(*in, *out, s); err != nil { + if err := Convert_apps_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(*in, *out, s); err != nil { return err } } else { @@ -1033,45 +910,45 @@ func autoConvert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateSt return nil } -// Convert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy is an autogenerated conversion function. -func Convert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(in *extensions.DaemonSetUpdateStrategy, out *v1beta1.DaemonSetUpdateStrategy, s conversion.Scope) error { - return autoConvert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(in, out, s) +// Convert_apps_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy is an autogenerated conversion function. +func Convert_apps_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(in *apps.DaemonSetUpdateStrategy, out *v1beta1.DaemonSetUpdateStrategy, s conversion.Scope) error { + return autoConvert_apps_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(in, out, s) } -func autoConvert_v1beta1_Deployment_To_extensions_Deployment(in *v1beta1.Deployment, out *extensions.Deployment, s conversion.Scope) error { +func autoConvert_v1beta1_Deployment_To_apps_Deployment(in *v1beta1.Deployment, out *apps.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_v1beta1_Deployment_To_extensions_Deployment is an autogenerated conversion function. -func Convert_v1beta1_Deployment_To_extensions_Deployment(in *v1beta1.Deployment, out *extensions.Deployment, s conversion.Scope) error { - return autoConvert_v1beta1_Deployment_To_extensions_Deployment(in, out, s) +// Convert_v1beta1_Deployment_To_apps_Deployment is an autogenerated conversion function. +func Convert_v1beta1_Deployment_To_apps_Deployment(in *v1beta1.Deployment, out *apps.Deployment, s conversion.Scope) error { + return autoConvert_v1beta1_Deployment_To_apps_Deployment(in, out, s) } -func autoConvert_extensions_Deployment_To_v1beta1_Deployment(in *extensions.Deployment, out *v1beta1.Deployment, s conversion.Scope) error { +func autoConvert_apps_Deployment_To_v1beta1_Deployment(in *apps.Deployment, out *v1beta1.Deployment, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_extensions_Deployment_To_v1beta1_Deployment is an autogenerated conversion function. -func Convert_extensions_Deployment_To_v1beta1_Deployment(in *extensions.Deployment, out *v1beta1.Deployment, s conversion.Scope) error { - return autoConvert_extensions_Deployment_To_v1beta1_Deployment(in, out, s) +// Convert_apps_Deployment_To_v1beta1_Deployment is an autogenerated conversion function. +func Convert_apps_Deployment_To_v1beta1_Deployment(in *apps.Deployment, out *v1beta1.Deployment, s conversion.Scope) error { + return autoConvert_apps_Deployment_To_v1beta1_Deployment(in, out, s) } -func autoConvert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(in *v1beta1.DeploymentCondition, out *extensions.DeploymentCondition, s conversion.Scope) error { - out.Type = extensions.DeploymentConditionType(in.Type) +func autoConvert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition(in *v1beta1.DeploymentCondition, out *apps.DeploymentCondition, s conversion.Scope) error { + out.Type = apps.DeploymentConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastUpdateTime = in.LastUpdateTime out.LastTransitionTime = in.LastTransitionTime @@ -1080,12 +957,12 @@ func autoConvert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(i return nil } -// Convert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition is an autogenerated conversion function. -func Convert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(in *v1beta1.DeploymentCondition, out *extensions.DeploymentCondition, s conversion.Scope) error { - return autoConvert_v1beta1_DeploymentCondition_To_extensions_DeploymentCondition(in, out, s) +// Convert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition is an autogenerated conversion function. +func Convert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition(in *v1beta1.DeploymentCondition, out *apps.DeploymentCondition, s conversion.Scope) error { + return autoConvert_v1beta1_DeploymentCondition_To_apps_DeploymentCondition(in, out, s) } -func autoConvert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(in *extensions.DeploymentCondition, out *v1beta1.DeploymentCondition, s conversion.Scope) error { +func autoConvert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition(in *apps.DeploymentCondition, out *v1beta1.DeploymentCondition, s conversion.Scope) error { out.Type = v1beta1.DeploymentConditionType(in.Type) out.Status = v1.ConditionStatus(in.Status) out.LastUpdateTime = in.LastUpdateTime @@ -1095,18 +972,18 @@ func autoConvert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(i return nil } -// Convert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition is an autogenerated conversion function. -func Convert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(in *extensions.DeploymentCondition, out *v1beta1.DeploymentCondition, s conversion.Scope) error { - return autoConvert_extensions_DeploymentCondition_To_v1beta1_DeploymentCondition(in, out, s) +// Convert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition is an autogenerated conversion function. +func Convert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition(in *apps.DeploymentCondition, out *v1beta1.DeploymentCondition, s conversion.Scope) error { + return autoConvert_apps_DeploymentCondition_To_v1beta1_DeploymentCondition(in, out, s) } -func autoConvert_v1beta1_DeploymentList_To_extensions_DeploymentList(in *v1beta1.DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { +func autoConvert_v1beta1_DeploymentList_To_apps_DeploymentList(in *v1beta1.DeploymentList, out *apps.DeploymentList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.Deployment, len(*in)) + *out = make([]apps.Deployment, len(*in)) for i := range *in { - if err := Convert_v1beta1_Deployment_To_extensions_Deployment(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1beta1_Deployment_To_apps_Deployment(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -1116,18 +993,18 @@ func autoConvert_v1beta1_DeploymentList_To_extensions_DeploymentList(in *v1beta1 return nil } -// Convert_v1beta1_DeploymentList_To_extensions_DeploymentList is an autogenerated conversion function. -func Convert_v1beta1_DeploymentList_To_extensions_DeploymentList(in *v1beta1.DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { - return autoConvert_v1beta1_DeploymentList_To_extensions_DeploymentList(in, out, s) +// Convert_v1beta1_DeploymentList_To_apps_DeploymentList is an autogenerated conversion function. +func Convert_v1beta1_DeploymentList_To_apps_DeploymentList(in *v1beta1.DeploymentList, out *apps.DeploymentList, s conversion.Scope) error { + return autoConvert_v1beta1_DeploymentList_To_apps_DeploymentList(in, out, s) } -func autoConvert_extensions_DeploymentList_To_v1beta1_DeploymentList(in *extensions.DeploymentList, out *v1beta1.DeploymentList, s conversion.Scope) error { +func autoConvert_apps_DeploymentList_To_v1beta1_DeploymentList(in *apps.DeploymentList, out *v1beta1.DeploymentList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1beta1.Deployment, len(*in)) for i := range *in { - if err := Convert_extensions_Deployment_To_v1beta1_Deployment(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_Deployment_To_v1beta1_Deployment(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -1137,40 +1014,40 @@ func autoConvert_extensions_DeploymentList_To_v1beta1_DeploymentList(in *extensi return nil } -// Convert_extensions_DeploymentList_To_v1beta1_DeploymentList is an autogenerated conversion function. -func Convert_extensions_DeploymentList_To_v1beta1_DeploymentList(in *extensions.DeploymentList, out *v1beta1.DeploymentList, s conversion.Scope) error { - return autoConvert_extensions_DeploymentList_To_v1beta1_DeploymentList(in, out, s) +// Convert_apps_DeploymentList_To_v1beta1_DeploymentList is an autogenerated conversion function. +func Convert_apps_DeploymentList_To_v1beta1_DeploymentList(in *apps.DeploymentList, out *v1beta1.DeploymentList, s conversion.Scope) error { + return autoConvert_apps_DeploymentList_To_v1beta1_DeploymentList(in, out, s) } -func autoConvert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback(in *v1beta1.DeploymentRollback, out *extensions.DeploymentRollback, s conversion.Scope) error { +func autoConvert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback(in *v1beta1.DeploymentRollback, out *apps.DeploymentRollback, s conversion.Scope) error { out.Name = in.Name out.UpdatedAnnotations = *(*map[string]string)(unsafe.Pointer(&in.UpdatedAnnotations)) - if err := Convert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(&in.RollbackTo, &out.RollbackTo, s); err != nil { + if err := Convert_v1beta1_RollbackConfig_To_apps_RollbackConfig(&in.RollbackTo, &out.RollbackTo, s); err != nil { return err } return nil } -// Convert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback is an autogenerated conversion function. -func Convert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback(in *v1beta1.DeploymentRollback, out *extensions.DeploymentRollback, s conversion.Scope) error { - return autoConvert_v1beta1_DeploymentRollback_To_extensions_DeploymentRollback(in, out, s) +// Convert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback is an autogenerated conversion function. +func Convert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback(in *v1beta1.DeploymentRollback, out *apps.DeploymentRollback, s conversion.Scope) error { + return autoConvert_v1beta1_DeploymentRollback_To_apps_DeploymentRollback(in, out, s) } -func autoConvert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback(in *extensions.DeploymentRollback, out *v1beta1.DeploymentRollback, s conversion.Scope) error { +func autoConvert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback(in *apps.DeploymentRollback, out *v1beta1.DeploymentRollback, s conversion.Scope) error { out.Name = in.Name out.UpdatedAnnotations = *(*map[string]string)(unsafe.Pointer(&in.UpdatedAnnotations)) - if err := Convert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(&in.RollbackTo, &out.RollbackTo, s); err != nil { + if err := Convert_apps_RollbackConfig_To_v1beta1_RollbackConfig(&in.RollbackTo, &out.RollbackTo, s); err != nil { return err } return nil } -// Convert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback is an autogenerated conversion function. -func Convert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback(in *extensions.DeploymentRollback, out *v1beta1.DeploymentRollback, s conversion.Scope) error { - return autoConvert_extensions_DeploymentRollback_To_v1beta1_DeploymentRollback(in, out, s) +// Convert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback is an autogenerated conversion function. +func Convert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback(in *apps.DeploymentRollback, out *v1beta1.DeploymentRollback, s conversion.Scope) error { + return autoConvert_apps_DeploymentRollback_To_v1beta1_DeploymentRollback(in, out, s) } -func autoConvert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *v1beta1.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { +func autoConvert_v1beta1_DeploymentSpec_To_apps_DeploymentSpec(in *v1beta1.DeploymentSpec, out *apps.DeploymentSpec, s conversion.Scope) error { if err := metav1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -1178,18 +1055,18 @@ func autoConvert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *v1beta1 if err := corev1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) out.Paused = in.Paused - out.RollbackTo = (*extensions.RollbackConfig)(unsafe.Pointer(in.RollbackTo)) + out.RollbackTo = (*apps.RollbackConfig)(unsafe.Pointer(in.RollbackTo)) out.ProgressDeadlineSeconds = (*int32)(unsafe.Pointer(in.ProgressDeadlineSeconds)) return nil } -func autoConvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.DeploymentSpec, out *v1beta1.DeploymentSpec, s conversion.Scope) error { +func autoConvert_apps_DeploymentSpec_To_v1beta1_DeploymentSpec(in *apps.DeploymentSpec, out *v1beta1.DeploymentSpec, s conversion.Scope) error { if err := metav1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -1197,7 +1074,7 @@ func autoConvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensi if err := corev1.Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - if err := Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := Convert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.MinReadySeconds = in.MinReadySeconds @@ -1208,24 +1085,24 @@ func autoConvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensi return nil } -func autoConvert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in *v1beta1.DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { +func autoConvert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(in *v1beta1.DeploymentStatus, out *apps.DeploymentStatus, s conversion.Scope) error { out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas out.ReadyReplicas = in.ReadyReplicas out.AvailableReplicas = in.AvailableReplicas out.UnavailableReplicas = in.UnavailableReplicas - out.Conditions = *(*[]extensions.DeploymentCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.DeploymentCondition)(unsafe.Pointer(&in.Conditions)) out.CollisionCount = (*int32)(unsafe.Pointer(in.CollisionCount)) return nil } -// Convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus is an autogenerated conversion function. -func Convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in *v1beta1.DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { - return autoConvert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in, out, s) +// Convert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus is an autogenerated conversion function. +func Convert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(in *v1beta1.DeploymentStatus, out *apps.DeploymentStatus, s conversion.Scope) error { + return autoConvert_v1beta1_DeploymentStatus_To_apps_DeploymentStatus(in, out, s) } -func autoConvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *extensions.DeploymentStatus, out *v1beta1.DeploymentStatus, s conversion.Scope) error { +func autoConvert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(in *apps.DeploymentStatus, out *v1beta1.DeploymentStatus, s conversion.Scope) error { out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas @@ -1237,17 +1114,17 @@ func autoConvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *ext return nil } -// Convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus is an autogenerated conversion function. -func Convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *extensions.DeploymentStatus, out *v1beta1.DeploymentStatus, s conversion.Scope) error { - return autoConvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in, out, s) +// Convert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus is an autogenerated conversion function. +func Convert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(in *apps.DeploymentStatus, out *v1beta1.DeploymentStatus, s conversion.Scope) error { + return autoConvert_apps_DeploymentStatus_To_v1beta1_DeploymentStatus(in, out, s) } -func autoConvert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *v1beta1.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { - out.Type = extensions.DeploymentStrategyType(in.Type) +func autoConvert_v1beta1_DeploymentStrategy_To_apps_DeploymentStrategy(in *v1beta1.DeploymentStrategy, out *apps.DeploymentStrategy, s conversion.Scope) error { + out.Type = apps.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(extensions.RollingUpdateDeployment) - if err := Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(*in, *out, s); err != nil { + *out = new(apps.RollingUpdateDeployment) + if err := Convert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(*in, *out, s); err != nil { return err } } else { @@ -1256,12 +1133,12 @@ func autoConvert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in return nil } -func autoConvert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *v1beta1.DeploymentStrategy, s conversion.Scope) error { +func autoConvert_apps_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *apps.DeploymentStrategy, out *v1beta1.DeploymentStrategy, s conversion.Scope) error { out.Type = v1beta1.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { in, out := &in.RollingUpdate, &out.RollingUpdate *out = new(v1beta1.RollingUpdateDeployment) - if err := Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(*in, *out, s); err != nil { + if err := Convert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(*in, *out, s); err != nil { return err } } else { @@ -1726,40 +1603,40 @@ func Convert_policy_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySpec(in *p return autoConvert_policy_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySpec(in, out, s) } -func autoConvert_v1beta1_ReplicaSet_To_extensions_ReplicaSet(in *v1beta1.ReplicaSet, out *extensions.ReplicaSet, s conversion.Scope) error { +func autoConvert_v1beta1_ReplicaSet_To_apps_ReplicaSet(in *v1beta1.ReplicaSet, out *apps.ReplicaSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_v1beta1_ReplicaSetSpec_To_apps_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_v1beta1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_v1beta1_ReplicaSetStatus_To_apps_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_v1beta1_ReplicaSet_To_extensions_ReplicaSet is an autogenerated conversion function. -func Convert_v1beta1_ReplicaSet_To_extensions_ReplicaSet(in *v1beta1.ReplicaSet, out *extensions.ReplicaSet, s conversion.Scope) error { - return autoConvert_v1beta1_ReplicaSet_To_extensions_ReplicaSet(in, out, s) +// Convert_v1beta1_ReplicaSet_To_apps_ReplicaSet is an autogenerated conversion function. +func Convert_v1beta1_ReplicaSet_To_apps_ReplicaSet(in *v1beta1.ReplicaSet, out *apps.ReplicaSet, s conversion.Scope) error { + return autoConvert_v1beta1_ReplicaSet_To_apps_ReplicaSet(in, out, s) } -func autoConvert_extensions_ReplicaSet_To_v1beta1_ReplicaSet(in *extensions.ReplicaSet, out *v1beta1.ReplicaSet, s conversion.Scope) error { +func autoConvert_apps_ReplicaSet_To_v1beta1_ReplicaSet(in *apps.ReplicaSet, out *v1beta1.ReplicaSet, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - if err := Convert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { + if err := Convert_apps_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { return err } - if err := Convert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { + if err := Convert_apps_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { return err } return nil } -// Convert_extensions_ReplicaSet_To_v1beta1_ReplicaSet is an autogenerated conversion function. -func Convert_extensions_ReplicaSet_To_v1beta1_ReplicaSet(in *extensions.ReplicaSet, out *v1beta1.ReplicaSet, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSet_To_v1beta1_ReplicaSet(in, out, s) +// Convert_apps_ReplicaSet_To_v1beta1_ReplicaSet is an autogenerated conversion function. +func Convert_apps_ReplicaSet_To_v1beta1_ReplicaSet(in *apps.ReplicaSet, out *v1beta1.ReplicaSet, s conversion.Scope) error { + return autoConvert_apps_ReplicaSet_To_v1beta1_ReplicaSet(in, out, s) } -func autoConvert_v1beta1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in *v1beta1.ReplicaSetCondition, out *extensions.ReplicaSetCondition, s conversion.Scope) error { - out.Type = extensions.ReplicaSetConditionType(in.Type) +func autoConvert_v1beta1_ReplicaSetCondition_To_apps_ReplicaSetCondition(in *v1beta1.ReplicaSetCondition, out *apps.ReplicaSetCondition, s conversion.Scope) error { + out.Type = apps.ReplicaSetConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime out.Reason = in.Reason @@ -1767,12 +1644,12 @@ func autoConvert_v1beta1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(i return nil } -// Convert_v1beta1_ReplicaSetCondition_To_extensions_ReplicaSetCondition is an autogenerated conversion function. -func Convert_v1beta1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in *v1beta1.ReplicaSetCondition, out *extensions.ReplicaSetCondition, s conversion.Scope) error { - return autoConvert_v1beta1_ReplicaSetCondition_To_extensions_ReplicaSetCondition(in, out, s) +// Convert_v1beta1_ReplicaSetCondition_To_apps_ReplicaSetCondition is an autogenerated conversion function. +func Convert_v1beta1_ReplicaSetCondition_To_apps_ReplicaSetCondition(in *v1beta1.ReplicaSetCondition, out *apps.ReplicaSetCondition, s conversion.Scope) error { + return autoConvert_v1beta1_ReplicaSetCondition_To_apps_ReplicaSetCondition(in, out, s) } -func autoConvert_extensions_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(in *extensions.ReplicaSetCondition, out *v1beta1.ReplicaSetCondition, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(in *apps.ReplicaSetCondition, out *v1beta1.ReplicaSetCondition, s conversion.Scope) error { out.Type = v1beta1.ReplicaSetConditionType(in.Type) out.Status = v1.ConditionStatus(in.Status) out.LastTransitionTime = in.LastTransitionTime @@ -1781,18 +1658,18 @@ func autoConvert_extensions_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(i return nil } -// Convert_extensions_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition is an autogenerated conversion function. -func Convert_extensions_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(in *extensions.ReplicaSetCondition, out *v1beta1.ReplicaSetCondition, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(in, out, s) +// Convert_apps_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition is an autogenerated conversion function. +func Convert_apps_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(in *apps.ReplicaSetCondition, out *v1beta1.ReplicaSetCondition, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetCondition_To_v1beta1_ReplicaSetCondition(in, out, s) } -func autoConvert_v1beta1_ReplicaSetList_To_extensions_ReplicaSetList(in *v1beta1.ReplicaSetList, out *extensions.ReplicaSetList, s conversion.Scope) error { +func autoConvert_v1beta1_ReplicaSetList_To_apps_ReplicaSetList(in *v1beta1.ReplicaSetList, out *apps.ReplicaSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]extensions.ReplicaSet, len(*in)) + *out = make([]apps.ReplicaSet, len(*in)) for i := range *in { - if err := Convert_v1beta1_ReplicaSet_To_extensions_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_v1beta1_ReplicaSet_To_apps_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -1802,18 +1679,18 @@ func autoConvert_v1beta1_ReplicaSetList_To_extensions_ReplicaSetList(in *v1beta1 return nil } -// Convert_v1beta1_ReplicaSetList_To_extensions_ReplicaSetList is an autogenerated conversion function. -func Convert_v1beta1_ReplicaSetList_To_extensions_ReplicaSetList(in *v1beta1.ReplicaSetList, out *extensions.ReplicaSetList, s conversion.Scope) error { - return autoConvert_v1beta1_ReplicaSetList_To_extensions_ReplicaSetList(in, out, s) +// Convert_v1beta1_ReplicaSetList_To_apps_ReplicaSetList is an autogenerated conversion function. +func Convert_v1beta1_ReplicaSetList_To_apps_ReplicaSetList(in *v1beta1.ReplicaSetList, out *apps.ReplicaSetList, s conversion.Scope) error { + return autoConvert_v1beta1_ReplicaSetList_To_apps_ReplicaSetList(in, out, s) } -func autoConvert_extensions_ReplicaSetList_To_v1beta1_ReplicaSetList(in *extensions.ReplicaSetList, out *v1beta1.ReplicaSetList, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetList_To_v1beta1_ReplicaSetList(in *apps.ReplicaSetList, out *v1beta1.ReplicaSetList, s conversion.Scope) error { out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]v1beta1.ReplicaSet, len(*in)) for i := range *in { - if err := Convert_extensions_ReplicaSet_To_v1beta1_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { + if err := Convert_apps_ReplicaSet_To_v1beta1_ReplicaSet(&(*in)[i], &(*out)[i], s); err != nil { return err } } @@ -1823,12 +1700,12 @@ func autoConvert_extensions_ReplicaSetList_To_v1beta1_ReplicaSetList(in *extensi return nil } -// Convert_extensions_ReplicaSetList_To_v1beta1_ReplicaSetList is an autogenerated conversion function. -func Convert_extensions_ReplicaSetList_To_v1beta1_ReplicaSetList(in *extensions.ReplicaSetList, out *v1beta1.ReplicaSetList, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetList_To_v1beta1_ReplicaSetList(in, out, s) +// Convert_apps_ReplicaSetList_To_v1beta1_ReplicaSetList is an autogenerated conversion function. +func Convert_apps_ReplicaSetList_To_v1beta1_ReplicaSetList(in *apps.ReplicaSetList, out *v1beta1.ReplicaSetList, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetList_To_v1beta1_ReplicaSetList(in, out, s) } -func autoConvert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *v1beta1.ReplicaSetSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error { +func autoConvert_v1beta1_ReplicaSetSpec_To_apps_ReplicaSetSpec(in *v1beta1.ReplicaSetSpec, out *apps.ReplicaSetSpec, s conversion.Scope) error { if err := metav1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -1840,7 +1717,7 @@ func autoConvert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *v1beta1 return nil } -func autoConvert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(in *extensions.ReplicaSetSpec, out *v1beta1.ReplicaSetSpec, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(in *apps.ReplicaSetSpec, out *v1beta1.ReplicaSetSpec, s conversion.Scope) error { if err := metav1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil { return err } @@ -1852,22 +1729,22 @@ func autoConvert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(in *extensi return nil } -func autoConvert_v1beta1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in *v1beta1.ReplicaSetStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error { +func autoConvert_v1beta1_ReplicaSetStatus_To_apps_ReplicaSetStatus(in *v1beta1.ReplicaSetStatus, out *apps.ReplicaSetStatus, s conversion.Scope) error { out.Replicas = in.Replicas out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ReadyReplicas = in.ReadyReplicas out.AvailableReplicas = in.AvailableReplicas out.ObservedGeneration = in.ObservedGeneration - out.Conditions = *(*[]extensions.ReplicaSetCondition)(unsafe.Pointer(&in.Conditions)) + out.Conditions = *(*[]apps.ReplicaSetCondition)(unsafe.Pointer(&in.Conditions)) return nil } -// Convert_v1beta1_ReplicaSetStatus_To_extensions_ReplicaSetStatus is an autogenerated conversion function. -func Convert_v1beta1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in *v1beta1.ReplicaSetStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error { - return autoConvert_v1beta1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in, out, s) +// Convert_v1beta1_ReplicaSetStatus_To_apps_ReplicaSetStatus is an autogenerated conversion function. +func Convert_v1beta1_ReplicaSetStatus_To_apps_ReplicaSetStatus(in *v1beta1.ReplicaSetStatus, out *apps.ReplicaSetStatus, s conversion.Scope) error { + return autoConvert_v1beta1_ReplicaSetStatus_To_apps_ReplicaSetStatus(in, out, s) } -func autoConvert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(in *extensions.ReplicaSetStatus, out *v1beta1.ReplicaSetStatus, s conversion.Scope) error { +func autoConvert_apps_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(in *apps.ReplicaSetStatus, out *v1beta1.ReplicaSetStatus, s conversion.Scope) error { out.Replicas = in.Replicas out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ReadyReplicas = in.ReadyReplicas @@ -1877,9 +1754,9 @@ func autoConvert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(in *ext return nil } -// Convert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus is an autogenerated conversion function. -func Convert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(in *extensions.ReplicaSetStatus, out *v1beta1.ReplicaSetStatus, s conversion.Scope) error { - return autoConvert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(in, out, s) +// Convert_apps_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus is an autogenerated conversion function. +func Convert_apps_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(in *apps.ReplicaSetStatus, out *v1beta1.ReplicaSetStatus, s conversion.Scope) error { + return autoConvert_apps_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(in, out, s) } func autoConvert_v1beta1_ReplicationControllerDummy_To_extensions_ReplicationControllerDummy(in *v1beta1.ReplicationControllerDummy, out *extensions.ReplicationControllerDummy, s conversion.Scope) error { @@ -1900,43 +1777,43 @@ func Convert_extensions_ReplicationControllerDummy_To_v1beta1_ReplicationControl return autoConvert_extensions_ReplicationControllerDummy_To_v1beta1_ReplicationControllerDummy(in, out, s) } -func autoConvert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(in *v1beta1.RollbackConfig, out *extensions.RollbackConfig, s conversion.Scope) error { +func autoConvert_v1beta1_RollbackConfig_To_apps_RollbackConfig(in *v1beta1.RollbackConfig, out *apps.RollbackConfig, s conversion.Scope) error { out.Revision = in.Revision return nil } -// Convert_v1beta1_RollbackConfig_To_extensions_RollbackConfig is an autogenerated conversion function. -func Convert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(in *v1beta1.RollbackConfig, out *extensions.RollbackConfig, s conversion.Scope) error { - return autoConvert_v1beta1_RollbackConfig_To_extensions_RollbackConfig(in, out, s) +// Convert_v1beta1_RollbackConfig_To_apps_RollbackConfig is an autogenerated conversion function. +func Convert_v1beta1_RollbackConfig_To_apps_RollbackConfig(in *v1beta1.RollbackConfig, out *apps.RollbackConfig, s conversion.Scope) error { + return autoConvert_v1beta1_RollbackConfig_To_apps_RollbackConfig(in, out, s) } -func autoConvert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(in *extensions.RollbackConfig, out *v1beta1.RollbackConfig, s conversion.Scope) error { +func autoConvert_apps_RollbackConfig_To_v1beta1_RollbackConfig(in *apps.RollbackConfig, out *v1beta1.RollbackConfig, s conversion.Scope) error { out.Revision = in.Revision return nil } -// Convert_extensions_RollbackConfig_To_v1beta1_RollbackConfig is an autogenerated conversion function. -func Convert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(in *extensions.RollbackConfig, out *v1beta1.RollbackConfig, s conversion.Scope) error { - return autoConvert_extensions_RollbackConfig_To_v1beta1_RollbackConfig(in, out, s) +// Convert_apps_RollbackConfig_To_v1beta1_RollbackConfig is an autogenerated conversion function. +func Convert_apps_RollbackConfig_To_v1beta1_RollbackConfig(in *apps.RollbackConfig, out *v1beta1.RollbackConfig, s conversion.Scope) error { + return autoConvert_apps_RollbackConfig_To_v1beta1_RollbackConfig(in, out, s) } -func autoConvert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in *v1beta1.RollingUpdateDaemonSet, out *extensions.RollingUpdateDaemonSet, s conversion.Scope) error { +func autoConvert_v1beta1_RollingUpdateDaemonSet_To_apps_RollingUpdateDaemonSet(in *v1beta1.RollingUpdateDaemonSet, out *apps.RollingUpdateDaemonSet, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *v1beta1.RollingUpdateDaemonSet, s conversion.Scope) error { +func autoConvert_apps_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(in *apps.RollingUpdateDaemonSet, out *v1beta1.RollingUpdateDaemonSet, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *v1beta1.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { +func autoConvert_v1beta1_RollingUpdateDeployment_To_apps_RollingUpdateDeployment(in *v1beta1.RollingUpdateDeployment, out *apps.RollingUpdateDeployment, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) // WARNING: in.MaxSurge requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/util/intstr.IntOrString vs k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil } -func autoConvert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *v1beta1.RollingUpdateDeployment, s conversion.Scope) error { +func autoConvert_apps_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *apps.RollingUpdateDeployment, out *v1beta1.RollingUpdateDeployment, s conversion.Scope) error { // WARNING: in.MaxUnavailable requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) // WARNING: in.MaxSurge requires manual conversion: inconvertible types (k8s.io/apimachinery/pkg/util/intstr.IntOrString vs *k8s.io/apimachinery/pkg/util/intstr.IntOrString) return nil diff --git a/pkg/apis/extensions/validation/BUILD b/pkg/apis/extensions/validation/BUILD index 7e5cb10616b2f..f734bdefe4ef9 100644 --- a/pkg/apis/extensions/validation/BUILD +++ b/pkg/apis/extensions/validation/BUILD @@ -11,15 +11,9 @@ go_library( srcs = ["validation.go"], importpath = "k8s.io/kubernetes/pkg/apis/extensions/validation", deps = [ - "//pkg/apis/core:go_default_library", "//pkg/apis/core/validation:go_default_library", "//pkg/apis/extensions:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", ], @@ -34,8 +28,6 @@ go_test( "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", - "//vendor/github.com/davecgh/go-spew/spew:go_default_library", ], ) diff --git a/pkg/apis/extensions/validation/validation.go b/pkg/apis/extensions/validation/validation.go index 36c191c17fb62..0ada34ce60685 100644 --- a/pkg/apis/extensions/validation/validation.go +++ b/pkg/apis/extensions/validation/validation.go @@ -19,347 +19,15 @@ package validation import ( "net" "regexp" - "strconv" "strings" - apiequality "k8s.io/apimachinery/pkg/api/equality" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" - api "k8s.io/kubernetes/pkg/apis/core" apivalidation "k8s.io/kubernetes/pkg/apis/core/validation" "k8s.io/kubernetes/pkg/apis/extensions" ) -// ValidateDaemonSet tests if required fields in the DaemonSet are set. -func ValidateDaemonSet(ds *extensions.DaemonSet) field.ErrorList { - allErrs := apivalidation.ValidateObjectMeta(&ds.ObjectMeta, true, ValidateDaemonSetName, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateDaemonSetSpec(&ds.Spec, field.NewPath("spec"))...) - return allErrs -} - -// ValidateDaemonSetUpdate tests if required fields in the DaemonSet are set. -func ValidateDaemonSetUpdate(ds, oldDS *extensions.DaemonSet) field.ErrorList { - allErrs := apivalidation.ValidateObjectMetaUpdate(&ds.ObjectMeta, &oldDS.ObjectMeta, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateDaemonSetSpecUpdate(&ds.Spec, &oldDS.Spec, field.NewPath("spec"))...) - allErrs = append(allErrs, ValidateDaemonSetSpec(&ds.Spec, field.NewPath("spec"))...) - return allErrs -} - -func ValidateDaemonSetSpecUpdate(newSpec, oldSpec *extensions.DaemonSetSpec, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - - // TemplateGeneration shouldn't be decremented - if newSpec.TemplateGeneration < oldSpec.TemplateGeneration { - allErrs = append(allErrs, field.Invalid(fldPath.Child("templateGeneration"), newSpec.TemplateGeneration, "must not be decremented")) - } - - // TemplateGeneration should be increased when and only when template is changed - templateUpdated := !apiequality.Semantic.DeepEqual(newSpec.Template, oldSpec.Template) - if newSpec.TemplateGeneration == oldSpec.TemplateGeneration && templateUpdated { - allErrs = append(allErrs, field.Invalid(fldPath.Child("templateGeneration"), newSpec.TemplateGeneration, "must be incremented upon template update")) - } else if newSpec.TemplateGeneration > oldSpec.TemplateGeneration && !templateUpdated { - allErrs = append(allErrs, field.Invalid(fldPath.Child("templateGeneration"), newSpec.TemplateGeneration, "must not be incremented without template update")) - } - - return allErrs -} - -// validateDaemonSetStatus validates a DaemonSetStatus -func validateDaemonSetStatus(status *extensions.DaemonSetStatus, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.CurrentNumberScheduled), fldPath.Child("currentNumberScheduled"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.NumberMisscheduled), fldPath.Child("numberMisscheduled"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.DesiredNumberScheduled), fldPath.Child("desiredNumberScheduled"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.NumberReady), fldPath.Child("numberReady"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(status.ObservedGeneration, fldPath.Child("observedGeneration"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UpdatedNumberScheduled), fldPath.Child("updatedNumberScheduled"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.NumberAvailable), fldPath.Child("numberAvailable"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.NumberUnavailable), fldPath.Child("numberUnavailable"))...) - if status.CollisionCount != nil { - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*status.CollisionCount), fldPath.Child("collisionCount"))...) - } - return allErrs -} - -// ValidateDaemonSetStatus validates tests if required fields in the DaemonSet Status section -func ValidateDaemonSetStatusUpdate(ds, oldDS *extensions.DaemonSet) field.ErrorList { - allErrs := apivalidation.ValidateObjectMetaUpdate(&ds.ObjectMeta, &oldDS.ObjectMeta, field.NewPath("metadata")) - allErrs = append(allErrs, validateDaemonSetStatus(&ds.Status, field.NewPath("status"))...) - if apivalidation.IsDecremented(ds.Status.CollisionCount, oldDS.Status.CollisionCount) { - value := int32(0) - if ds.Status.CollisionCount != nil { - value = *ds.Status.CollisionCount - } - allErrs = append(allErrs, field.Invalid(field.NewPath("status").Child("collisionCount"), value, "cannot be decremented")) - } - return allErrs -} - -// ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set. -func ValidateDaemonSetSpec(spec *extensions.DaemonSetSpec, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - - allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) - - selector, err := metav1.LabelSelectorAsSelector(spec.Selector) - if err == nil && !selector.Matches(labels.Set(spec.Template.Labels)) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "metadata", "labels"), spec.Template.Labels, "`selector` does not match template `labels`")) - } - if spec.Selector != nil && len(spec.Selector.MatchLabels)+len(spec.Selector.MatchExpressions) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "empty selector is invalid for daemonset")) - } - - allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(&spec.Template, fldPath.Child("template"))...) - // Daemons typically run on more than one node, so mark Read-Write persistent disks as invalid. - allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(spec.Template.Spec.Volumes, fldPath.Child("template", "spec", "volumes"))...) - // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). - if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways { - allErrs = append(allErrs, field.NotSupported(fldPath.Child("template", "spec", "restartPolicy"), spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) - } - if spec.Template.Spec.ActiveDeadlineSeconds != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "spec", "activeDeadlineSeconds"), spec.Template.Spec.ActiveDeadlineSeconds, "must not be specified")) - } - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.TemplateGeneration), fldPath.Child("templateGeneration"))...) - - allErrs = append(allErrs, ValidateDaemonSetUpdateStrategy(&spec.UpdateStrategy, fldPath.Child("updateStrategy"))...) - if spec.RevisionHistoryLimit != nil { - // zero is a valid RevisionHistoryLimit - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.RevisionHistoryLimit), fldPath.Child("revisionHistoryLimit"))...) - } - return allErrs -} - -func ValidateRollingUpdateDaemonSet(rollingUpdate *extensions.RollingUpdateDaemonSet, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) - if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 { - // MaxUnavailable cannot be 0. - allErrs = append(allErrs, field.Invalid(fldPath.Child("maxUnavailable"), rollingUpdate.MaxUnavailable, "cannot be 0")) - } - // Validate that MaxUnavailable is not more than 100%. - allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) - return allErrs -} - -func ValidateDaemonSetUpdateStrategy(strategy *extensions.DaemonSetUpdateStrategy, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - switch strategy.Type { - case extensions.OnDeleteDaemonSetStrategyType: - case extensions.RollingUpdateDaemonSetStrategyType: - // Make sure RollingUpdate field isn't nil. - if strategy.RollingUpdate == nil { - allErrs = append(allErrs, field.Required(fldPath.Child("rollingUpdate"), "")) - return allErrs - } - allErrs = append(allErrs, ValidateRollingUpdateDaemonSet(strategy.RollingUpdate, fldPath.Child("rollingUpdate"))...) - default: - validValues := []string{string(extensions.RollingUpdateDaemonSetStrategyType), string(extensions.OnDeleteDaemonSetStrategyType)} - allErrs = append(allErrs, field.NotSupported(fldPath, strategy, validValues)) - } - return allErrs -} - -// ValidateDaemonSetName can be used to check whether the given daemon set name is valid. -// Prefix indicates this name will be used as part of generation, in which case -// trailing dashes are allowed. -var ValidateDaemonSetName = apimachineryvalidation.NameIsDNSSubdomain - -// Validates that the given name can be used as a deployment name. -var ValidateDeploymentName = apimachineryvalidation.NameIsDNSSubdomain - -func ValidatePositiveIntOrPercent(intOrPercent intstr.IntOrString, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - switch intOrPercent.Type { - case intstr.String: - for _, msg := range validation.IsValidPercent(intOrPercent.StrVal) { - allErrs = append(allErrs, field.Invalid(fldPath, intOrPercent, msg)) - } - case intstr.Int: - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(intOrPercent.IntValue()), fldPath)...) - default: - allErrs = append(allErrs, field.Invalid(fldPath, intOrPercent, "must be an integer or percentage (e.g '5%%')")) - } - return allErrs -} - -func getPercentValue(intOrStringValue intstr.IntOrString) (int, bool) { - if intOrStringValue.Type != intstr.String { - return 0, false - } - if len(validation.IsValidPercent(intOrStringValue.StrVal)) != 0 { - return 0, false - } - value, _ := strconv.Atoi(intOrStringValue.StrVal[:len(intOrStringValue.StrVal)-1]) - return value, true -} - -func getIntOrPercentValue(intOrStringValue intstr.IntOrString) int { - value, isPercent := getPercentValue(intOrStringValue) - if isPercent { - return value - } - return intOrStringValue.IntValue() -} - -func IsNotMoreThan100Percent(intOrStringValue intstr.IntOrString, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - value, isPercent := getPercentValue(intOrStringValue) - if !isPercent || value <= 100 { - return nil - } - allErrs = append(allErrs, field.Invalid(fldPath, intOrStringValue, "must not be greater than 100%")) - return allErrs -} - -func ValidateRollingUpdateDeployment(rollingUpdate *extensions.RollingUpdateDeployment, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) - allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxSurge, fldPath.Child("maxSurge"))...) - if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 && getIntOrPercentValue(rollingUpdate.MaxSurge) == 0 { - // Both MaxSurge and MaxUnavailable cannot be zero. - allErrs = append(allErrs, field.Invalid(fldPath.Child("maxUnavailable"), rollingUpdate.MaxUnavailable, "may not be 0 when `maxSurge` is 0")) - } - // Validate that MaxUnavailable is not more than 100%. - allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) - return allErrs -} - -func ValidateDeploymentStrategy(strategy *extensions.DeploymentStrategy, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - switch strategy.Type { - case extensions.RecreateDeploymentStrategyType: - if strategy.RollingUpdate != nil { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("rollingUpdate"), "may not be specified when strategy `type` is '"+string(extensions.RecreateDeploymentStrategyType+"'"))) - } - case extensions.RollingUpdateDeploymentStrategyType: - // This should never happen since it's set and checked in defaults.go - if strategy.RollingUpdate == nil { - allErrs = append(allErrs, field.Required(fldPath.Child("rollingUpdate"), "this should be defaulted and never be nil")) - } else { - allErrs = append(allErrs, ValidateRollingUpdateDeployment(strategy.RollingUpdate, fldPath.Child("rollingUpdate"))...) - } - default: - validValues := []string{string(extensions.RecreateDeploymentStrategyType), string(extensions.RollingUpdateDeploymentStrategyType)} - allErrs = append(allErrs, field.NotSupported(fldPath, strategy, validValues)) - } - return allErrs -} - -func ValidateRollback(rollback *extensions.RollbackConfig, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - v := rollback.Revision - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(v), fldPath.Child("version"))...) - return allErrs -} - -// Validates given deployment spec. -func ValidateDeploymentSpec(spec *extensions.DeploymentSpec, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) - - if spec.Selector == nil { - allErrs = append(allErrs, field.Required(fldPath.Child("selector"), "")) - } else { - allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) - if len(spec.Selector.MatchLabels)+len(spec.Selector.MatchExpressions) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "empty selector is invalid for deployment")) - } - } - - selector, err := metav1.LabelSelectorAsSelector(spec.Selector) - if err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector")) - } else { - allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"))...) - } - - allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, fldPath.Child("strategy"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) - if spec.RevisionHistoryLimit != nil { - // zero is a valid RevisionHistoryLimit - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.RevisionHistoryLimit), fldPath.Child("revisionHistoryLimit"))...) - } - if spec.RollbackTo != nil { - allErrs = append(allErrs, ValidateRollback(spec.RollbackTo, fldPath.Child("rollback"))...) - } - if spec.ProgressDeadlineSeconds != nil { - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.ProgressDeadlineSeconds), fldPath.Child("progressDeadlineSeconds"))...) - if *spec.ProgressDeadlineSeconds <= spec.MinReadySeconds { - allErrs = append(allErrs, field.Invalid(fldPath.Child("progressDeadlineSeconds"), spec.ProgressDeadlineSeconds, "must be greater than minReadySeconds")) - } - } - return allErrs -} - -// Validates given deployment status. -func ValidateDeploymentStatus(status *extensions.DeploymentStatus, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(status.ObservedGeneration, fldPath.Child("observedGeneration"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Replicas), fldPath.Child("replicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UpdatedReplicas), fldPath.Child("updatedReplicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ReadyReplicas), fldPath.Child("readyReplicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.AvailableReplicas), fldPath.Child("availableReplicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UnavailableReplicas), fldPath.Child("unavailableReplicas"))...) - if status.CollisionCount != nil { - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*status.CollisionCount), fldPath.Child("collisionCount"))...) - } - msg := "cannot be greater than status.replicas" - if status.UpdatedReplicas > status.Replicas { - allErrs = append(allErrs, field.Invalid(fldPath.Child("updatedReplicas"), status.UpdatedReplicas, msg)) - } - if status.ReadyReplicas > status.Replicas { - allErrs = append(allErrs, field.Invalid(fldPath.Child("readyReplicas"), status.ReadyReplicas, msg)) - } - if status.AvailableReplicas > status.Replicas { - allErrs = append(allErrs, field.Invalid(fldPath.Child("availableReplicas"), status.AvailableReplicas, msg)) - } - if status.AvailableReplicas > status.ReadyReplicas { - allErrs = append(allErrs, field.Invalid(fldPath.Child("availableReplicas"), status.AvailableReplicas, "cannot be greater than readyReplicas")) - } - return allErrs -} - -func ValidateDeploymentUpdate(update, old *extensions.Deployment) field.ErrorList { - allErrs := apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateDeploymentSpec(&update.Spec, field.NewPath("spec"))...) - return allErrs -} - -func ValidateDeploymentStatusUpdate(update, old *extensions.Deployment) field.ErrorList { - allErrs := apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata")) - fldPath := field.NewPath("status") - allErrs = append(allErrs, ValidateDeploymentStatus(&update.Status, fldPath)...) - if apivalidation.IsDecremented(update.Status.CollisionCount, old.Status.CollisionCount) { - value := int32(0) - if update.Status.CollisionCount != nil { - value = *update.Status.CollisionCount - } - allErrs = append(allErrs, field.Invalid(fldPath.Child("collisionCount"), value, "cannot be decremented")) - } - return allErrs -} - -func ValidateDeployment(obj *extensions.Deployment) field.ErrorList { - allErrs := apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, ValidateDeploymentName, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateDeploymentSpec(&obj.Spec, field.NewPath("spec"))...) - return allErrs -} - -func ValidateDeploymentRollback(obj *extensions.DeploymentRollback) field.ErrorList { - allErrs := apivalidation.ValidateAnnotations(obj.UpdatedAnnotations, field.NewPath("updatedAnnotations")) - if len(obj.Name) == 0 { - allErrs = append(allErrs, field.Required(field.NewPath("name"), "name is required")) - } - allErrs = append(allErrs, ValidateRollback(&obj.RollbackTo, field.NewPath("rollback"))...) - return allErrs -} - // ValidateIngress tests if required fields in the Ingress are set. func ValidateIngress(ingress *extensions.Ingress) field.ErrorList { allErrs := apivalidation.ValidateObjectMeta(&ingress.ObjectMeta, true, ValidateIngressName, field.NewPath("metadata")) @@ -502,108 +170,3 @@ func validateIngressBackend(backend *extensions.IngressBackend, fldPath *field.P allErrs = append(allErrs, apivalidation.ValidatePortNumOrName(backend.ServicePort, fldPath.Child("servicePort"))...) return allErrs } - -// ValidateReplicaSetName can be used to check whether the given ReplicaSet -// name is valid. -// Prefix indicates this name will be used as part of generation, in which case -// trailing dashes are allowed. -var ValidateReplicaSetName = apimachineryvalidation.NameIsDNSSubdomain - -// ValidateReplicaSet tests if required fields in the ReplicaSet are set. -func ValidateReplicaSet(rs *extensions.ReplicaSet) field.ErrorList { - allErrs := apivalidation.ValidateObjectMeta(&rs.ObjectMeta, true, ValidateReplicaSetName, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateReplicaSetSpec(&rs.Spec, field.NewPath("spec"))...) - return allErrs -} - -// ValidateReplicaSetUpdate tests if required fields in the ReplicaSet are set. -func ValidateReplicaSetUpdate(rs, oldRs *extensions.ReplicaSet) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&rs.ObjectMeta, &oldRs.ObjectMeta, field.NewPath("metadata"))...) - allErrs = append(allErrs, ValidateReplicaSetSpec(&rs.Spec, field.NewPath("spec"))...) - return allErrs -} - -// ValidateReplicaSetStatusUpdate tests if required fields in the ReplicaSet are set. -func ValidateReplicaSetStatusUpdate(rs, oldRs *extensions.ReplicaSet) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&rs.ObjectMeta, &oldRs.ObjectMeta, field.NewPath("metadata"))...) - allErrs = append(allErrs, ValidateReplicaSetStatus(rs.Status, field.NewPath("status"))...) - return allErrs -} - -func ValidateReplicaSetStatus(status extensions.ReplicaSetStatus, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Replicas), fldPath.Child("replicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.FullyLabeledReplicas), fldPath.Child("fullyLabeledReplicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ReadyReplicas), fldPath.Child("readyReplicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.AvailableReplicas), fldPath.Child("availableReplicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ObservedGeneration), fldPath.Child("observedGeneration"))...) - msg := "cannot be greater than status.replicas" - if status.FullyLabeledReplicas > status.Replicas { - allErrs = append(allErrs, field.Invalid(fldPath.Child("fullyLabeledReplicas"), status.FullyLabeledReplicas, msg)) - } - if status.ReadyReplicas > status.Replicas { - allErrs = append(allErrs, field.Invalid(fldPath.Child("readyReplicas"), status.ReadyReplicas, msg)) - } - if status.AvailableReplicas > status.Replicas { - allErrs = append(allErrs, field.Invalid(fldPath.Child("availableReplicas"), status.AvailableReplicas, msg)) - } - if status.AvailableReplicas > status.ReadyReplicas { - allErrs = append(allErrs, field.Invalid(fldPath.Child("availableReplicas"), status.AvailableReplicas, "cannot be greater than readyReplicas")) - } - return allErrs -} - -// ValidateReplicaSetSpec tests if required fields in the ReplicaSet spec are set. -func ValidateReplicaSetSpec(spec *extensions.ReplicaSetSpec, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) - - if spec.Selector == nil { - allErrs = append(allErrs, field.Required(fldPath.Child("selector"), "")) - } else { - allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) - if len(spec.Selector.MatchLabels)+len(spec.Selector.MatchExpressions) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "empty selector is invalid for deployment")) - } - } - - selector, err := metav1.LabelSelectorAsSelector(spec.Selector) - if err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector")) - } else { - allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"))...) - } - return allErrs -} - -// Validates the given template and ensures that it is in accordance with the desired selector and replicas. -func ValidatePodTemplateSpecForReplicaSet(template *api.PodTemplateSpec, selector labels.Selector, replicas int32, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - if template == nil { - allErrs = append(allErrs, field.Required(fldPath, "")) - } else { - if !selector.Empty() { - // Verify that the ReplicaSet selector matches the labels in template. - labels := labels.Set(template.Labels) - if !selector.Matches(labels) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("metadata", "labels"), template.Labels, "`selector` does not match template `labels`")) - } - } - allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(template, fldPath)...) - if replicas > 1 { - allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(template.Spec.Volumes, fldPath.Child("spec", "volumes"))...) - } - // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). - if template.Spec.RestartPolicy != api.RestartPolicyAlways { - allErrs = append(allErrs, field.NotSupported(fldPath.Child("spec", "restartPolicy"), template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) - } - if template.Spec.ActiveDeadlineSeconds != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("spec", "activeDeadlineSeconds"), template.Spec.ActiveDeadlineSeconds, "must not be specified")) - } - } - return allErrs -} diff --git a/pkg/apis/extensions/validation/validation_test.go b/pkg/apis/extensions/validation/validation_test.go index cd56129a9e3a8..2d99683788912 100644 --- a/pkg/apis/extensions/validation/validation_test.go +++ b/pkg/apis/extensions/validation/validation_test.go @@ -21,1449 +21,11 @@ import ( "strings" "testing" - "github.com/davecgh/go-spew/spew" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/apimachinery/pkg/util/validation/field" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" -) - -func TestValidateDaemonSetStatusUpdate(t *testing.T) { - type dsUpdateTest struct { - old extensions.DaemonSet - update extensions.DaemonSet - } - - successCases := []dsUpdateTest{ - { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 1, - DesiredNumberScheduled: 3, - NumberReady: 1, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - }, - } - - for _, successCase := range successCases { - successCase.old.ObjectMeta.ResourceVersion = "1" - successCase.update.ObjectMeta.ResourceVersion = "1" - if errs := ValidateDaemonSetStatusUpdate(&successCase.update, &successCase.old); len(errs) != 0 { - t.Errorf("expected success: %v", errs) - } - } - errorCases := map[string]dsUpdateTest{ - "negative values": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: -1, - NumberMisscheduled: -1, - DesiredNumberScheduled: -3, - NumberReady: -1, - ObservedGeneration: -3, - UpdatedNumberScheduled: -1, - NumberAvailable: -1, - NumberUnavailable: -2, - }, - }, - }, - "negative CurrentNumberScheduled": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: -1, - NumberMisscheduled: 1, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - }, - "negative NumberMisscheduled": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: -1, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - }, - "negative DesiredNumberScheduled": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 1, - DesiredNumberScheduled: -3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - }, - "negative NumberReady": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 1, - DesiredNumberScheduled: 3, - NumberReady: -1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - }, - "negative ObservedGeneration": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 1, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: -3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - }, - "negative UpdatedNumberScheduled": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 1, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: -1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - }, - "negative NumberAvailable": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 1, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: -1, - NumberUnavailable: 2, - }, - }, - }, - "negative NumberUnavailable": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 2, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: 2, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - ResourceVersion: "10", - }, - Status: extensions.DaemonSetStatus{ - CurrentNumberScheduled: 1, - NumberMisscheduled: 1, - DesiredNumberScheduled: 3, - NumberReady: 1, - ObservedGeneration: 3, - UpdatedNumberScheduled: 1, - NumberAvailable: 1, - NumberUnavailable: -2, - }, - }, - }, - } - - for testName, errorCase := range errorCases { - if errs := ValidateDaemonSetStatusUpdate(&errorCase.update, &errorCase.old); len(errs) == 0 { - t.Errorf("expected failure: %s", testName) - } - } -} - -func TestValidateDaemonSetUpdate(t *testing.T) { - validSelector := map[string]string{"a": "b"} - validSelector2 := map[string]string{"c": "d"} - invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} - - validPodSpecAbc := api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - } - validPodSpecDef := api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - } - validPodSpecNodeSelector := api.PodSpec{ - NodeSelector: validSelector, - NodeName: "xyz", - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - } - validPodSpecVolume := api.PodSpec{ - Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - } - - validPodTemplateAbc := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector, - }, - Spec: validPodSpecAbc, - }, - } - validPodTemplateAbcSemanticallyEqual := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector, - }, - Spec: validPodSpecAbc, - }, - } - validPodTemplateAbcSemanticallyEqual.Template.Spec.ImagePullSecrets = []api.LocalObjectReference{} - validPodTemplateNodeSelector := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector, - }, - Spec: validPodSpecNodeSelector, - }, - } - validPodTemplateAbc2 := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector2, - }, - Spec: validPodSpecAbc, - }, - } - validPodTemplateDef := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector2, - }, - Spec: validPodSpecDef, - }, - } - invalidPodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - Spec: api.PodSpec{ - // no containers specified - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - }, - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector, - }, - }, - } - readWriteVolumePodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector, - }, - Spec: validPodSpecVolume, - }, - } - - type dsUpdateTest struct { - old extensions.DaemonSet - update extensions.DaemonSet - expectedErrNum int - } - successCases := map[string]dsUpdateTest{ - "no change": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - }, - "change template and selector": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 2, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector2}, - TemplateGeneration: 3, - Template: validPodTemplateAbc2.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - }, - "change template": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 3, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 4, - Template: validPodTemplateNodeSelector.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - }, - "change container image name": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector2}, - TemplateGeneration: 2, - Template: validPodTemplateDef.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - }, - "change update strategy": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 4, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 4, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.RollingUpdateDaemonSetStrategyType, - RollingUpdate: &extensions.RollingUpdateDaemonSet{ - MaxUnavailable: intstr.FromInt(1), - }, - }, - }, - }, - }, - "unchanged templateGeneration upon semantically equal template update": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 4, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 4, - Template: validPodTemplateAbcSemanticallyEqual.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.RollingUpdateDaemonSetStrategyType, - RollingUpdate: &extensions.RollingUpdateDaemonSet{ - MaxUnavailable: intstr.FromInt(1), - }, - }, - }, - }, - }, - } - for testName, successCase := range successCases { - // ResourceVersion is required for updates. - successCase.old.ObjectMeta.ResourceVersion = "1" - successCase.update.ObjectMeta.ResourceVersion = "2" - // Check test setup - if successCase.expectedErrNum > 0 { - t.Errorf("%q has incorrect test setup with expectedErrNum %d, expected no error", testName, successCase.expectedErrNum) - } - if len(successCase.old.ObjectMeta.ResourceVersion) == 0 || len(successCase.update.ObjectMeta.ResourceVersion) == 0 { - t.Errorf("%q has incorrect test setup with no resource version set", testName) - } - if errs := ValidateDaemonSetUpdate(&successCase.update, &successCase.old); len(errs) != 0 { - t.Errorf("%q expected no error, but got: %v", testName, errs) - } - } - errorCases := map[string]dsUpdateTest{ - "change daemon name": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - expectedErrNum: 1, - }, - "invalid selector": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: invalidSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - expectedErrNum: 1, - }, - "invalid pod": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 2, - Template: invalidPodTemplate.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - expectedErrNum: 1, - }, - "invalid read-write volume": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 2, - Template: readWriteVolumePodTemplate.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - expectedErrNum: 1, - }, - "invalid update strategy": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: "Random", - }, - }, - }, - expectedErrNum: 1, - }, - "negative templateGeneration": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: -1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: -1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - expectedErrNum: 1, - }, - "decreased templateGeneration": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - TemplateGeneration: 2, - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - TemplateGeneration: 1, - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - expectedErrNum: 1, - }, - "unchanged templateGeneration upon template update": { - old: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - TemplateGeneration: 2, - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplateAbc.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: extensions.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - TemplateGeneration: 2, - Selector: &metav1.LabelSelector{MatchLabels: validSelector2}, - Template: validPodTemplateAbc2.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - expectedErrNum: 1, - }, - } - for testName, errorCase := range errorCases { - // ResourceVersion is required for updates. - errorCase.old.ObjectMeta.ResourceVersion = "1" - errorCase.update.ObjectMeta.ResourceVersion = "2" - // Check test setup - if errorCase.expectedErrNum <= 0 { - t.Errorf("%q has incorrect test setup with expectedErrNum %d, expected at least one error", testName, errorCase.expectedErrNum) - } - if len(errorCase.old.ObjectMeta.ResourceVersion) == 0 || len(errorCase.update.ObjectMeta.ResourceVersion) == 0 { - t.Errorf("%q has incorrect test setup with no resource version set", testName) - } - // Run the tests - if errs := ValidateDaemonSetUpdate(&errorCase.update, &errorCase.old); len(errs) != errorCase.expectedErrNum { - t.Errorf("%q expected %d errors, but got %d error: %v", testName, errorCase.expectedErrNum, len(errs), errs) - } else { - t.Logf("(PASS) %q got errors %v", testName, errs) - } - } -} - -func TestValidateDaemonSet(t *testing.T) { - validSelector := map[string]string{"a": "b"} - validPodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector, - }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - }, - } - invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} - invalidPodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - }, - ObjectMeta: metav1.ObjectMeta{ - Labels: invalidSelector, - }, - }, - } - successCases := []extensions.DaemonSet{ - { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplate.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplate.Template, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, - }, - }, - }, - } - for _, successCase := range successCases { - if errs := ValidateDaemonSet(&successCase); len(errs) != 0 { - t.Errorf("expected success: %v", errs) - } - } - - errorCases := map[string]extensions.DaemonSet{ - "zero-length ID": { - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplate.Template, - }, - }, - "missing-namespace": { - ObjectMeta: metav1.ObjectMeta{Name: "abc-123"}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplate.Template, - }, - }, - "nil selector": { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Template: validPodTemplate.Template, - }, - }, - "empty selector": { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{}, - Template: validPodTemplate.Template, - }, - }, - "selector_doesnt_match": { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, - Template: validPodTemplate.Template, - }, - }, - "invalid template": { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - }, - }, - "invalid_label": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - Labels: map[string]string{ - "NoUppercaseOrSpecialCharsLike=Equals": "bar", - }, - }, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplate.Template, - }, - }, - "invalid_label 2": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - Labels: map[string]string{ - "NoUppercaseOrSpecialCharsLike=Equals": "bar", - }, - }, - Spec: extensions.DaemonSetSpec{ - Template: invalidPodTemplate.Template, - }, - }, - "invalid_annotation": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - Annotations: map[string]string{ - "NoUppercaseOrSpecialCharsLike=Equals": "bar", - }, - }, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: validPodTemplate.Template, - }, - }, - "invalid restart policy 1": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: api.PodTemplateSpec{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyOnFailure, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector, - }, - }, - }, - }, - "invalid restart policy 2": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - Template: api.PodTemplateSpec{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyNever, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - ObjectMeta: metav1.ObjectMeta{ - Labels: validSelector, - }, - }, - }, - }, - } - for k, v := range errorCases { - errs := ValidateDaemonSet(&v) - if len(errs) == 0 { - t.Errorf("expected failure for %s", k) - } - for i := range errs { - field := errs[i].Field - if !strings.HasPrefix(field, "spec.template.") && - !strings.HasPrefix(field, "spec.updateStrategy") && - field != "metadata.name" && - field != "metadata.namespace" && - field != "spec.selector" && - field != "spec.template" && - field != "GCEPersistentDisk.ReadOnly" && - field != "spec.template.labels" && - field != "metadata.annotations" && - field != "metadata.labels" { - t.Errorf("%s: missing prefix for: %v", k, errs[i]) - } - } - } -} - -func validDeployment() *extensions.Deployment { - return &extensions.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "name": "abc", - }, - }, - Strategy: extensions.DeploymentStrategy{ - Type: extensions.RollingUpdateDeploymentStrategyType, - RollingUpdate: &extensions.RollingUpdateDeployment{ - MaxSurge: intstr.FromInt(1), - MaxUnavailable: intstr.FromInt(1), - }, - }, - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Namespace: metav1.NamespaceDefault, - Labels: map[string]string{ - "name": "abc", - }, - }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSDefault, - Containers: []api.Container{ - { - Name: "nginx", - Image: "image", - ImagePullPolicy: api.PullNever, - TerminationMessagePolicy: api.TerminationMessageReadFile, - }, - }, - }, - }, - RollbackTo: &extensions.RollbackConfig{ - Revision: 1, - }, - }, - } -} - -func TestValidateDeployment(t *testing.T) { - successCases := []*extensions.Deployment{ - validDeployment(), - } - for _, successCase := range successCases { - if errs := ValidateDeployment(successCase); len(errs) != 0 { - t.Errorf("expected success: %v", errs) - } - } - - errorCases := map[string]*extensions.Deployment{} - errorCases["metadata.name: Required value"] = &extensions.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: metav1.NamespaceDefault, - }, - } - // selector should match the labels in pod template. - invalidSelectorDeployment := validDeployment() - invalidSelectorDeployment.Spec.Selector = &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "name": "def", - }, - } - errorCases["`selector` does not match template `labels`"] = invalidSelectorDeployment - - // RestartPolicy should be always. - invalidRestartPolicyDeployment := validDeployment() - invalidRestartPolicyDeployment.Spec.Template.Spec.RestartPolicy = api.RestartPolicyNever - errorCases["Unsupported value: \"Never\""] = invalidRestartPolicyDeployment - - // must have valid strategy type - invalidStrategyDeployment := validDeployment() - invalidStrategyDeployment.Spec.Strategy.Type = extensions.DeploymentStrategyType("randomType") - errorCases[`supported values: "Recreate", "RollingUpdate"`] = invalidStrategyDeployment - - // rollingUpdate should be nil for recreate. - invalidRecreateDeployment := validDeployment() - invalidRecreateDeployment.Spec.Strategy = extensions.DeploymentStrategy{ - Type: extensions.RecreateDeploymentStrategyType, - RollingUpdate: &extensions.RollingUpdateDeployment{}, - } - errorCases["may not be specified when strategy `type` is 'Recreate'"] = invalidRecreateDeployment - - // MaxSurge should be in the form of 20%. - invalidMaxSurgeDeployment := validDeployment() - invalidMaxSurgeDeployment.Spec.Strategy = extensions.DeploymentStrategy{ - Type: extensions.RollingUpdateDeploymentStrategyType, - RollingUpdate: &extensions.RollingUpdateDeployment{ - MaxSurge: intstr.FromString("20Percent"), - }, - } - errorCases["a valid percent string must be"] = invalidMaxSurgeDeployment - - // MaxSurge and MaxUnavailable cannot both be zero. - invalidRollingUpdateDeployment := validDeployment() - invalidRollingUpdateDeployment.Spec.Strategy = extensions.DeploymentStrategy{ - Type: extensions.RollingUpdateDeploymentStrategyType, - RollingUpdate: &extensions.RollingUpdateDeployment{ - MaxSurge: intstr.FromString("0%"), - MaxUnavailable: intstr.FromInt(0), - }, - } - errorCases["may not be 0 when `maxSurge` is 0"] = invalidRollingUpdateDeployment - - // MaxUnavailable should not be more than 100%. - invalidMaxUnavailableDeployment := validDeployment() - invalidMaxUnavailableDeployment.Spec.Strategy = extensions.DeploymentStrategy{ - Type: extensions.RollingUpdateDeploymentStrategyType, - RollingUpdate: &extensions.RollingUpdateDeployment{ - MaxUnavailable: intstr.FromString("110%"), - }, - } - errorCases["must not be greater than 100%"] = invalidMaxUnavailableDeployment - - // Rollback.Revision must be non-negative - invalidRollbackRevisionDeployment := validDeployment() - invalidRollbackRevisionDeployment.Spec.RollbackTo.Revision = -3 - errorCases["must be greater than or equal to 0"] = invalidRollbackRevisionDeployment - - // ProgressDeadlineSeconds should be greater than MinReadySeconds - invalidProgressDeadlineDeployment := validDeployment() - seconds := int32(600) - invalidProgressDeadlineDeployment.Spec.ProgressDeadlineSeconds = &seconds - invalidProgressDeadlineDeployment.Spec.MinReadySeconds = seconds - errorCases["must be greater than minReadySeconds"] = invalidProgressDeadlineDeployment - - for k, v := range errorCases { - errs := ValidateDeployment(v) - if len(errs) == 0 { - t.Errorf("[%s] expected failure", k) - } else if !strings.Contains(errs[0].Error(), k) { - t.Errorf("unexpected error: %q, expected: %q", errs[0].Error(), k) - } - } -} - -func TestValidateDeploymentStatus(t *testing.T) { - collisionCount := int32(-3) - tests := []struct { - name string - - replicas int32 - updatedReplicas int32 - readyReplicas int32 - availableReplicas int32 - observedGeneration int64 - collisionCount *int32 - - expectedErr bool - }{ - { - name: "valid status", - replicas: 3, - updatedReplicas: 3, - readyReplicas: 2, - availableReplicas: 1, - observedGeneration: 2, - expectedErr: false, - }, - { - name: "invalid replicas", - replicas: -1, - updatedReplicas: 2, - readyReplicas: 2, - availableReplicas: 1, - observedGeneration: 2, - expectedErr: true, - }, - { - name: "invalid updatedReplicas", - replicas: 2, - updatedReplicas: -1, - readyReplicas: 2, - availableReplicas: 1, - observedGeneration: 2, - expectedErr: true, - }, - { - name: "invalid readyReplicas", - replicas: 3, - readyReplicas: -1, - availableReplicas: 1, - observedGeneration: 2, - expectedErr: true, - }, - { - name: "invalid availableReplicas", - replicas: 3, - readyReplicas: 3, - availableReplicas: -1, - observedGeneration: 2, - expectedErr: true, - }, - { - name: "invalid observedGeneration", - replicas: 3, - readyReplicas: 3, - availableReplicas: 3, - observedGeneration: -1, - expectedErr: true, - }, - { - name: "updatedReplicas greater than replicas", - replicas: 3, - updatedReplicas: 4, - readyReplicas: 3, - availableReplicas: 3, - observedGeneration: 1, - expectedErr: true, - }, - { - name: "readyReplicas greater than replicas", - replicas: 3, - readyReplicas: 4, - availableReplicas: 3, - observedGeneration: 1, - expectedErr: true, - }, - { - name: "availableReplicas greater than replicas", - replicas: 3, - readyReplicas: 3, - availableReplicas: 4, - observedGeneration: 1, - expectedErr: true, - }, - { - name: "availableReplicas greater than readyReplicas", - replicas: 3, - readyReplicas: 2, - availableReplicas: 3, - observedGeneration: 1, - expectedErr: true, - }, - { - name: "invalid collisionCount", - replicas: 3, - observedGeneration: 1, - collisionCount: &collisionCount, - expectedErr: true, - }, - } - - for _, test := range tests { - status := extensions.DeploymentStatus{ - Replicas: test.replicas, - UpdatedReplicas: test.updatedReplicas, - ReadyReplicas: test.readyReplicas, - AvailableReplicas: test.availableReplicas, - ObservedGeneration: test.observedGeneration, - CollisionCount: test.collisionCount, - } - - errs := ValidateDeploymentStatus(&status, field.NewPath("status")) - if hasErr := len(errs) > 0; hasErr != test.expectedErr { - errString := spew.Sprintf("%#v", errs) - t.Errorf("%s: expected error: %t, got error: %t\nerrors: %s", test.name, test.expectedErr, hasErr, errString) - } - } -} - -func TestValidateDeploymentStatusUpdate(t *testing.T) { - collisionCount := int32(1) - otherCollisionCount := int32(2) - tests := []struct { - name string - - from, to extensions.DeploymentStatus - - expectedErr bool - }{ - { - name: "increase: valid update", - from: extensions.DeploymentStatus{ - CollisionCount: nil, - }, - to: extensions.DeploymentStatus{ - CollisionCount: &collisionCount, - }, - expectedErr: false, - }, - { - name: "stable: valid update", - from: extensions.DeploymentStatus{ - CollisionCount: &collisionCount, - }, - to: extensions.DeploymentStatus{ - CollisionCount: &collisionCount, - }, - expectedErr: false, - }, - { - name: "unset: invalid update", - from: extensions.DeploymentStatus{ - CollisionCount: &collisionCount, - }, - to: extensions.DeploymentStatus{ - CollisionCount: nil, - }, - expectedErr: true, - }, - { - name: "decrease: invalid update", - from: extensions.DeploymentStatus{ - CollisionCount: &otherCollisionCount, - }, - to: extensions.DeploymentStatus{ - CollisionCount: &collisionCount, - }, - expectedErr: true, - }, - } - - for _, test := range tests { - meta := metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault, ResourceVersion: "1"} - from := &extensions.Deployment{ - ObjectMeta: meta, - Status: test.from, - } - to := &extensions.Deployment{ - ObjectMeta: meta, - Status: test.to, - } - - errs := ValidateDeploymentStatusUpdate(to, from) - if hasErr := len(errs) > 0; hasErr != test.expectedErr { - errString := spew.Sprintf("%#v", errs) - t.Errorf("%s: expected error: %t, got error: %t\nerrors: %s", test.name, test.expectedErr, hasErr, errString) - } - } -} - -func validDeploymentRollback() *extensions.DeploymentRollback { - return &extensions.DeploymentRollback{ - Name: "abc", - UpdatedAnnotations: map[string]string{ - "created-by": "abc", - }, - RollbackTo: extensions.RollbackConfig{ - Revision: 1, - }, - } -} - -func TestValidateDeploymentRollback(t *testing.T) { - noAnnotation := validDeploymentRollback() - noAnnotation.UpdatedAnnotations = nil - successCases := []*extensions.DeploymentRollback{ - validDeploymentRollback(), - noAnnotation, - } - for _, successCase := range successCases { - if errs := ValidateDeploymentRollback(successCase); len(errs) != 0 { - t.Errorf("expected success: %v", errs) - } - } - - errorCases := map[string]*extensions.DeploymentRollback{} - invalidNoName := validDeploymentRollback() - invalidNoName.Name = "" - errorCases["name: Required value"] = invalidNoName - - for k, v := range errorCases { - errs := ValidateDeploymentRollback(v) - if len(errs) == 0 { - t.Errorf("[%s] expected failure", k) - } else if !strings.Contains(errs[0].Error(), k) { - t.Errorf("unexpected error: %q, expected: %q", errs[0].Error(), k) - } - } -} + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/kubernetes/pkg/apis/core" + "k8s.io/kubernetes/pkg/apis/extensions" +) func TestValidateIngress(t *testing.T) { defaultBackend := extensions.IngressBackend{ @@ -1730,587 +292,3 @@ func TestValidateIngressStatusUpdate(t *testing.T) { } } } - -func TestValidateReplicaSetStatus(t *testing.T) { - tests := []struct { - name string - - replicas int32 - fullyLabeledReplicas int32 - readyReplicas int32 - availableReplicas int32 - observedGeneration int64 - - expectedErr bool - }{ - { - name: "valid status", - replicas: 3, - fullyLabeledReplicas: 3, - readyReplicas: 2, - availableReplicas: 1, - observedGeneration: 2, - expectedErr: false, - }, - { - name: "invalid replicas", - replicas: -1, - fullyLabeledReplicas: 3, - readyReplicas: 2, - availableReplicas: 1, - observedGeneration: 2, - expectedErr: true, - }, - { - name: "invalid fullyLabeledReplicas", - replicas: 3, - fullyLabeledReplicas: -1, - readyReplicas: 2, - availableReplicas: 1, - observedGeneration: 2, - expectedErr: true, - }, - { - name: "invalid readyReplicas", - replicas: 3, - fullyLabeledReplicas: 3, - readyReplicas: -1, - availableReplicas: 1, - observedGeneration: 2, - expectedErr: true, - }, - { - name: "invalid availableReplicas", - replicas: 3, - fullyLabeledReplicas: 3, - readyReplicas: 3, - availableReplicas: -1, - observedGeneration: 2, - expectedErr: true, - }, - { - name: "invalid observedGeneration", - replicas: 3, - fullyLabeledReplicas: 3, - readyReplicas: 3, - availableReplicas: 3, - observedGeneration: -1, - expectedErr: true, - }, - { - name: "fullyLabeledReplicas greater than replicas", - replicas: 3, - fullyLabeledReplicas: 4, - readyReplicas: 3, - availableReplicas: 3, - observedGeneration: 1, - expectedErr: true, - }, - { - name: "readyReplicas greater than replicas", - replicas: 3, - fullyLabeledReplicas: 3, - readyReplicas: 4, - availableReplicas: 3, - observedGeneration: 1, - expectedErr: true, - }, - { - name: "availableReplicas greater than replicas", - replicas: 3, - fullyLabeledReplicas: 3, - readyReplicas: 3, - availableReplicas: 4, - observedGeneration: 1, - expectedErr: true, - }, - { - name: "availableReplicas greater than readyReplicas", - replicas: 3, - fullyLabeledReplicas: 3, - readyReplicas: 2, - availableReplicas: 3, - observedGeneration: 1, - expectedErr: true, - }, - } - - for _, test := range tests { - status := extensions.ReplicaSetStatus{ - Replicas: test.replicas, - FullyLabeledReplicas: test.fullyLabeledReplicas, - ReadyReplicas: test.readyReplicas, - AvailableReplicas: test.availableReplicas, - ObservedGeneration: test.observedGeneration, - } - - if hasErr := len(ValidateReplicaSetStatus(status, field.NewPath("status"))) > 0; hasErr != test.expectedErr { - t.Errorf("%s: expected error: %t, got error: %t", test.name, test.expectedErr, hasErr) - } - } -} - -func TestValidateReplicaSetStatusUpdate(t *testing.T) { - validLabels := map[string]string{"a": "b"} - validPodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validLabels, - }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - }, - } - type rcUpdateTest struct { - old extensions.ReplicaSet - update extensions.ReplicaSet - } - successCases := []rcUpdateTest{ - { - old: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - Status: extensions.ReplicaSetStatus{ - Replicas: 2, - }, - }, - update: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 3, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - Status: extensions.ReplicaSetStatus{ - Replicas: 4, - }, - }, - }, - } - for _, successCase := range successCases { - successCase.old.ObjectMeta.ResourceVersion = "1" - successCase.update.ObjectMeta.ResourceVersion = "1" - if errs := ValidateReplicaSetStatusUpdate(&successCase.update, &successCase.old); len(errs) != 0 { - t.Errorf("expected success: %v", errs) - } - } - errorCases := map[string]rcUpdateTest{ - "negative replicas": { - old: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - Status: extensions.ReplicaSetStatus{ - Replicas: 3, - }, - }, - update: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 2, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - Status: extensions.ReplicaSetStatus{ - Replicas: -3, - }, - }, - }, - } - for testName, errorCase := range errorCases { - if errs := ValidateReplicaSetStatusUpdate(&errorCase.update, &errorCase.old); len(errs) == 0 { - t.Errorf("expected failure: %s", testName) - } - } - -} - -func TestValidateReplicaSetUpdate(t *testing.T) { - validLabels := map[string]string{"a": "b"} - validPodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validLabels, - }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - }, - } - readWriteVolumePodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validLabels, - }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, - }, - }, - } - invalidLabels := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} - invalidPodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - }, - ObjectMeta: metav1.ObjectMeta{ - Labels: invalidLabels, - }, - }, - } - type rcUpdateTest struct { - old extensions.ReplicaSet - update extensions.ReplicaSet - } - successCases := []rcUpdateTest{ - { - old: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - update: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 3, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - }, - { - old: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - update: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 1, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: readWriteVolumePodTemplate.Template, - }, - }, - }, - } - for _, successCase := range successCases { - successCase.old.ObjectMeta.ResourceVersion = "1" - successCase.update.ObjectMeta.ResourceVersion = "1" - if errs := ValidateReplicaSetUpdate(&successCase.update, &successCase.old); len(errs) != 0 { - t.Errorf("expected success: %v", errs) - } - } - errorCases := map[string]rcUpdateTest{ - "more than one read/write": { - old: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - update: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 2, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: readWriteVolumePodTemplate.Template, - }, - }, - }, - "invalid selector": { - old: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - update: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 2, - Selector: &metav1.LabelSelector{MatchLabels: invalidLabels}, - Template: validPodTemplate.Template, - }, - }, - }, - "invalid pod": { - old: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - update: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 2, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: invalidPodTemplate.Template, - }, - }, - }, - "negative replicas": { - old: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - update: extensions.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: -1, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - }, - } - for testName, errorCase := range errorCases { - if errs := ValidateReplicaSetUpdate(&errorCase.update, &errorCase.old); len(errs) == 0 { - t.Errorf("expected failure: %s", testName) - } - } -} - -func TestValidateReplicaSet(t *testing.T) { - validLabels := map[string]string{"a": "b"} - validPodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validLabels, - }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - }, - } - readWriteVolumePodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: validLabels, - }, - Spec: api.PodSpec{ - Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - }, - } - invalidLabels := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} - invalidPodTemplate := api.PodTemplate{ - Template: api.PodTemplateSpec{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - }, - ObjectMeta: metav1.ObjectMeta{ - Labels: invalidLabels, - }, - }, - } - successCases := []extensions.ReplicaSet{ - { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 1, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: readWriteVolumePodTemplate.Template, - }, - }, - } - for _, successCase := range successCases { - if errs := ValidateReplicaSet(&successCase); len(errs) != 0 { - t.Errorf("expected success: %v", errs) - } - } - - errorCases := map[string]extensions.ReplicaSet{ - "zero-length ID": { - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - "missing-namespace": { - ObjectMeta: metav1.ObjectMeta{Name: "abc-123"}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - "empty selector": { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Template: validPodTemplate.Template, - }, - }, - "selector_doesnt_match": { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, - Template: validPodTemplate.Template, - }, - }, - "invalid manifest": { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - }, - }, - "read-write persistent disk with > 1 pod": { - ObjectMeta: metav1.ObjectMeta{Name: "abc"}, - Spec: extensions.ReplicaSetSpec{ - Replicas: 2, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: readWriteVolumePodTemplate.Template, - }, - }, - "negative_replicas": { - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ - Replicas: -1, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - }, - }, - "invalid_label": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - Labels: map[string]string{ - "NoUppercaseOrSpecialCharsLike=Equals": "bar", - }, - }, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - "invalid_label 2": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - Labels: map[string]string{ - "NoUppercaseOrSpecialCharsLike=Equals": "bar", - }, - }, - Spec: extensions.ReplicaSetSpec{ - Template: invalidPodTemplate.Template, - }, - }, - "invalid_annotation": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - Annotations: map[string]string{ - "NoUppercaseOrSpecialCharsLike=Equals": "bar", - }, - }, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - "invalid restart policy 1": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: api.PodTemplateSpec{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyOnFailure, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - ObjectMeta: metav1.ObjectMeta{ - Labels: validLabels, - }, - }, - }, - }, - "invalid restart policy 2": { - ObjectMeta: metav1.ObjectMeta{ - Name: "abc-123", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: api.PodTemplateSpec{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyNever, - DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - ObjectMeta: metav1.ObjectMeta{ - Labels: validLabels, - }, - }, - }, - }, - } - for k, v := range errorCases { - errs := ValidateReplicaSet(&v) - if len(errs) == 0 { - t.Errorf("expected failure for %s", k) - } - for i := range errs { - field := errs[i].Field - if !strings.HasPrefix(field, "spec.template.") && - field != "metadata.name" && - field != "metadata.namespace" && - field != "spec.selector" && - field != "spec.template" && - field != "GCEPersistentDisk.ReadOnly" && - field != "spec.replicas" && - field != "spec.template.labels" && - field != "metadata.annotations" && - field != "metadata.labels" && - field != "status.replicas" { - t.Errorf("%s: missing prefix for: %v", k, errs[i]) - } - } - } -} diff --git a/pkg/apis/extensions/zz_generated.deepcopy.go b/pkg/apis/extensions/zz_generated.deepcopy.go index befc3a71d63f9..390f43280798f 100644 --- a/pkg/apis/extensions/zz_generated.deepcopy.go +++ b/pkg/apis/extensions/zz_generated.deepcopy.go @@ -21,444 +21,9 @@ limitations under the License. package extensions 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 *CustomMetricCurrentStatus) DeepCopyInto(out *CustomMetricCurrentStatus) { - *out = *in - out.CurrentValue = in.CurrentValue.DeepCopy() - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricCurrentStatus. -func (in *CustomMetricCurrentStatus) DeepCopy() *CustomMetricCurrentStatus { - if in == nil { - return nil - } - out := new(CustomMetricCurrentStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomMetricCurrentStatusList) DeepCopyInto(out *CustomMetricCurrentStatusList) { - *out = *in - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]CustomMetricCurrentStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricCurrentStatusList. -func (in *CustomMetricCurrentStatusList) DeepCopy() *CustomMetricCurrentStatusList { - if in == nil { - return nil - } - out := new(CustomMetricCurrentStatusList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomMetricTarget) DeepCopyInto(out *CustomMetricTarget) { - *out = *in - out.TargetValue = in.TargetValue.DeepCopy() - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricTarget. -func (in *CustomMetricTarget) DeepCopy() *CustomMetricTarget { - if in == nil { - return nil - } - out := new(CustomMetricTarget) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomMetricTargetList) DeepCopyInto(out *CustomMetricTargetList) { - *out = *in - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]CustomMetricTarget, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricTargetList. -func (in *CustomMetricTargetList) DeepCopy() *CustomMetricTargetList { - if in == nil { - return nil - } - out := new(CustomMetricTargetList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DaemonSet) DeepCopyInto(out *DaemonSet) { - *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 DaemonSet. -func (in *DaemonSet) DeepCopy() *DaemonSet { - if in == nil { - return nil - } - out := new(DaemonSet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DaemonSet) 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 *DaemonSetCondition) DeepCopyInto(out *DaemonSetCondition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetCondition. -func (in *DaemonSetCondition) DeepCopy() *DaemonSetCondition { - if in == nil { - return nil - } - out := new(DaemonSetCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DaemonSetList) DeepCopyInto(out *DaemonSetList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]DaemonSet, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetList. -func (in *DaemonSetList) DeepCopy() *DaemonSetList { - if in == nil { - return nil - } - out := new(DaemonSetList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DaemonSetList) 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 *DaemonSetSpec) DeepCopyInto(out *DaemonSetSpec) { - *out = *in - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - in.Template.DeepCopyInto(&out.Template) - in.UpdateStrategy.DeepCopyInto(&out.UpdateStrategy) - if in.RevisionHistoryLimit != nil { - in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit - *out = new(int32) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetSpec. -func (in *DaemonSetSpec) DeepCopy() *DaemonSetSpec { - if in == nil { - return nil - } - out := new(DaemonSetSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DaemonSetStatus) DeepCopyInto(out *DaemonSetStatus) { - *out = *in - if in.CollisionCount != nil { - in, out := &in.CollisionCount, &out.CollisionCount - *out = new(int32) - **out = **in - } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]DaemonSetCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetStatus. -func (in *DaemonSetStatus) DeepCopy() *DaemonSetStatus { - if in == nil { - return nil - } - out := new(DaemonSetStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DaemonSetUpdateStrategy) DeepCopyInto(out *DaemonSetUpdateStrategy) { - *out = *in - if in.RollingUpdate != nil { - in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(RollingUpdateDaemonSet) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonSetUpdateStrategy. -func (in *DaemonSetUpdateStrategy) DeepCopy() *DaemonSetUpdateStrategy { - if in == nil { - return nil - } - out := new(DaemonSetUpdateStrategy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Deployment) DeepCopyInto(out *Deployment) { - *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 Deployment. -func (in *Deployment) DeepCopy() *Deployment { - if in == nil { - return nil - } - out := new(Deployment) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Deployment) 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 *DeploymentCondition) DeepCopyInto(out *DeploymentCondition) { - *out = *in - in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentCondition. -func (in *DeploymentCondition) DeepCopy() *DeploymentCondition { - if in == nil { - return nil - } - out := new(DeploymentCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DeploymentList) DeepCopyInto(out *DeploymentList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Deployment, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentList. -func (in *DeploymentList) DeepCopy() *DeploymentList { - if in == nil { - return nil - } - out := new(DeploymentList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DeploymentList) 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 *DeploymentRollback) DeepCopyInto(out *DeploymentRollback) { - *out = *in - out.TypeMeta = in.TypeMeta - if in.UpdatedAnnotations != nil { - in, out := &in.UpdatedAnnotations, &out.UpdatedAnnotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - out.RollbackTo = in.RollbackTo - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentRollback. -func (in *DeploymentRollback) DeepCopy() *DeploymentRollback { - if in == nil { - return nil - } - out := new(DeploymentRollback) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DeploymentRollback) 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 *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { - *out = *in - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - in.Template.DeepCopyInto(&out.Template) - in.Strategy.DeepCopyInto(&out.Strategy) - if in.RevisionHistoryLimit != nil { - in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit - *out = new(int32) - **out = **in - } - if in.RollbackTo != nil { - in, out := &in.RollbackTo, &out.RollbackTo - *out = new(RollbackConfig) - **out = **in - } - if in.ProgressDeadlineSeconds != nil { - in, out := &in.ProgressDeadlineSeconds, &out.ProgressDeadlineSeconds - *out = new(int32) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentSpec. -func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { - if in == nil { - return nil - } - out := new(DeploymentSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]DeploymentCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.CollisionCount != nil { - in, out := &in.CollisionCount, &out.CollisionCount - *out = new(int32) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatus. -func (in *DeploymentStatus) DeepCopy() *DeploymentStatus { - if in == nil { - return nil - } - out := new(DeploymentStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DeploymentStrategy) DeepCopyInto(out *DeploymentStrategy) { - *out = *in - if in.RollingUpdate != nil { - in, out := &in.RollingUpdate, &out.RollingUpdate - *out = new(RollingUpdateDeployment) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStrategy. -func (in *DeploymentStrategy) DeepCopy() *DeploymentStrategy { - if in == nil { - return nil - } - out := new(DeploymentStrategy) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPIngressPath) DeepCopyInto(out *HTTPIngressPath) { *out = *in @@ -686,129 +251,6 @@ func (in *IngressTLS) DeepCopy() *IngressTLS { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ReplicaSet) DeepCopyInto(out *ReplicaSet) { - *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 ReplicaSet. -func (in *ReplicaSet) DeepCopy() *ReplicaSet { - if in == nil { - return nil - } - out := new(ReplicaSet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ReplicaSet) 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 *ReplicaSetCondition) DeepCopyInto(out *ReplicaSetCondition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetCondition. -func (in *ReplicaSetCondition) DeepCopy() *ReplicaSetCondition { - if in == nil { - return nil - } - out := new(ReplicaSetCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ReplicaSetList) DeepCopyInto(out *ReplicaSetList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ReplicaSet, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetList. -func (in *ReplicaSetList) DeepCopy() *ReplicaSetList { - if in == nil { - return nil - } - out := new(ReplicaSetList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ReplicaSetList) 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 *ReplicaSetSpec) DeepCopyInto(out *ReplicaSetSpec) { - *out = *in - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - in.Template.DeepCopyInto(&out.Template) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetSpec. -func (in *ReplicaSetSpec) DeepCopy() *ReplicaSetSpec { - if in == nil { - return nil - } - out := new(ReplicaSetSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ReplicaSetStatus) DeepCopyInto(out *ReplicaSetStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]ReplicaSetCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetStatus. -func (in *ReplicaSetStatus) DeepCopy() *ReplicaSetStatus { - if in == nil { - return nil - } - out := new(ReplicaSetStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicationControllerDummy) DeepCopyInto(out *ReplicationControllerDummy) { *out = *in @@ -833,54 +275,3 @@ func (in *ReplicationControllerDummy) DeepCopyObject() runtime.Object { } return nil } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RollbackConfig) DeepCopyInto(out *RollbackConfig) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollbackConfig. -func (in *RollbackConfig) DeepCopy() *RollbackConfig { - if in == nil { - return nil - } - out := new(RollbackConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RollingUpdateDaemonSet) DeepCopyInto(out *RollingUpdateDaemonSet) { - *out = *in - out.MaxUnavailable = in.MaxUnavailable - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdateDaemonSet. -func (in *RollingUpdateDaemonSet) DeepCopy() *RollingUpdateDaemonSet { - if in == nil { - return nil - } - out := new(RollingUpdateDaemonSet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RollingUpdateDeployment) DeepCopyInto(out *RollingUpdateDeployment) { - *out = *in - out.MaxUnavailable = in.MaxUnavailable - out.MaxSurge = in.MaxSurge - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdateDeployment. -func (in *RollingUpdateDeployment) DeepCopy() *RollingUpdateDeployment { - if in == nil { - return nil - } - out := new(RollingUpdateDeployment) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/apis/imagepolicy/OWNERS b/pkg/apis/imagepolicy/OWNERS index 96ae42e027a01..02b8511e46556 100755 --- a/pkg/apis/imagepolicy/OWNERS +++ b/pkg/apis/imagepolicy/OWNERS @@ -1,4 +1,7 @@ +# approval on api packages bubbles to api-approvers reviewers: -- deads2k -- mbohlool -- jianhuiz +- sig-auth-policy-approvers +- sig-auth-policy-reviewers +labels: +- sig/auth + diff --git a/pkg/apis/policy/OWNERS b/pkg/apis/policy/OWNERS index 872e16329b0ad..5780104890ded 100755 --- a/pkg/apis/policy/OWNERS +++ b/pkg/apis/policy/OWNERS @@ -1,7 +1,8 @@ -approvers: -- sig-apps-api-approvers +# approval on api packages bubbles to api-approvers reviewers: -- sig-apps-reviewers -- pweil- -- liggitt -- tallclair +- sig-apps-api-approvers +- sig-auth-policy-approvers +- sig-auth-policy-reviewers +labels: +- sig/auth + diff --git a/pkg/apis/policy/validation/BUILD b/pkg/apis/policy/validation/BUILD index ffa56b65c12b0..a32bc3f9ca4b1 100644 --- a/pkg/apis/policy/validation/BUILD +++ b/pkg/apis/policy/validation/BUILD @@ -11,9 +11,9 @@ go_library( srcs = ["validation.go"], importpath = "k8s.io/kubernetes/pkg/apis/policy/validation", deps = [ + "//pkg/apis/apps/validation:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/validation:go_default_library", - "//pkg/apis/extensions/validation:go_default_library", "//pkg/apis/policy:go_default_library", "//pkg/features:go_default_library", "//pkg/security/apparmor:go_default_library", diff --git a/pkg/apis/policy/validation/validation.go b/pkg/apis/policy/validation/validation.go index 9911b5551642c..fa1af17afa76a 100644 --- a/pkg/apis/policy/validation/validation.go +++ b/pkg/apis/policy/validation/validation.go @@ -27,9 +27,9 @@ import ( unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" + appsvalidation "k8s.io/kubernetes/pkg/apis/apps/validation" core "k8s.io/kubernetes/pkg/apis/core" apivalidation "k8s.io/kubernetes/pkg/apis/core/validation" - extensionsvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/security/apparmor" @@ -68,13 +68,13 @@ func ValidatePodDisruptionBudgetSpec(spec policy.PodDisruptionBudgetSpec, fldPat } if spec.MinAvailable != nil { - allErrs = append(allErrs, extensionsvalidation.ValidatePositiveIntOrPercent(*spec.MinAvailable, fldPath.Child("minAvailable"))...) - allErrs = append(allErrs, extensionsvalidation.IsNotMoreThan100Percent(*spec.MinAvailable, fldPath.Child("minAvailable"))...) + allErrs = append(allErrs, appsvalidation.ValidatePositiveIntOrPercent(*spec.MinAvailable, fldPath.Child("minAvailable"))...) + allErrs = append(allErrs, appsvalidation.IsNotMoreThan100Percent(*spec.MinAvailable, fldPath.Child("minAvailable"))...) } if spec.MaxUnavailable != nil { - allErrs = append(allErrs, extensionsvalidation.ValidatePositiveIntOrPercent(*spec.MaxUnavailable, fldPath.Child("maxUnavailable"))...) - allErrs = append(allErrs, extensionsvalidation.IsNotMoreThan100Percent(*spec.MaxUnavailable, fldPath.Child("maxUnavailable"))...) + allErrs = append(allErrs, appsvalidation.ValidatePositiveIntOrPercent(*spec.MaxUnavailable, fldPath.Child("maxUnavailable"))...) + allErrs = append(allErrs, appsvalidation.IsNotMoreThan100Percent(*spec.MaxUnavailable, fldPath.Child("maxUnavailable"))...) } allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) diff --git a/pkg/apis/rbac/OWNERS b/pkg/apis/rbac/OWNERS index 45b66b0a8ca25..ff4a7f4bf9ad0 100755 --- a/pkg/apis/rbac/OWNERS +++ b/pkg/apis/rbac/OWNERS @@ -1,16 +1,7 @@ +# approval on api packages bubbles to api-approvers reviewers: -- thockin -- lavalamp -- smarterclayton -- deads2k -- sttts -- ncdc -- dims -- krousey -- mml -- mbohlool -- david-mcmahon -- lixiaobing10051267 -- jianhuiz -- liggitt -- enj +- sig-auth-authorizers-approvers +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/pkg/auth/authorizer/abac/abac.go b/pkg/auth/authorizer/abac/abac.go index fc3a9dfcf9b55..86e7f8ed3e0bb 100644 --- a/pkg/auth/authorizer/abac/abac.go +++ b/pkg/auth/authorizer/abac/abac.go @@ -227,7 +227,7 @@ func (pl policyList) Authorize(a authorizer.Attributes) (authorizer.Decision, st return authorizer.DecisionAllow, "", nil } } - return authorizer.DecisionNoOpinion, "no ABAC policy matched", nil + return authorizer.DecisionNoOpinion, "No policy matched.", nil // TODO: Benchmark how much time policy matching takes with a medium size // policy file, compared to other steps such as encoding/decoding. // Then, add Caching only if needed. diff --git a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/BUILD b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/BUILD index 794648663b05f..2f786404bccdf 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/BUILD +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/BUILD @@ -10,14 +10,16 @@ go_library( srcs = [ "apps_client.go", "controllerrevision.go", + "daemonset.go", + "deployment.go", "doc.go", "generated_expansion.go", + "replicaset.go", "statefulset.go", ], importpath = "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion", deps = [ "//pkg/apis/apps:go_default_library", - "//pkg/apis/autoscaling:go_default_library", "//pkg/client/clientset_generated/internalclientset/scheme:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", diff --git a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/apps_client.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/apps_client.go index abcdc639fa86e..e72ae6bb1cbaf 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/apps_client.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/apps_client.go @@ -26,6 +26,9 @@ import ( type AppsInterface interface { RESTClient() rest.Interface ControllerRevisionsGetter + DaemonSetsGetter + DeploymentsGetter + ReplicaSetsGetter StatefulSetsGetter } @@ -38,6 +41,18 @@ func (c *AppsClient) ControllerRevisions(namespace string) ControllerRevisionInt return newControllerRevisions(c, namespace) } +func (c *AppsClient) DaemonSets(namespace string) DaemonSetInterface { + return newDaemonSets(c, namespace) +} + +func (c *AppsClient) Deployments(namespace string) DeploymentInterface { + return newDeployments(c, namespace) +} + +func (c *AppsClient) ReplicaSets(namespace string) ReplicaSetInterface { + return newReplicaSets(c, namespace) +} + func (c *AppsClient) StatefulSets(namespace string) StatefulSetInterface { return newStatefulSets(c, namespace) } diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/daemonset.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/daemonset.go similarity index 77% rename from pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/daemonset.go rename to pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/daemonset.go index 66fd1af05ef19..ac411caea4502 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/daemonset.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/daemonset.go @@ -23,7 +23,7 @@ import ( types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rest "k8s.io/client-go/rest" - extensions "k8s.io/kubernetes/pkg/apis/extensions" + apps "k8s.io/kubernetes/pkg/apis/apps" scheme "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/scheme" ) @@ -35,15 +35,15 @@ type DaemonSetsGetter interface { // DaemonSetInterface has methods to work with DaemonSet resources. type DaemonSetInterface interface { - Create(*extensions.DaemonSet) (*extensions.DaemonSet, error) - Update(*extensions.DaemonSet) (*extensions.DaemonSet, error) - UpdateStatus(*extensions.DaemonSet) (*extensions.DaemonSet, error) + Create(*apps.DaemonSet) (*apps.DaemonSet, error) + Update(*apps.DaemonSet) (*apps.DaemonSet, error) + UpdateStatus(*apps.DaemonSet) (*apps.DaemonSet, error) Delete(name string, options *v1.DeleteOptions) error DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*extensions.DaemonSet, error) - List(opts v1.ListOptions) (*extensions.DaemonSetList, error) + Get(name string, options v1.GetOptions) (*apps.DaemonSet, error) + List(opts v1.ListOptions) (*apps.DaemonSetList, error) Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.DaemonSet, err error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.DaemonSet, err error) DaemonSetExpansion } @@ -54,7 +54,7 @@ type daemonSets struct { } // newDaemonSets returns a DaemonSets -func newDaemonSets(c *ExtensionsClient, namespace string) *daemonSets { +func newDaemonSets(c *AppsClient, namespace string) *daemonSets { return &daemonSets{ client: c.RESTClient(), ns: namespace, @@ -62,8 +62,8 @@ func newDaemonSets(c *ExtensionsClient, namespace string) *daemonSets { } // Get takes name of the daemonSet, and returns the corresponding daemonSet object, and an error if there is any. -func (c *daemonSets) Get(name string, options v1.GetOptions) (result *extensions.DaemonSet, err error) { - result = &extensions.DaemonSet{} +func (c *daemonSets) Get(name string, options v1.GetOptions) (result *apps.DaemonSet, err error) { + result = &apps.DaemonSet{} err = c.client.Get(). Namespace(c.ns). Resource("daemonsets"). @@ -75,8 +75,8 @@ func (c *daemonSets) Get(name string, options v1.GetOptions) (result *extensions } // List takes label and field selectors, and returns the list of DaemonSets that match those selectors. -func (c *daemonSets) List(opts v1.ListOptions) (result *extensions.DaemonSetList, err error) { - result = &extensions.DaemonSetList{} +func (c *daemonSets) List(opts v1.ListOptions) (result *apps.DaemonSetList, err error) { + result = &apps.DaemonSetList{} err = c.client.Get(). Namespace(c.ns). Resource("daemonsets"). @@ -97,8 +97,8 @@ func (c *daemonSets) Watch(opts v1.ListOptions) (watch.Interface, error) { } // Create takes the representation of a daemonSet and creates it. Returns the server's representation of the daemonSet, and an error, if there is any. -func (c *daemonSets) Create(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) { - result = &extensions.DaemonSet{} +func (c *daemonSets) Create(daemonSet *apps.DaemonSet) (result *apps.DaemonSet, err error) { + result = &apps.DaemonSet{} err = c.client.Post(). Namespace(c.ns). Resource("daemonsets"). @@ -109,8 +109,8 @@ func (c *daemonSets) Create(daemonSet *extensions.DaemonSet) (result *extensions } // Update takes the representation of a daemonSet and updates it. Returns the server's representation of the daemonSet, and an error, if there is any. -func (c *daemonSets) Update(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) { - result = &extensions.DaemonSet{} +func (c *daemonSets) Update(daemonSet *apps.DaemonSet) (result *apps.DaemonSet, err error) { + result = &apps.DaemonSet{} err = c.client.Put(). Namespace(c.ns). Resource("daemonsets"). @@ -124,8 +124,8 @@ func (c *daemonSets) Update(daemonSet *extensions.DaemonSet) (result *extensions // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *daemonSets) UpdateStatus(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) { - result = &extensions.DaemonSet{} +func (c *daemonSets) UpdateStatus(daemonSet *apps.DaemonSet) (result *apps.DaemonSet, err error) { + result = &apps.DaemonSet{} err = c.client.Put(). Namespace(c.ns). Resource("daemonsets"). @@ -160,8 +160,8 @@ func (c *daemonSets) DeleteCollection(options *v1.DeleteOptions, listOptions v1. } // Patch applies the patch and returns the patched daemonSet. -func (c *daemonSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.DaemonSet, err error) { - result = &extensions.DaemonSet{} +func (c *daemonSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.DaemonSet, err error) { + result = &apps.DaemonSet{} err = c.client.Patch(pt). Namespace(c.ns). Resource("daemonsets"). diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/deployment.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/deployment.go similarity index 64% rename from pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/deployment.go rename to pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/deployment.go index 074ea47f72d64..0fe3a2e2c5143 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/deployment.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/deployment.go @@ -23,8 +23,7 @@ import ( types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rest "k8s.io/client-go/rest" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" - extensions "k8s.io/kubernetes/pkg/apis/extensions" + apps "k8s.io/kubernetes/pkg/apis/apps" scheme "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/scheme" ) @@ -36,18 +35,15 @@ type DeploymentsGetter interface { // DeploymentInterface has methods to work with Deployment resources. type DeploymentInterface interface { - Create(*extensions.Deployment) (*extensions.Deployment, error) - Update(*extensions.Deployment) (*extensions.Deployment, error) - UpdateStatus(*extensions.Deployment) (*extensions.Deployment, error) + Create(*apps.Deployment) (*apps.Deployment, error) + Update(*apps.Deployment) (*apps.Deployment, error) + UpdateStatus(*apps.Deployment) (*apps.Deployment, error) Delete(name string, options *v1.DeleteOptions) error DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*extensions.Deployment, error) - List(opts v1.ListOptions) (*extensions.DeploymentList, error) + Get(name string, options v1.GetOptions) (*apps.Deployment, error) + List(opts v1.ListOptions) (*apps.DeploymentList, error) Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.Deployment, err error) - GetScale(deploymentName string, options v1.GetOptions) (*autoscaling.Scale, error) - UpdateScale(deploymentName string, scale *autoscaling.Scale) (*autoscaling.Scale, error) - + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.Deployment, err error) DeploymentExpansion } @@ -58,7 +54,7 @@ type deployments struct { } // newDeployments returns a Deployments -func newDeployments(c *ExtensionsClient, namespace string) *deployments { +func newDeployments(c *AppsClient, namespace string) *deployments { return &deployments{ client: c.RESTClient(), ns: namespace, @@ -66,8 +62,8 @@ func newDeployments(c *ExtensionsClient, namespace string) *deployments { } // Get takes name of the deployment, and returns the corresponding deployment object, and an error if there is any. -func (c *deployments) Get(name string, options v1.GetOptions) (result *extensions.Deployment, err error) { - result = &extensions.Deployment{} +func (c *deployments) Get(name string, options v1.GetOptions) (result *apps.Deployment, err error) { + result = &apps.Deployment{} err = c.client.Get(). Namespace(c.ns). Resource("deployments"). @@ -79,8 +75,8 @@ func (c *deployments) Get(name string, options v1.GetOptions) (result *extension } // List takes label and field selectors, and returns the list of Deployments that match those selectors. -func (c *deployments) List(opts v1.ListOptions) (result *extensions.DeploymentList, err error) { - result = &extensions.DeploymentList{} +func (c *deployments) List(opts v1.ListOptions) (result *apps.DeploymentList, err error) { + result = &apps.DeploymentList{} err = c.client.Get(). Namespace(c.ns). Resource("deployments"). @@ -101,8 +97,8 @@ func (c *deployments) Watch(opts v1.ListOptions) (watch.Interface, error) { } // Create takes the representation of a deployment and creates it. Returns the server's representation of the deployment, and an error, if there is any. -func (c *deployments) Create(deployment *extensions.Deployment) (result *extensions.Deployment, err error) { - result = &extensions.Deployment{} +func (c *deployments) Create(deployment *apps.Deployment) (result *apps.Deployment, err error) { + result = &apps.Deployment{} err = c.client.Post(). Namespace(c.ns). Resource("deployments"). @@ -113,8 +109,8 @@ func (c *deployments) Create(deployment *extensions.Deployment) (result *extensi } // Update takes the representation of a deployment and updates it. Returns the server's representation of the deployment, and an error, if there is any. -func (c *deployments) Update(deployment *extensions.Deployment) (result *extensions.Deployment, err error) { - result = &extensions.Deployment{} +func (c *deployments) Update(deployment *apps.Deployment) (result *apps.Deployment, err error) { + result = &apps.Deployment{} err = c.client.Put(). Namespace(c.ns). Resource("deployments"). @@ -128,8 +124,8 @@ func (c *deployments) Update(deployment *extensions.Deployment) (result *extensi // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *deployments) UpdateStatus(deployment *extensions.Deployment) (result *extensions.Deployment, err error) { - result = &extensions.Deployment{} +func (c *deployments) UpdateStatus(deployment *apps.Deployment) (result *apps.Deployment, err error) { + result = &apps.Deployment{} err = c.client.Put(). Namespace(c.ns). Resource("deployments"). @@ -164,8 +160,8 @@ func (c *deployments) DeleteCollection(options *v1.DeleteOptions, listOptions v1 } // Patch applies the patch and returns the patched deployment. -func (c *deployments) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.Deployment, err error) { - result = &extensions.Deployment{} +func (c *deployments) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.Deployment, err error) { + result = &apps.Deployment{} err = c.client.Patch(pt). Namespace(c.ns). Resource("deployments"). @@ -176,31 +172,3 @@ func (c *deployments) Patch(name string, pt types.PatchType, data []byte, subres Into(result) return } - -// GetScale takes name of the deployment, and returns the corresponding autoscaling.Scale object, and an error if there is any. -func (c *deployments) GetScale(deploymentName string, options v1.GetOptions) (result *autoscaling.Scale, err error) { - result = &autoscaling.Scale{} - err = c.client.Get(). - Namespace(c.ns). - Resource("deployments"). - Name(deploymentName). - SubResource("scale"). - VersionedParams(&options, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// UpdateScale takes the top resource name and the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. -func (c *deployments) UpdateScale(deploymentName string, scale *autoscaling.Scale) (result *autoscaling.Scale, err error) { - result = &autoscaling.Scale{} - err = c.client.Put(). - Namespace(c.ns). - Resource("deployments"). - Name(deploymentName). - SubResource("scale"). - Body(scale). - Do(). - Into(result) - return -} diff --git a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/BUILD b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/BUILD index 02f8bc0553ef3..5623ca155078a 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/BUILD +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/BUILD @@ -11,12 +11,14 @@ go_library( "doc.go", "fake_apps_client.go", "fake_controllerrevision.go", + "fake_daemonset.go", + "fake_deployment.go", + "fake_replicaset.go", "fake_statefulset.go", ], importpath = "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake", deps = [ "//pkg/apis/apps:go_default_library", - "//pkg/apis/autoscaling:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/apps/internalversion:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", diff --git a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_apps_client.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_apps_client.go index de71ebdf7c038..a964464e92af9 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_apps_client.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_apps_client.go @@ -32,6 +32,18 @@ func (c *FakeApps) ControllerRevisions(namespace string) internalversion.Control return &FakeControllerRevisions{c, namespace} } +func (c *FakeApps) DaemonSets(namespace string) internalversion.DaemonSetInterface { + return &FakeDaemonSets{c, namespace} +} + +func (c *FakeApps) Deployments(namespace string) internalversion.DeploymentInterface { + return &FakeDeployments{c, namespace} +} + +func (c *FakeApps) ReplicaSets(namespace string) internalversion.ReplicaSetInterface { + return &FakeReplicaSets{c, namespace} +} + func (c *FakeApps) StatefulSets(namespace string) internalversion.StatefulSetInterface { return &FakeStatefulSets{c, namespace} } diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_daemonset.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_daemonset.go similarity index 70% rename from pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_daemonset.go rename to pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_daemonset.go index 7c96d1ec3e2ba..8f786caf365ad 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_daemonset.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_daemonset.go @@ -25,34 +25,34 @@ import ( types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" - extensions "k8s.io/kubernetes/pkg/apis/extensions" + apps "k8s.io/kubernetes/pkg/apis/apps" ) // FakeDaemonSets implements DaemonSetInterface type FakeDaemonSets struct { - Fake *FakeExtensions + Fake *FakeApps ns string } -var daemonsetsResource = schema.GroupVersionResource{Group: "extensions", Version: "", Resource: "daemonsets"} +var daemonsetsResource = schema.GroupVersionResource{Group: "apps", Version: "", Resource: "daemonsets"} -var daemonsetsKind = schema.GroupVersionKind{Group: "extensions", Version: "", Kind: "DaemonSet"} +var daemonsetsKind = schema.GroupVersionKind{Group: "apps", Version: "", Kind: "DaemonSet"} // Get takes name of the daemonSet, and returns the corresponding daemonSet object, and an error if there is any. -func (c *FakeDaemonSets) Get(name string, options v1.GetOptions) (result *extensions.DaemonSet, err error) { +func (c *FakeDaemonSets) Get(name string, options v1.GetOptions) (result *apps.DaemonSet, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(daemonsetsResource, c.ns, name), &extensions.DaemonSet{}) + Invokes(testing.NewGetAction(daemonsetsResource, c.ns, name), &apps.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*extensions.DaemonSet), err + return obj.(*apps.DaemonSet), err } // List takes label and field selectors, and returns the list of DaemonSets that match those selectors. -func (c *FakeDaemonSets) List(opts v1.ListOptions) (result *extensions.DaemonSetList, err error) { +func (c *FakeDaemonSets) List(opts v1.ListOptions) (result *apps.DaemonSetList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(daemonsetsResource, daemonsetsKind, c.ns, opts), &extensions.DaemonSetList{}) + Invokes(testing.NewListAction(daemonsetsResource, daemonsetsKind, c.ns, opts), &apps.DaemonSetList{}) if obj == nil { return nil, err @@ -62,8 +62,8 @@ func (c *FakeDaemonSets) List(opts v1.ListOptions) (result *extensions.DaemonSet if label == nil { label = labels.Everything() } - list := &extensions.DaemonSetList{ListMeta: obj.(*extensions.DaemonSetList).ListMeta} - for _, item := range obj.(*extensions.DaemonSetList).Items { + list := &apps.DaemonSetList{ListMeta: obj.(*apps.DaemonSetList).ListMeta} + for _, item := range obj.(*apps.DaemonSetList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -79,43 +79,43 @@ func (c *FakeDaemonSets) Watch(opts v1.ListOptions) (watch.Interface, error) { } // Create takes the representation of a daemonSet and creates it. Returns the server's representation of the daemonSet, and an error, if there is any. -func (c *FakeDaemonSets) Create(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) { +func (c *FakeDaemonSets) Create(daemonSet *apps.DaemonSet) (result *apps.DaemonSet, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(daemonsetsResource, c.ns, daemonSet), &extensions.DaemonSet{}) + Invokes(testing.NewCreateAction(daemonsetsResource, c.ns, daemonSet), &apps.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*extensions.DaemonSet), err + return obj.(*apps.DaemonSet), err } // Update takes the representation of a daemonSet and updates it. Returns the server's representation of the daemonSet, and an error, if there is any. -func (c *FakeDaemonSets) Update(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) { +func (c *FakeDaemonSets) Update(daemonSet *apps.DaemonSet) (result *apps.DaemonSet, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(daemonsetsResource, c.ns, daemonSet), &extensions.DaemonSet{}) + Invokes(testing.NewUpdateAction(daemonsetsResource, c.ns, daemonSet), &apps.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*extensions.DaemonSet), err + return obj.(*apps.DaemonSet), err } // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeDaemonSets) UpdateStatus(daemonSet *extensions.DaemonSet) (*extensions.DaemonSet, error) { +func (c *FakeDaemonSets) UpdateStatus(daemonSet *apps.DaemonSet) (*apps.DaemonSet, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(daemonsetsResource, "status", c.ns, daemonSet), &extensions.DaemonSet{}) + Invokes(testing.NewUpdateSubresourceAction(daemonsetsResource, "status", c.ns, daemonSet), &apps.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*extensions.DaemonSet), err + return obj.(*apps.DaemonSet), err } // Delete takes name of the daemonSet and deletes it. Returns an error if one occurs. func (c *FakeDaemonSets) Delete(name string, options *v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(daemonsetsResource, c.ns, name), &extensions.DaemonSet{}) + Invokes(testing.NewDeleteAction(daemonsetsResource, c.ns, name), &apps.DaemonSet{}) return err } @@ -124,17 +124,17 @@ func (c *FakeDaemonSets) Delete(name string, options *v1.DeleteOptions) error { func (c *FakeDaemonSets) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { action := testing.NewDeleteCollectionAction(daemonsetsResource, c.ns, listOptions) - _, err := c.Fake.Invokes(action, &extensions.DaemonSetList{}) + _, err := c.Fake.Invokes(action, &apps.DaemonSetList{}) return err } // Patch applies the patch and returns the patched daemonSet. -func (c *FakeDaemonSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.DaemonSet, err error) { +func (c *FakeDaemonSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.DaemonSet, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(daemonsetsResource, c.ns, name, pt, data, subresources...), &extensions.DaemonSet{}) + Invokes(testing.NewPatchSubresourceAction(daemonsetsResource, c.ns, name, pt, data, subresources...), &apps.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*extensions.DaemonSet), err + return obj.(*apps.DaemonSet), err } diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_deployment.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_deployment.go similarity index 58% rename from pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_deployment.go rename to pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_deployment.go index 97ca031cf08c5..f1623d308aba5 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_deployment.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_deployment.go @@ -25,35 +25,34 @@ import ( types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" - extensions "k8s.io/kubernetes/pkg/apis/extensions" + apps "k8s.io/kubernetes/pkg/apis/apps" ) // FakeDeployments implements DeploymentInterface type FakeDeployments struct { - Fake *FakeExtensions + Fake *FakeApps ns string } -var deploymentsResource = schema.GroupVersionResource{Group: "extensions", Version: "", Resource: "deployments"} +var deploymentsResource = schema.GroupVersionResource{Group: "apps", Version: "", Resource: "deployments"} -var deploymentsKind = schema.GroupVersionKind{Group: "extensions", Version: "", Kind: "Deployment"} +var deploymentsKind = schema.GroupVersionKind{Group: "apps", Version: "", Kind: "Deployment"} // Get takes name of the deployment, and returns the corresponding deployment object, and an error if there is any. -func (c *FakeDeployments) Get(name string, options v1.GetOptions) (result *extensions.Deployment, err error) { +func (c *FakeDeployments) Get(name string, options v1.GetOptions) (result *apps.Deployment, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(deploymentsResource, c.ns, name), &extensions.Deployment{}) + Invokes(testing.NewGetAction(deploymentsResource, c.ns, name), &apps.Deployment{}) if obj == nil { return nil, err } - return obj.(*extensions.Deployment), err + return obj.(*apps.Deployment), err } // List takes label and field selectors, and returns the list of Deployments that match those selectors. -func (c *FakeDeployments) List(opts v1.ListOptions) (result *extensions.DeploymentList, err error) { +func (c *FakeDeployments) List(opts v1.ListOptions) (result *apps.DeploymentList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(deploymentsResource, deploymentsKind, c.ns, opts), &extensions.DeploymentList{}) + Invokes(testing.NewListAction(deploymentsResource, deploymentsKind, c.ns, opts), &apps.DeploymentList{}) if obj == nil { return nil, err @@ -63,8 +62,8 @@ func (c *FakeDeployments) List(opts v1.ListOptions) (result *extensions.Deployme if label == nil { label = labels.Everything() } - list := &extensions.DeploymentList{ListMeta: obj.(*extensions.DeploymentList).ListMeta} - for _, item := range obj.(*extensions.DeploymentList).Items { + list := &apps.DeploymentList{ListMeta: obj.(*apps.DeploymentList).ListMeta} + for _, item := range obj.(*apps.DeploymentList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -80,43 +79,43 @@ func (c *FakeDeployments) Watch(opts v1.ListOptions) (watch.Interface, error) { } // Create takes the representation of a deployment and creates it. Returns the server's representation of the deployment, and an error, if there is any. -func (c *FakeDeployments) Create(deployment *extensions.Deployment) (result *extensions.Deployment, err error) { +func (c *FakeDeployments) Create(deployment *apps.Deployment) (result *apps.Deployment, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(deploymentsResource, c.ns, deployment), &extensions.Deployment{}) + Invokes(testing.NewCreateAction(deploymentsResource, c.ns, deployment), &apps.Deployment{}) if obj == nil { return nil, err } - return obj.(*extensions.Deployment), err + return obj.(*apps.Deployment), err } // Update takes the representation of a deployment and updates it. Returns the server's representation of the deployment, and an error, if there is any. -func (c *FakeDeployments) Update(deployment *extensions.Deployment) (result *extensions.Deployment, err error) { +func (c *FakeDeployments) Update(deployment *apps.Deployment) (result *apps.Deployment, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(deploymentsResource, c.ns, deployment), &extensions.Deployment{}) + Invokes(testing.NewUpdateAction(deploymentsResource, c.ns, deployment), &apps.Deployment{}) if obj == nil { return nil, err } - return obj.(*extensions.Deployment), err + return obj.(*apps.Deployment), err } // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeDeployments) UpdateStatus(deployment *extensions.Deployment) (*extensions.Deployment, error) { +func (c *FakeDeployments) UpdateStatus(deployment *apps.Deployment) (*apps.Deployment, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(deploymentsResource, "status", c.ns, deployment), &extensions.Deployment{}) + Invokes(testing.NewUpdateSubresourceAction(deploymentsResource, "status", c.ns, deployment), &apps.Deployment{}) if obj == nil { return nil, err } - return obj.(*extensions.Deployment), err + return obj.(*apps.Deployment), err } // Delete takes name of the deployment and deletes it. Returns an error if one occurs. func (c *FakeDeployments) Delete(name string, options *v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(deploymentsResource, c.ns, name), &extensions.Deployment{}) + Invokes(testing.NewDeleteAction(deploymentsResource, c.ns, name), &apps.Deployment{}) return err } @@ -125,39 +124,17 @@ func (c *FakeDeployments) Delete(name string, options *v1.DeleteOptions) error { func (c *FakeDeployments) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { action := testing.NewDeleteCollectionAction(deploymentsResource, c.ns, listOptions) - _, err := c.Fake.Invokes(action, &extensions.DeploymentList{}) + _, err := c.Fake.Invokes(action, &apps.DeploymentList{}) return err } // Patch applies the patch and returns the patched deployment. -func (c *FakeDeployments) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.Deployment, err error) { +func (c *FakeDeployments) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.Deployment, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(deploymentsResource, c.ns, name, pt, data, subresources...), &extensions.Deployment{}) + Invokes(testing.NewPatchSubresourceAction(deploymentsResource, c.ns, name, pt, data, subresources...), &apps.Deployment{}) if obj == nil { return nil, err } - return obj.(*extensions.Deployment), err -} - -// GetScale takes name of the deployment, and returns the corresponding scale object, and an error if there is any. -func (c *FakeDeployments) GetScale(deploymentName string, options v1.GetOptions) (result *autoscaling.Scale, err error) { - obj, err := c.Fake. - Invokes(testing.NewGetSubresourceAction(deploymentsResource, c.ns, "scale", deploymentName), &autoscaling.Scale{}) - - if obj == nil { - return nil, err - } - return obj.(*autoscaling.Scale), err -} - -// UpdateScale takes the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. -func (c *FakeDeployments) UpdateScale(deploymentName string, scale *autoscaling.Scale) (result *autoscaling.Scale, err error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(deploymentsResource, "scale", c.ns, scale), &autoscaling.Scale{}) - - if obj == nil { - return nil, err - } - return obj.(*autoscaling.Scale), err + return obj.(*apps.Deployment), err } diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_replicaset.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_replicaset.go similarity index 58% rename from pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_replicaset.go rename to pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_replicaset.go index 067c510293171..88c28d42eb3a4 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_replicaset.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_replicaset.go @@ -25,35 +25,34 @@ import ( types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" - extensions "k8s.io/kubernetes/pkg/apis/extensions" + apps "k8s.io/kubernetes/pkg/apis/apps" ) // FakeReplicaSets implements ReplicaSetInterface type FakeReplicaSets struct { - Fake *FakeExtensions + Fake *FakeApps ns string } -var replicasetsResource = schema.GroupVersionResource{Group: "extensions", Version: "", Resource: "replicasets"} +var replicasetsResource = schema.GroupVersionResource{Group: "apps", Version: "", Resource: "replicasets"} -var replicasetsKind = schema.GroupVersionKind{Group: "extensions", Version: "", Kind: "ReplicaSet"} +var replicasetsKind = schema.GroupVersionKind{Group: "apps", Version: "", Kind: "ReplicaSet"} // Get takes name of the replicaSet, and returns the corresponding replicaSet object, and an error if there is any. -func (c *FakeReplicaSets) Get(name string, options v1.GetOptions) (result *extensions.ReplicaSet, err error) { +func (c *FakeReplicaSets) Get(name string, options v1.GetOptions) (result *apps.ReplicaSet, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(replicasetsResource, c.ns, name), &extensions.ReplicaSet{}) + Invokes(testing.NewGetAction(replicasetsResource, c.ns, name), &apps.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*extensions.ReplicaSet), err + return obj.(*apps.ReplicaSet), err } // List takes label and field selectors, and returns the list of ReplicaSets that match those selectors. -func (c *FakeReplicaSets) List(opts v1.ListOptions) (result *extensions.ReplicaSetList, err error) { +func (c *FakeReplicaSets) List(opts v1.ListOptions) (result *apps.ReplicaSetList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(replicasetsResource, replicasetsKind, c.ns, opts), &extensions.ReplicaSetList{}) + Invokes(testing.NewListAction(replicasetsResource, replicasetsKind, c.ns, opts), &apps.ReplicaSetList{}) if obj == nil { return nil, err @@ -63,8 +62,8 @@ func (c *FakeReplicaSets) List(opts v1.ListOptions) (result *extensions.ReplicaS if label == nil { label = labels.Everything() } - list := &extensions.ReplicaSetList{ListMeta: obj.(*extensions.ReplicaSetList).ListMeta} - for _, item := range obj.(*extensions.ReplicaSetList).Items { + list := &apps.ReplicaSetList{ListMeta: obj.(*apps.ReplicaSetList).ListMeta} + for _, item := range obj.(*apps.ReplicaSetList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -80,43 +79,43 @@ func (c *FakeReplicaSets) Watch(opts v1.ListOptions) (watch.Interface, error) { } // Create takes the representation of a replicaSet and creates it. Returns the server's representation of the replicaSet, and an error, if there is any. -func (c *FakeReplicaSets) Create(replicaSet *extensions.ReplicaSet) (result *extensions.ReplicaSet, err error) { +func (c *FakeReplicaSets) Create(replicaSet *apps.ReplicaSet) (result *apps.ReplicaSet, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(replicasetsResource, c.ns, replicaSet), &extensions.ReplicaSet{}) + Invokes(testing.NewCreateAction(replicasetsResource, c.ns, replicaSet), &apps.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*extensions.ReplicaSet), err + return obj.(*apps.ReplicaSet), err } // Update takes the representation of a replicaSet and updates it. Returns the server's representation of the replicaSet, and an error, if there is any. -func (c *FakeReplicaSets) Update(replicaSet *extensions.ReplicaSet) (result *extensions.ReplicaSet, err error) { +func (c *FakeReplicaSets) Update(replicaSet *apps.ReplicaSet) (result *apps.ReplicaSet, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(replicasetsResource, c.ns, replicaSet), &extensions.ReplicaSet{}) + Invokes(testing.NewUpdateAction(replicasetsResource, c.ns, replicaSet), &apps.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*extensions.ReplicaSet), err + return obj.(*apps.ReplicaSet), err } // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeReplicaSets) UpdateStatus(replicaSet *extensions.ReplicaSet) (*extensions.ReplicaSet, error) { +func (c *FakeReplicaSets) UpdateStatus(replicaSet *apps.ReplicaSet) (*apps.ReplicaSet, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(replicasetsResource, "status", c.ns, replicaSet), &extensions.ReplicaSet{}) + Invokes(testing.NewUpdateSubresourceAction(replicasetsResource, "status", c.ns, replicaSet), &apps.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*extensions.ReplicaSet), err + return obj.(*apps.ReplicaSet), err } // Delete takes name of the replicaSet and deletes it. Returns an error if one occurs. func (c *FakeReplicaSets) Delete(name string, options *v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(replicasetsResource, c.ns, name), &extensions.ReplicaSet{}) + Invokes(testing.NewDeleteAction(replicasetsResource, c.ns, name), &apps.ReplicaSet{}) return err } @@ -125,39 +124,17 @@ func (c *FakeReplicaSets) Delete(name string, options *v1.DeleteOptions) error { func (c *FakeReplicaSets) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { action := testing.NewDeleteCollectionAction(replicasetsResource, c.ns, listOptions) - _, err := c.Fake.Invokes(action, &extensions.ReplicaSetList{}) + _, err := c.Fake.Invokes(action, &apps.ReplicaSetList{}) return err } // Patch applies the patch and returns the patched replicaSet. -func (c *FakeReplicaSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.ReplicaSet, err error) { +func (c *FakeReplicaSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.ReplicaSet, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(replicasetsResource, c.ns, name, pt, data, subresources...), &extensions.ReplicaSet{}) + Invokes(testing.NewPatchSubresourceAction(replicasetsResource, c.ns, name, pt, data, subresources...), &apps.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*extensions.ReplicaSet), err -} - -// GetScale takes name of the replicaSet, and returns the corresponding scale object, and an error if there is any. -func (c *FakeReplicaSets) GetScale(replicaSetName string, options v1.GetOptions) (result *autoscaling.Scale, err error) { - obj, err := c.Fake. - Invokes(testing.NewGetSubresourceAction(replicasetsResource, c.ns, "scale", replicaSetName), &autoscaling.Scale{}) - - if obj == nil { - return nil, err - } - return obj.(*autoscaling.Scale), err -} - -// UpdateScale takes the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. -func (c *FakeReplicaSets) UpdateScale(replicaSetName string, scale *autoscaling.Scale) (result *autoscaling.Scale, err error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(replicasetsResource, "scale", c.ns, scale), &autoscaling.Scale{}) - - if obj == nil { - return nil, err - } - return obj.(*autoscaling.Scale), err + return obj.(*apps.ReplicaSet), err } diff --git a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_statefulset.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_statefulset.go index ba1be4a4bcc7b..6a875708a25c1 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_statefulset.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/fake/fake_statefulset.go @@ -26,7 +26,6 @@ import ( watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" apps "k8s.io/kubernetes/pkg/apis/apps" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" ) // FakeStatefulSets implements StatefulSetInterface @@ -139,25 +138,3 @@ func (c *FakeStatefulSets) Patch(name string, pt types.PatchType, data []byte, s } return obj.(*apps.StatefulSet), err } - -// GetScale takes name of the statefulSet, and returns the corresponding scale object, and an error if there is any. -func (c *FakeStatefulSets) GetScale(statefulSetName string, options v1.GetOptions) (result *autoscaling.Scale, err error) { - obj, err := c.Fake. - Invokes(testing.NewGetSubresourceAction(statefulsetsResource, c.ns, "scale", statefulSetName), &autoscaling.Scale{}) - - if obj == nil { - return nil, err - } - return obj.(*autoscaling.Scale), err -} - -// UpdateScale takes the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. -func (c *FakeStatefulSets) UpdateScale(statefulSetName string, scale *autoscaling.Scale) (result *autoscaling.Scale, err error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(statefulsetsResource, "scale", c.ns, scale), &autoscaling.Scale{}) - - if obj == nil { - return nil, err - } - return obj.(*autoscaling.Scale), err -} diff --git a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/generated_expansion.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/generated_expansion.go index 9bfab85765022..7987f18b259c6 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/generated_expansion.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/generated_expansion.go @@ -20,4 +20,10 @@ package internalversion type ControllerRevisionExpansion interface{} +type DaemonSetExpansion interface{} + +type DeploymentExpansion interface{} + +type ReplicaSetExpansion interface{} + type StatefulSetExpansion interface{} diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/replicaset.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/replicaset.go similarity index 64% rename from pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/replicaset.go rename to pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/replicaset.go index b2263cb09ed5f..f213722d68bc0 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/replicaset.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/replicaset.go @@ -23,8 +23,7 @@ import ( types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rest "k8s.io/client-go/rest" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" - extensions "k8s.io/kubernetes/pkg/apis/extensions" + apps "k8s.io/kubernetes/pkg/apis/apps" scheme "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/scheme" ) @@ -36,18 +35,15 @@ type ReplicaSetsGetter interface { // ReplicaSetInterface has methods to work with ReplicaSet resources. type ReplicaSetInterface interface { - Create(*extensions.ReplicaSet) (*extensions.ReplicaSet, error) - Update(*extensions.ReplicaSet) (*extensions.ReplicaSet, error) - UpdateStatus(*extensions.ReplicaSet) (*extensions.ReplicaSet, error) + Create(*apps.ReplicaSet) (*apps.ReplicaSet, error) + Update(*apps.ReplicaSet) (*apps.ReplicaSet, error) + UpdateStatus(*apps.ReplicaSet) (*apps.ReplicaSet, error) Delete(name string, options *v1.DeleteOptions) error DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*extensions.ReplicaSet, error) - List(opts v1.ListOptions) (*extensions.ReplicaSetList, error) + Get(name string, options v1.GetOptions) (*apps.ReplicaSet, error) + List(opts v1.ListOptions) (*apps.ReplicaSetList, error) Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.ReplicaSet, err error) - GetScale(replicaSetName string, options v1.GetOptions) (*autoscaling.Scale, error) - UpdateScale(replicaSetName string, scale *autoscaling.Scale) (*autoscaling.Scale, error) - + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.ReplicaSet, err error) ReplicaSetExpansion } @@ -58,7 +54,7 @@ type replicaSets struct { } // newReplicaSets returns a ReplicaSets -func newReplicaSets(c *ExtensionsClient, namespace string) *replicaSets { +func newReplicaSets(c *AppsClient, namespace string) *replicaSets { return &replicaSets{ client: c.RESTClient(), ns: namespace, @@ -66,8 +62,8 @@ func newReplicaSets(c *ExtensionsClient, namespace string) *replicaSets { } // Get takes name of the replicaSet, and returns the corresponding replicaSet object, and an error if there is any. -func (c *replicaSets) Get(name string, options v1.GetOptions) (result *extensions.ReplicaSet, err error) { - result = &extensions.ReplicaSet{} +func (c *replicaSets) Get(name string, options v1.GetOptions) (result *apps.ReplicaSet, err error) { + result = &apps.ReplicaSet{} err = c.client.Get(). Namespace(c.ns). Resource("replicasets"). @@ -79,8 +75,8 @@ func (c *replicaSets) Get(name string, options v1.GetOptions) (result *extension } // List takes label and field selectors, and returns the list of ReplicaSets that match those selectors. -func (c *replicaSets) List(opts v1.ListOptions) (result *extensions.ReplicaSetList, err error) { - result = &extensions.ReplicaSetList{} +func (c *replicaSets) List(opts v1.ListOptions) (result *apps.ReplicaSetList, err error) { + result = &apps.ReplicaSetList{} err = c.client.Get(). Namespace(c.ns). Resource("replicasets"). @@ -101,8 +97,8 @@ func (c *replicaSets) Watch(opts v1.ListOptions) (watch.Interface, error) { } // Create takes the representation of a replicaSet and creates it. Returns the server's representation of the replicaSet, and an error, if there is any. -func (c *replicaSets) Create(replicaSet *extensions.ReplicaSet) (result *extensions.ReplicaSet, err error) { - result = &extensions.ReplicaSet{} +func (c *replicaSets) Create(replicaSet *apps.ReplicaSet) (result *apps.ReplicaSet, err error) { + result = &apps.ReplicaSet{} err = c.client.Post(). Namespace(c.ns). Resource("replicasets"). @@ -113,8 +109,8 @@ func (c *replicaSets) Create(replicaSet *extensions.ReplicaSet) (result *extensi } // Update takes the representation of a replicaSet and updates it. Returns the server's representation of the replicaSet, and an error, if there is any. -func (c *replicaSets) Update(replicaSet *extensions.ReplicaSet) (result *extensions.ReplicaSet, err error) { - result = &extensions.ReplicaSet{} +func (c *replicaSets) Update(replicaSet *apps.ReplicaSet) (result *apps.ReplicaSet, err error) { + result = &apps.ReplicaSet{} err = c.client.Put(). Namespace(c.ns). Resource("replicasets"). @@ -128,8 +124,8 @@ func (c *replicaSets) Update(replicaSet *extensions.ReplicaSet) (result *extensi // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *replicaSets) UpdateStatus(replicaSet *extensions.ReplicaSet) (result *extensions.ReplicaSet, err error) { - result = &extensions.ReplicaSet{} +func (c *replicaSets) UpdateStatus(replicaSet *apps.ReplicaSet) (result *apps.ReplicaSet, err error) { + result = &apps.ReplicaSet{} err = c.client.Put(). Namespace(c.ns). Resource("replicasets"). @@ -164,8 +160,8 @@ func (c *replicaSets) DeleteCollection(options *v1.DeleteOptions, listOptions v1 } // Patch applies the patch and returns the patched replicaSet. -func (c *replicaSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *extensions.ReplicaSet, err error) { - result = &extensions.ReplicaSet{} +func (c *replicaSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.ReplicaSet, err error) { + result = &apps.ReplicaSet{} err = c.client.Patch(pt). Namespace(c.ns). Resource("replicasets"). @@ -176,31 +172,3 @@ func (c *replicaSets) Patch(name string, pt types.PatchType, data []byte, subres Into(result) return } - -// GetScale takes name of the replicaSet, and returns the corresponding autoscaling.Scale object, and an error if there is any. -func (c *replicaSets) GetScale(replicaSetName string, options v1.GetOptions) (result *autoscaling.Scale, err error) { - result = &autoscaling.Scale{} - err = c.client.Get(). - Namespace(c.ns). - Resource("replicasets"). - Name(replicaSetName). - SubResource("scale"). - VersionedParams(&options, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// UpdateScale takes the top resource name and the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. -func (c *replicaSets) UpdateScale(replicaSetName string, scale *autoscaling.Scale) (result *autoscaling.Scale, err error) { - result = &autoscaling.Scale{} - err = c.client.Put(). - Namespace(c.ns). - Resource("replicasets"). - Name(replicaSetName). - SubResource("scale"). - Body(scale). - Do(). - Into(result) - return -} diff --git a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/statefulset.go b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/statefulset.go index 4d1e5fa16fde9..b9eb391e9a0bc 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/statefulset.go +++ b/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion/statefulset.go @@ -24,7 +24,6 @@ import ( watch "k8s.io/apimachinery/pkg/watch" rest "k8s.io/client-go/rest" apps "k8s.io/kubernetes/pkg/apis/apps" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" scheme "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/scheme" ) @@ -45,9 +44,6 @@ type StatefulSetInterface interface { List(opts v1.ListOptions) (*apps.StatefulSetList, error) Watch(opts v1.ListOptions) (watch.Interface, error) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.StatefulSet, err error) - GetScale(statefulSetName string, options v1.GetOptions) (*autoscaling.Scale, error) - UpdateScale(statefulSetName string, scale *autoscaling.Scale) (*autoscaling.Scale, error) - StatefulSetExpansion } @@ -176,31 +172,3 @@ func (c *statefulSets) Patch(name string, pt types.PatchType, data []byte, subre Into(result) return } - -// GetScale takes name of the statefulSet, and returns the corresponding autoscaling.Scale object, and an error if there is any. -func (c *statefulSets) GetScale(statefulSetName string, options v1.GetOptions) (result *autoscaling.Scale, err error) { - result = &autoscaling.Scale{} - err = c.client.Get(). - Namespace(c.ns). - Resource("statefulsets"). - Name(statefulSetName). - SubResource("scale"). - VersionedParams(&options, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// UpdateScale takes the top resource name and the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. -func (c *statefulSets) UpdateScale(statefulSetName string, scale *autoscaling.Scale) (result *autoscaling.Scale, err error) { - result = &autoscaling.Scale{} - err = c.client.Put(). - Namespace(c.ns). - Resource("statefulsets"). - Name(statefulSetName). - SubResource("scale"). - Body(scale). - Do(). - Into(result) - return -} diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/BUILD b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/BUILD index 97770ae84496a..6fb0ee1557ecd 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/BUILD +++ b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/BUILD @@ -8,18 +8,13 @@ load( go_library( name = "go_default_library", srcs = [ - "daemonset.go", - "deployment.go", - "deployment_expansion.go", "doc.go", "extensions_client.go", "generated_expansion.go", "ingress.go", - "replicaset.go", ], importpath = "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion", deps = [ - "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/client/clientset_generated/internalclientset/scheme:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/deployment_expansion.go b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/deployment_expansion.go deleted file mode 100644 index f8d7a1c6341c3..0000000000000 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/deployment_expansion.go +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2016 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 internalversion - -import "k8s.io/kubernetes/pkg/apis/extensions" - -// The DeploymentExpansion interface allows manually adding extra methods to the DeploymentInterface. -type DeploymentExpansion interface { - Rollback(*extensions.DeploymentRollback) error -} - -// Rollback applied the provided DeploymentRollback to the named deployment in the current namespace. -func (c *deployments) Rollback(deploymentRollback *extensions.DeploymentRollback) error { - return c.client.Post().Namespace(c.ns).Resource("deployments").Name(deploymentRollback.Name).SubResource("rollback").Body(deploymentRollback).Do().Error() -} diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/extensions_client.go b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/extensions_client.go index 43ea79be3233b..b7a7df1b96cd4 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/extensions_client.go +++ b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/extensions_client.go @@ -25,10 +25,7 @@ import ( type ExtensionsInterface interface { RESTClient() rest.Interface - DaemonSetsGetter - DeploymentsGetter IngressesGetter - ReplicaSetsGetter } // ExtensionsClient is used to interact with features provided by the extensions group. @@ -36,22 +33,10 @@ type ExtensionsClient struct { restClient rest.Interface } -func (c *ExtensionsClient) DaemonSets(namespace string) DaemonSetInterface { - return newDaemonSets(c, namespace) -} - -func (c *ExtensionsClient) Deployments(namespace string) DeploymentInterface { - return newDeployments(c, namespace) -} - func (c *ExtensionsClient) Ingresses(namespace string) IngressInterface { return newIngresses(c, namespace) } -func (c *ExtensionsClient) ReplicaSets(namespace string) ReplicaSetInterface { - return newReplicaSets(c, namespace) -} - // NewForConfig creates a new ExtensionsClient for the given config. func NewForConfig(c *rest.Config) (*ExtensionsClient, error) { config := *c diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/BUILD b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/BUILD index e75f0acee7b58..a7551ee5ed45f 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/BUILD +++ b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/BUILD @@ -9,16 +9,11 @@ go_library( name = "go_default_library", srcs = [ "doc.go", - "fake_daemonset.go", - "fake_deployment.go", - "fake_deployment_expansion.go", "fake_extensions_client.go", "fake_ingress.go", - "fake_replicaset.go", ], importpath = "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake", deps = [ - "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_deployment_expansion.go b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_deployment_expansion.go deleted file mode 100644 index eec9d55d95255..0000000000000 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_deployment_expansion.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2014 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 fake - -import ( - core "k8s.io/client-go/testing" - "k8s.io/kubernetes/pkg/apis/extensions" -) - -func (c *FakeDeployments) Rollback(deploymentRollback *extensions.DeploymentRollback) error { - action := core.CreateActionImpl{} - action.Verb = "create" - action.Resource = deploymentsResource - action.Subresource = "rollback" - action.Object = deploymentRollback - - _, err := c.Fake.Invokes(action, deploymentRollback) - return err -} diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_extensions_client.go b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_extensions_client.go index 1336d8558cdf0..016e1bec064db 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_extensions_client.go +++ b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/fake/fake_extensions_client.go @@ -28,22 +28,10 @@ type FakeExtensions struct { *testing.Fake } -func (c *FakeExtensions) DaemonSets(namespace string) internalversion.DaemonSetInterface { - return &FakeDaemonSets{c, namespace} -} - -func (c *FakeExtensions) Deployments(namespace string) internalversion.DeploymentInterface { - return &FakeDeployments{c, namespace} -} - func (c *FakeExtensions) Ingresses(namespace string) internalversion.IngressInterface { return &FakeIngresses{c, namespace} } -func (c *FakeExtensions) ReplicaSets(namespace string) internalversion.ReplicaSetInterface { - return &FakeReplicaSets{c, namespace} -} - // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeExtensions) RESTClient() rest.Interface { diff --git a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/generated_expansion.go b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/generated_expansion.go index 2560f4a32d14b..3c1593ccf5e54 100644 --- a/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/generated_expansion.go +++ b/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion/generated_expansion.go @@ -18,8 +18,4 @@ limitations under the License. package internalversion -type DaemonSetExpansion interface{} - type IngressExpansion interface{} - -type ReplicaSetExpansion interface{} diff --git a/pkg/client/informers/informers_generated/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/BUILD deleted file mode 100644 index febac107a40c3..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/BUILD +++ /dev/null @@ -1,84 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "factory.go", - "generic.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion", - deps = [ - "//pkg/apis/admissionregistration:go_default_library", - "//pkg/apis/apps:go_default_library", - "//pkg/apis/auditregistration:go_default_library", - "//pkg/apis/autoscaling:go_default_library", - "//pkg/apis/batch:go_default_library", - "//pkg/apis/certificates:go_default_library", - "//pkg/apis/coordination:go_default_library", - "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", - "//pkg/apis/networking:go_default_library", - "//pkg/apis/policy:go_default_library", - "//pkg/apis/rbac:go_default_library", - "//pkg/apis/scheduling:go_default_library", - "//pkg/apis/settings:go_default_library", - "//pkg/apis/storage:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/admissionregistration:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/apps:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/auditregistration:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/autoscaling:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/batch:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/certificates:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/coordination:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/core:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/extensions:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/networking:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/policy:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/rbac:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/scheduling:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/settings:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/storage:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/admissionregistration:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/apps:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/auditregistration:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/autoscaling:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/batch:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/certificates:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/coordination:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/core:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/extensions:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/networking:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/policy:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/rbac:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/scheduling:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/settings:all-srcs", - "//pkg/client/informers/informers_generated/internalversion/storage:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/admissionregistration/BUILD b/pkg/client/informers/informers_generated/internalversion/admissionregistration/BUILD deleted file mode 100644 index 0c993a743c010..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/admissionregistration/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/admissionregistration", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/admissionregistration/interface.go b/pkg/client/informers/informers_generated/internalversion/admissionregistration/interface.go deleted file mode 100644 index 2ff34d93fa05f..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/admissionregistration/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package admissionregistration - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/BUILD deleted file mode 100644 index a086ab74e4f8f..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/BUILD +++ /dev/null @@ -1,40 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "initializerconfiguration.go", - "interface.go", - "mutatingwebhookconfiguration.go", - "validatingwebhookconfiguration.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion", - deps = [ - "//pkg/apis/admissionregistration:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/admissionregistration/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/initializerconfiguration.go b/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/initializerconfiguration.go deleted file mode 100644 index 898fd48670d6c..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/initializerconfiguration.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/admissionregistration/internalversion" -) - -// InitializerConfigurationInformer provides access to a shared informer and lister for -// InitializerConfigurations. -type InitializerConfigurationInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.InitializerConfigurationLister -} - -type initializerConfigurationInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewInitializerConfigurationInformer constructs a new informer for InitializerConfiguration type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewInitializerConfigurationInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredInitializerConfigurationInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredInitializerConfigurationInformer constructs a new informer for InitializerConfiguration type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredInitializerConfigurationInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Admissionregistration().InitializerConfigurations().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Admissionregistration().InitializerConfigurations().Watch(options) - }, - }, - &admissionregistration.InitializerConfiguration{}, - resyncPeriod, - indexers, - ) -} - -func (f *initializerConfigurationInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredInitializerConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *initializerConfigurationInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&admissionregistration.InitializerConfiguration{}, f.defaultInformer) -} - -func (f *initializerConfigurationInformer) Lister() internalversion.InitializerConfigurationLister { - return internalversion.NewInitializerConfigurationLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/interface.go deleted file mode 100644 index 9955e6b9ca7af..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/interface.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // InitializerConfigurations returns a InitializerConfigurationInformer. - InitializerConfigurations() InitializerConfigurationInformer - // MutatingWebhookConfigurations returns a MutatingWebhookConfigurationInformer. - MutatingWebhookConfigurations() MutatingWebhookConfigurationInformer - // ValidatingWebhookConfigurations returns a ValidatingWebhookConfigurationInformer. - ValidatingWebhookConfigurations() ValidatingWebhookConfigurationInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InitializerConfigurations returns a InitializerConfigurationInformer. -func (v *version) InitializerConfigurations() InitializerConfigurationInformer { - return &initializerConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// MutatingWebhookConfigurations returns a MutatingWebhookConfigurationInformer. -func (v *version) MutatingWebhookConfigurations() MutatingWebhookConfigurationInformer { - return &mutatingWebhookConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// ValidatingWebhookConfigurations returns a ValidatingWebhookConfigurationInformer. -func (v *version) ValidatingWebhookConfigurations() ValidatingWebhookConfigurationInformer { - return &validatingWebhookConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/mutatingwebhookconfiguration.go b/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/mutatingwebhookconfiguration.go deleted file mode 100644 index 01b65bd564608..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/mutatingwebhookconfiguration.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/admissionregistration/internalversion" -) - -// MutatingWebhookConfigurationInformer provides access to a shared informer and lister for -// MutatingWebhookConfigurations. -type MutatingWebhookConfigurationInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.MutatingWebhookConfigurationLister -} - -type mutatingWebhookConfigurationInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewMutatingWebhookConfigurationInformer constructs a new informer for MutatingWebhookConfiguration type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewMutatingWebhookConfigurationInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredMutatingWebhookConfigurationInformer constructs a new informer for MutatingWebhookConfiguration type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredMutatingWebhookConfigurationInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Admissionregistration().MutatingWebhookConfigurations().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Admissionregistration().MutatingWebhookConfigurations().Watch(options) - }, - }, - &admissionregistration.MutatingWebhookConfiguration{}, - resyncPeriod, - indexers, - ) -} - -func (f *mutatingWebhookConfigurationInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *mutatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&admissionregistration.MutatingWebhookConfiguration{}, f.defaultInformer) -} - -func (f *mutatingWebhookConfigurationInformer) Lister() internalversion.MutatingWebhookConfigurationLister { - return internalversion.NewMutatingWebhookConfigurationLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/validatingwebhookconfiguration.go b/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/validatingwebhookconfiguration.go deleted file mode 100644 index b1bcb715f3e0b..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/admissionregistration/internalversion/validatingwebhookconfiguration.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/admissionregistration/internalversion" -) - -// ValidatingWebhookConfigurationInformer provides access to a shared informer and lister for -// ValidatingWebhookConfigurations. -type ValidatingWebhookConfigurationInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ValidatingWebhookConfigurationLister -} - -type validatingWebhookConfigurationInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewValidatingWebhookConfigurationInformer constructs a new informer for ValidatingWebhookConfiguration type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewValidatingWebhookConfigurationInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredValidatingWebhookConfigurationInformer constructs a new informer for ValidatingWebhookConfiguration type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredValidatingWebhookConfigurationInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Admissionregistration().ValidatingWebhookConfigurations().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Admissionregistration().ValidatingWebhookConfigurations().Watch(options) - }, - }, - &admissionregistration.ValidatingWebhookConfiguration{}, - resyncPeriod, - indexers, - ) -} - -func (f *validatingWebhookConfigurationInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *validatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&admissionregistration.ValidatingWebhookConfiguration{}, f.defaultInformer) -} - -func (f *validatingWebhookConfigurationInformer) Lister() internalversion.ValidatingWebhookConfigurationLister { - return internalversion.NewValidatingWebhookConfigurationLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/apps/BUILD b/pkg/client/informers/informers_generated/internalversion/apps/BUILD deleted file mode 100644 index be3d8f6f5aabe..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/apps/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/apps", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/apps/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/apps/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/apps/interface.go b/pkg/client/informers/informers_generated/internalversion/apps/interface.go deleted file mode 100644 index 1291f39796908..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/apps/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package apps - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/apps/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/apps/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/apps/internalversion/BUILD deleted file mode 100644 index 33c4f5c574aa1..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/apps/internalversion/BUILD +++ /dev/null @@ -1,39 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "controllerrevision.go", - "interface.go", - "statefulset.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/apps/internalversion", - deps = [ - "//pkg/apis/apps:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/apps/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/apps/internalversion/controllerrevision.go b/pkg/client/informers/informers_generated/internalversion/apps/internalversion/controllerrevision.go deleted file mode 100644 index ed13860674391..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/apps/internalversion/controllerrevision.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - apps "k8s.io/kubernetes/pkg/apis/apps" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/apps/internalversion" -) - -// ControllerRevisionInformer provides access to a shared informer and lister for -// ControllerRevisions. -type ControllerRevisionInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ControllerRevisionLister -} - -type controllerRevisionInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewControllerRevisionInformer constructs a new informer for ControllerRevision type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewControllerRevisionInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredControllerRevisionInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredControllerRevisionInformer constructs a new informer for ControllerRevision type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredControllerRevisionInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Apps().ControllerRevisions(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Apps().ControllerRevisions(namespace).Watch(options) - }, - }, - &apps.ControllerRevision{}, - resyncPeriod, - indexers, - ) -} - -func (f *controllerRevisionInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredControllerRevisionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apps.ControllerRevision{}, f.defaultInformer) -} - -func (f *controllerRevisionInformer) Lister() internalversion.ControllerRevisionLister { - return internalversion.NewControllerRevisionLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/apps/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/apps/internalversion/interface.go deleted file mode 100644 index 9dbb8fcb78bb2..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/apps/internalversion/interface.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // ControllerRevisions returns a ControllerRevisionInformer. - ControllerRevisions() ControllerRevisionInformer - // StatefulSets returns a StatefulSetInformer. - StatefulSets() StatefulSetInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// ControllerRevisions returns a ControllerRevisionInformer. -func (v *version) ControllerRevisions() ControllerRevisionInformer { - return &controllerRevisionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// StatefulSets returns a StatefulSetInformer. -func (v *version) StatefulSets() StatefulSetInformer { - return &statefulSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/apps/internalversion/statefulset.go b/pkg/client/informers/informers_generated/internalversion/apps/internalversion/statefulset.go deleted file mode 100644 index 32c6f583a0b86..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/apps/internalversion/statefulset.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - apps "k8s.io/kubernetes/pkg/apis/apps" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/apps/internalversion" -) - -// StatefulSetInformer provides access to a shared informer and lister for -// StatefulSets. -type StatefulSetInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.StatefulSetLister -} - -type statefulSetInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewStatefulSetInformer constructs a new informer for StatefulSet type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewStatefulSetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStatefulSetInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredStatefulSetInformer constructs a new informer for StatefulSet type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredStatefulSetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Apps().StatefulSets(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Apps().StatefulSets(namespace).Watch(options) - }, - }, - &apps.StatefulSet{}, - resyncPeriod, - indexers, - ) -} - -func (f *statefulSetInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStatefulSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *statefulSetInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apps.StatefulSet{}, f.defaultInformer) -} - -func (f *statefulSetInformer) Lister() internalversion.StatefulSetLister { - return internalversion.NewStatefulSetLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/auditregistration/BUILD b/pkg/client/informers/informers_generated/internalversion/auditregistration/BUILD deleted file mode 100644 index 66d103acd280e..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/auditregistration/BUILD +++ /dev/null @@ -1,29 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/auditregistration", - visibility = ["//visibility:public"], - deps = [ - "//pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion:all-srcs", - ], - tags = ["automanaged"], - visibility = ["//visibility:public"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/auditregistration/interface.go b/pkg/client/informers/informers_generated/internalversion/auditregistration/interface.go deleted file mode 100644 index 4340986bd0989..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/auditregistration/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package auditregistration - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/BUILD deleted file mode 100644 index 51da67f1c4347..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/BUILD +++ /dev/null @@ -1,35 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "auditsink.go", - "interface.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion", - visibility = ["//visibility:public"], - deps = [ - "//pkg/apis/auditregistration:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/auditregistration/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/auditsink.go b/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/auditsink.go deleted file mode 100644 index 328962ba1d37e..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/auditsink.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - auditregistration "k8s.io/kubernetes/pkg/apis/auditregistration" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/auditregistration/internalversion" -) - -// AuditSinkInformer provides access to a shared informer and lister for -// AuditSinks. -type AuditSinkInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.AuditSinkLister -} - -type auditSinkInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewAuditSinkInformer constructs a new informer for AuditSink type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewAuditSinkInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredAuditSinkInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredAuditSinkInformer constructs a new informer for AuditSink type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredAuditSinkInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Auditregistration().AuditSinks().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Auditregistration().AuditSinks().Watch(options) - }, - }, - &auditregistration.AuditSink{}, - resyncPeriod, - indexers, - ) -} - -func (f *auditSinkInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredAuditSinkInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *auditSinkInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&auditregistration.AuditSink{}, f.defaultInformer) -} - -func (f *auditSinkInformer) Lister() internalversion.AuditSinkLister { - return internalversion.NewAuditSinkLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/interface.go deleted file mode 100644 index 94164ee06e14c..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/auditregistration/internalversion/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // AuditSinks returns a AuditSinkInformer. - AuditSinks() AuditSinkInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// AuditSinks returns a AuditSinkInformer. -func (v *version) AuditSinks() AuditSinkInformer { - return &auditSinkInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/autoscaling/BUILD b/pkg/client/informers/informers_generated/internalversion/autoscaling/BUILD deleted file mode 100644 index 7f48220955fbf..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/autoscaling/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/autoscaling", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/autoscaling/interface.go b/pkg/client/informers/informers_generated/internalversion/autoscaling/interface.go deleted file mode 100644 index b918859fb70ea..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/autoscaling/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package autoscaling - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/BUILD deleted file mode 100644 index fbada0330ab6a..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/BUILD +++ /dev/null @@ -1,38 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "horizontalpodautoscaler.go", - "interface.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion", - deps = [ - "//pkg/apis/autoscaling:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/autoscaling/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/horizontalpodautoscaler.go b/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/horizontalpodautoscaler.go deleted file mode 100644 index 4bdf2f6102908..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/horizontalpodautoscaler.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/autoscaling/internalversion" -) - -// HorizontalPodAutoscalerInformer provides access to a shared informer and lister for -// HorizontalPodAutoscalers. -type HorizontalPodAutoscalerInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.HorizontalPodAutoscalerLister -} - -type horizontalPodAutoscalerInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewHorizontalPodAutoscalerInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredHorizontalPodAutoscalerInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Autoscaling().HorizontalPodAutoscalers(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Autoscaling().HorizontalPodAutoscalers(namespace).Watch(options) - }, - }, - &autoscaling.HorizontalPodAutoscaler{}, - resyncPeriod, - indexers, - ) -} - -func (f *horizontalPodAutoscalerInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&autoscaling.HorizontalPodAutoscaler{}, f.defaultInformer) -} - -func (f *horizontalPodAutoscalerInformer) Lister() internalversion.HorizontalPodAutoscalerLister { - return internalversion.NewHorizontalPodAutoscalerLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/interface.go deleted file mode 100644 index b1f4104a01380..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/autoscaling/internalversion/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. - HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. -func (v *version) HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer { - return &horizontalPodAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/batch/BUILD b/pkg/client/informers/informers_generated/internalversion/batch/BUILD deleted file mode 100644 index 536b976f4cbb3..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/batch/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/batch", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/batch/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/batch/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/batch/interface.go b/pkg/client/informers/informers_generated/internalversion/batch/interface.go deleted file mode 100644 index 84416cb37e719..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/batch/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package batch - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/batch/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/batch/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/batch/internalversion/BUILD deleted file mode 100644 index b2315e06f67a4..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/batch/internalversion/BUILD +++ /dev/null @@ -1,39 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "cronjob.go", - "interface.go", - "job.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/batch/internalversion", - deps = [ - "//pkg/apis/batch:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/batch/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/batch/internalversion/cronjob.go b/pkg/client/informers/informers_generated/internalversion/batch/internalversion/cronjob.go deleted file mode 100644 index 66388b5fe5106..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/batch/internalversion/cronjob.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - batch "k8s.io/kubernetes/pkg/apis/batch" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/batch/internalversion" -) - -// CronJobInformer provides access to a shared informer and lister for -// CronJobs. -type CronJobInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.CronJobLister -} - -type cronJobInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewCronJobInformer constructs a new informer for CronJob type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewCronJobInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCronJobInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredCronJobInformer constructs a new informer for CronJob type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredCronJobInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Batch().CronJobs(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Batch().CronJobs(namespace).Watch(options) - }, - }, - &batch.CronJob{}, - resyncPeriod, - indexers, - ) -} - -func (f *cronJobInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCronJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *cronJobInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&batch.CronJob{}, f.defaultInformer) -} - -func (f *cronJobInformer) Lister() internalversion.CronJobLister { - return internalversion.NewCronJobLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/batch/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/batch/internalversion/interface.go deleted file mode 100644 index 7f808b5ba8434..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/batch/internalversion/interface.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // CronJobs returns a CronJobInformer. - CronJobs() CronJobInformer - // Jobs returns a JobInformer. - Jobs() JobInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// CronJobs returns a CronJobInformer. -func (v *version) CronJobs() CronJobInformer { - return &cronJobInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Jobs returns a JobInformer. -func (v *version) Jobs() JobInformer { - return &jobInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/batch/internalversion/job.go b/pkg/client/informers/informers_generated/internalversion/batch/internalversion/job.go deleted file mode 100644 index 0926fcddb4566..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/batch/internalversion/job.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - batch "k8s.io/kubernetes/pkg/apis/batch" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/batch/internalversion" -) - -// JobInformer provides access to a shared informer and lister for -// Jobs. -type JobInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.JobLister -} - -type jobInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewJobInformer constructs a new informer for Job type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewJobInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredJobInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredJobInformer constructs a new informer for Job type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredJobInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Batch().Jobs(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Batch().Jobs(namespace).Watch(options) - }, - }, - &batch.Job{}, - resyncPeriod, - indexers, - ) -} - -func (f *jobInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *jobInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&batch.Job{}, f.defaultInformer) -} - -func (f *jobInformer) Lister() internalversion.JobLister { - return internalversion.NewJobLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/certificates/BUILD b/pkg/client/informers/informers_generated/internalversion/certificates/BUILD deleted file mode 100644 index 013c84a91d036..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/certificates/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/certificates", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/certificates/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/certificates/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/certificates/interface.go b/pkg/client/informers/informers_generated/internalversion/certificates/interface.go deleted file mode 100644 index 7f87468051be9..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/certificates/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package certificates - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/certificates/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/BUILD deleted file mode 100644 index 5332aac13b899..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/BUILD +++ /dev/null @@ -1,38 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "certificatesigningrequest.go", - "interface.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/certificates/internalversion", - deps = [ - "//pkg/apis/certificates:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/certificates/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/certificatesigningrequest.go b/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/certificatesigningrequest.go deleted file mode 100644 index 49be6ed0d7bca..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/certificatesigningrequest.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - certificates "k8s.io/kubernetes/pkg/apis/certificates" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/certificates/internalversion" -) - -// CertificateSigningRequestInformer provides access to a shared informer and lister for -// CertificateSigningRequests. -type CertificateSigningRequestInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.CertificateSigningRequestLister -} - -type certificateSigningRequestInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewCertificateSigningRequestInformer constructs a new informer for CertificateSigningRequest type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewCertificateSigningRequestInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredCertificateSigningRequestInformer constructs a new informer for CertificateSigningRequest type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredCertificateSigningRequestInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Certificates().CertificateSigningRequests().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Certificates().CertificateSigningRequests().Watch(options) - }, - }, - &certificates.CertificateSigningRequest{}, - resyncPeriod, - indexers, - ) -} - -func (f *certificateSigningRequestInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *certificateSigningRequestInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&certificates.CertificateSigningRequest{}, f.defaultInformer) -} - -func (f *certificateSigningRequestInformer) Lister() internalversion.CertificateSigningRequestLister { - return internalversion.NewCertificateSigningRequestLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/interface.go deleted file mode 100644 index 7cad24c3edcc9..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/certificates/internalversion/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // CertificateSigningRequests returns a CertificateSigningRequestInformer. - CertificateSigningRequests() CertificateSigningRequestInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// CertificateSigningRequests returns a CertificateSigningRequestInformer. -func (v *version) CertificateSigningRequests() CertificateSigningRequestInformer { - return &certificateSigningRequestInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/coordination/BUILD b/pkg/client/informers/informers_generated/internalversion/coordination/BUILD deleted file mode 100644 index aad9ae90e5344..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/coordination/BUILD +++ /dev/null @@ -1,29 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/coordination", - visibility = ["//visibility:public"], - deps = [ - "//pkg/client/informers/informers_generated/internalversion/coordination/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/coordination/internalversion:all-srcs", - ], - tags = ["automanaged"], - visibility = ["//visibility:public"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/coordination/interface.go b/pkg/client/informers/informers_generated/internalversion/coordination/interface.go deleted file mode 100644 index 5aa5d2deb9ec8..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/coordination/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package coordination - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/coordination/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/BUILD deleted file mode 100644 index 0fb46577e12ad..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/BUILD +++ /dev/null @@ -1,35 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "interface.go", - "lease.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/coordination/internalversion", - visibility = ["//visibility:public"], - deps = [ - "//pkg/apis/coordination:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/coordination/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/interface.go deleted file mode 100644 index 4209303d79351..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // Leases returns a LeaseInformer. - Leases() LeaseInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// Leases returns a LeaseInformer. -func (v *version) Leases() LeaseInformer { - return &leaseInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/lease.go b/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/lease.go deleted file mode 100644 index 598fce6043200..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/coordination/internalversion/lease.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - coordination "k8s.io/kubernetes/pkg/apis/coordination" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/coordination/internalversion" -) - -// LeaseInformer provides access to a shared informer and lister for -// Leases. -type LeaseInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.LeaseLister -} - -type leaseInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewLeaseInformer constructs a new informer for Lease type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewLeaseInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredLeaseInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredLeaseInformer constructs a new informer for Lease type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredLeaseInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Coordination().Leases(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Coordination().Leases(namespace).Watch(options) - }, - }, - &coordination.Lease{}, - resyncPeriod, - indexers, - ) -} - -func (f *leaseInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredLeaseInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *leaseInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&coordination.Lease{}, f.defaultInformer) -} - -func (f *leaseInformer) Lister() internalversion.LeaseLister { - return internalversion.NewLeaseLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/BUILD b/pkg/client/informers/informers_generated/internalversion/core/BUILD deleted file mode 100644 index ef8ca96e8d530..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/core", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/core/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/core/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/core/interface.go b/pkg/client/informers/informers_generated/internalversion/core/interface.go deleted file mode 100644 index b0a9365d451f8..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package core - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/core/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/core/internalversion/BUILD deleted file mode 100644 index 36f7f0b9b27ec..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/BUILD +++ /dev/null @@ -1,53 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "componentstatus.go", - "configmap.go", - "endpoints.go", - "event.go", - "interface.go", - "limitrange.go", - "namespace.go", - "node.go", - "persistentvolume.go", - "persistentvolumeclaim.go", - "pod.go", - "podtemplate.go", - "replicationcontroller.go", - "resourcequota.go", - "secret.go", - "service.go", - "serviceaccount.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/core/internalversion", - deps = [ - "//pkg/apis/core:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/core/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/core/internalversion/componentstatus.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/componentstatus.go deleted file mode 100644 index 68521873fde11..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/componentstatus.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// ComponentStatusInformer provides access to a shared informer and lister for -// ComponentStatuses. -type ComponentStatusInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ComponentStatusLister -} - -type componentStatusInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewComponentStatusInformer constructs a new informer for ComponentStatus type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewComponentStatusInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredComponentStatusInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredComponentStatusInformer constructs a new informer for ComponentStatus type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredComponentStatusInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ComponentStatuses().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ComponentStatuses().Watch(options) - }, - }, - &core.ComponentStatus{}, - resyncPeriod, - indexers, - ) -} - -func (f *componentStatusInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredComponentStatusInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *componentStatusInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.ComponentStatus{}, f.defaultInformer) -} - -func (f *componentStatusInformer) Lister() internalversion.ComponentStatusLister { - return internalversion.NewComponentStatusLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/configmap.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/configmap.go deleted file mode 100644 index 7c15f2320976c..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/configmap.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// ConfigMapInformer provides access to a shared informer and lister for -// ConfigMaps. -type ConfigMapInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ConfigMapLister -} - -type configMapInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewConfigMapInformer constructs a new informer for ConfigMap type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewConfigMapInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredConfigMapInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredConfigMapInformer constructs a new informer for ConfigMap type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredConfigMapInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ConfigMaps(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ConfigMaps(namespace).Watch(options) - }, - }, - &core.ConfigMap{}, - resyncPeriod, - indexers, - ) -} - -func (f *configMapInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredConfigMapInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *configMapInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.ConfigMap{}, f.defaultInformer) -} - -func (f *configMapInformer) Lister() internalversion.ConfigMapLister { - return internalversion.NewConfigMapLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/endpoints.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/endpoints.go deleted file mode 100644 index 64078fcc2e658..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/endpoints.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// EndpointsInformer provides access to a shared informer and lister for -// Endpoints. -type EndpointsInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.EndpointsLister -} - -type endpointsInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewEndpointsInformer constructs a new informer for Endpoints type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewEndpointsInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEndpointsInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredEndpointsInformer constructs a new informer for Endpoints type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredEndpointsInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Endpoints(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Endpoints(namespace).Watch(options) - }, - }, - &core.Endpoints{}, - resyncPeriod, - indexers, - ) -} - -func (f *endpointsInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEndpointsInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *endpointsInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.Endpoints{}, f.defaultInformer) -} - -func (f *endpointsInformer) Lister() internalversion.EndpointsLister { - return internalversion.NewEndpointsLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/event.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/event.go deleted file mode 100644 index d1a01e6554cf5..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/event.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// EventInformer provides access to a shared informer and lister for -// Events. -type EventInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.EventLister -} - -type eventInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewEventInformer constructs a new informer for Event type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewEventInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEventInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredEventInformer constructs a new informer for Event type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredEventInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Events(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Events(namespace).Watch(options) - }, - }, - &core.Event{}, - resyncPeriod, - indexers, - ) -} - -func (f *eventInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEventInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *eventInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.Event{}, f.defaultInformer) -} - -func (f *eventInformer) Lister() internalversion.EventLister { - return internalversion.NewEventLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/interface.go deleted file mode 100644 index 57ba136048cc3..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/interface.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // ComponentStatuses returns a ComponentStatusInformer. - ComponentStatuses() ComponentStatusInformer - // ConfigMaps returns a ConfigMapInformer. - ConfigMaps() ConfigMapInformer - // Endpoints returns a EndpointsInformer. - Endpoints() EndpointsInformer - // Events returns a EventInformer. - Events() EventInformer - // LimitRanges returns a LimitRangeInformer. - LimitRanges() LimitRangeInformer - // Namespaces returns a NamespaceInformer. - Namespaces() NamespaceInformer - // Nodes returns a NodeInformer. - Nodes() NodeInformer - // PersistentVolumes returns a PersistentVolumeInformer. - PersistentVolumes() PersistentVolumeInformer - // PersistentVolumeClaims returns a PersistentVolumeClaimInformer. - PersistentVolumeClaims() PersistentVolumeClaimInformer - // Pods returns a PodInformer. - Pods() PodInformer - // PodTemplates returns a PodTemplateInformer. - PodTemplates() PodTemplateInformer - // ReplicationControllers returns a ReplicationControllerInformer. - ReplicationControllers() ReplicationControllerInformer - // ResourceQuotas returns a ResourceQuotaInformer. - ResourceQuotas() ResourceQuotaInformer - // Secrets returns a SecretInformer. - Secrets() SecretInformer - // Services returns a ServiceInformer. - Services() ServiceInformer - // ServiceAccounts returns a ServiceAccountInformer. - ServiceAccounts() ServiceAccountInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// ComponentStatuses returns a ComponentStatusInformer. -func (v *version) ComponentStatuses() ComponentStatusInformer { - return &componentStatusInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// ConfigMaps returns a ConfigMapInformer. -func (v *version) ConfigMaps() ConfigMapInformer { - return &configMapInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Endpoints returns a EndpointsInformer. -func (v *version) Endpoints() EndpointsInformer { - return &endpointsInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Events returns a EventInformer. -func (v *version) Events() EventInformer { - return &eventInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// LimitRanges returns a LimitRangeInformer. -func (v *version) LimitRanges() LimitRangeInformer { - return &limitRangeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Namespaces returns a NamespaceInformer. -func (v *version) Namespaces() NamespaceInformer { - return &namespaceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// Nodes returns a NodeInformer. -func (v *version) Nodes() NodeInformer { - return &nodeInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// PersistentVolumes returns a PersistentVolumeInformer. -func (v *version) PersistentVolumes() PersistentVolumeInformer { - return &persistentVolumeInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// PersistentVolumeClaims returns a PersistentVolumeClaimInformer. -func (v *version) PersistentVolumeClaims() PersistentVolumeClaimInformer { - return &persistentVolumeClaimInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Pods returns a PodInformer. -func (v *version) Pods() PodInformer { - return &podInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// PodTemplates returns a PodTemplateInformer. -func (v *version) PodTemplates() PodTemplateInformer { - return &podTemplateInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// ReplicationControllers returns a ReplicationControllerInformer. -func (v *version) ReplicationControllers() ReplicationControllerInformer { - return &replicationControllerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// ResourceQuotas returns a ResourceQuotaInformer. -func (v *version) ResourceQuotas() ResourceQuotaInformer { - return &resourceQuotaInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Secrets returns a SecretInformer. -func (v *version) Secrets() SecretInformer { - return &secretInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Services returns a ServiceInformer. -func (v *version) Services() ServiceInformer { - return &serviceInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// ServiceAccounts returns a ServiceAccountInformer. -func (v *version) ServiceAccounts() ServiceAccountInformer { - return &serviceAccountInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/limitrange.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/limitrange.go deleted file mode 100644 index aec069188a7fe..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/limitrange.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// LimitRangeInformer provides access to a shared informer and lister for -// LimitRanges. -type LimitRangeInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.LimitRangeLister -} - -type limitRangeInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewLimitRangeInformer constructs a new informer for LimitRange type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewLimitRangeInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredLimitRangeInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredLimitRangeInformer constructs a new informer for LimitRange type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredLimitRangeInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().LimitRanges(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().LimitRanges(namespace).Watch(options) - }, - }, - &core.LimitRange{}, - resyncPeriod, - indexers, - ) -} - -func (f *limitRangeInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredLimitRangeInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *limitRangeInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.LimitRange{}, f.defaultInformer) -} - -func (f *limitRangeInformer) Lister() internalversion.LimitRangeLister { - return internalversion.NewLimitRangeLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/namespace.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/namespace.go deleted file mode 100644 index 538c3f5fd874c..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/namespace.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// NamespaceInformer provides access to a shared informer and lister for -// Namespaces. -type NamespaceInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.NamespaceLister -} - -type namespaceInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewNamespaceInformer constructs a new informer for Namespace type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewNamespaceInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNamespaceInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredNamespaceInformer constructs a new informer for Namespace type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredNamespaceInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Namespaces().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Namespaces().Watch(options) - }, - }, - &core.Namespace{}, - resyncPeriod, - indexers, - ) -} - -func (f *namespaceInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNamespaceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *namespaceInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.Namespace{}, f.defaultInformer) -} - -func (f *namespaceInformer) Lister() internalversion.NamespaceLister { - return internalversion.NewNamespaceLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/node.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/node.go deleted file mode 100644 index aa24935374a57..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/node.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// NodeInformer provides access to a shared informer and lister for -// Nodes. -type NodeInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.NodeLister -} - -type nodeInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewNodeInformer constructs a new informer for Node type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewNodeInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNodeInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredNodeInformer constructs a new informer for Node type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredNodeInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Nodes().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Nodes().Watch(options) - }, - }, - &core.Node{}, - resyncPeriod, - indexers, - ) -} - -func (f *nodeInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *nodeInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.Node{}, f.defaultInformer) -} - -func (f *nodeInformer) Lister() internalversion.NodeLister { - return internalversion.NewNodeLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/persistentvolume.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/persistentvolume.go deleted file mode 100644 index 708cb37322b7a..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/persistentvolume.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// PersistentVolumeInformer provides access to a shared informer and lister for -// PersistentVolumes. -type PersistentVolumeInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.PersistentVolumeLister -} - -type persistentVolumeInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewPersistentVolumeInformer constructs a new informer for PersistentVolume type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPersistentVolumeInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPersistentVolumeInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredPersistentVolumeInformer constructs a new informer for PersistentVolume type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPersistentVolumeInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().PersistentVolumes().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().PersistentVolumes().Watch(options) - }, - }, - &core.PersistentVolume{}, - resyncPeriod, - indexers, - ) -} - -func (f *persistentVolumeInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPersistentVolumeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *persistentVolumeInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.PersistentVolume{}, f.defaultInformer) -} - -func (f *persistentVolumeInformer) Lister() internalversion.PersistentVolumeLister { - return internalversion.NewPersistentVolumeLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/persistentvolumeclaim.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/persistentvolumeclaim.go deleted file mode 100644 index bc70a44a198a0..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/persistentvolumeclaim.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// PersistentVolumeClaimInformer provides access to a shared informer and lister for -// PersistentVolumeClaims. -type PersistentVolumeClaimInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.PersistentVolumeClaimLister -} - -type persistentVolumeClaimInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewPersistentVolumeClaimInformer constructs a new informer for PersistentVolumeClaim type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPersistentVolumeClaimInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPersistentVolumeClaimInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredPersistentVolumeClaimInformer constructs a new informer for PersistentVolumeClaim type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPersistentVolumeClaimInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().PersistentVolumeClaims(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().PersistentVolumeClaims(namespace).Watch(options) - }, - }, - &core.PersistentVolumeClaim{}, - resyncPeriod, - indexers, - ) -} - -func (f *persistentVolumeClaimInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPersistentVolumeClaimInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *persistentVolumeClaimInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.PersistentVolumeClaim{}, f.defaultInformer) -} - -func (f *persistentVolumeClaimInformer) Lister() internalversion.PersistentVolumeClaimLister { - return internalversion.NewPersistentVolumeClaimLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/pod.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/pod.go deleted file mode 100644 index de3377eeb7802..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/pod.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// PodInformer provides access to a shared informer and lister for -// Pods. -type PodInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.PodLister -} - -type podInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewPodInformer constructs a new informer for Pod type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPodInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredPodInformer constructs a new informer for Pod type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPodInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Pods(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Pods(namespace).Watch(options) - }, - }, - &core.Pod{}, - resyncPeriod, - indexers, - ) -} - -func (f *podInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *podInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.Pod{}, f.defaultInformer) -} - -func (f *podInformer) Lister() internalversion.PodLister { - return internalversion.NewPodLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/podtemplate.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/podtemplate.go deleted file mode 100644 index 25718f44e8463..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/podtemplate.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// PodTemplateInformer provides access to a shared informer and lister for -// PodTemplates. -type PodTemplateInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.PodTemplateLister -} - -type podTemplateInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewPodTemplateInformer constructs a new informer for PodTemplate type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPodTemplateInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodTemplateInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredPodTemplateInformer constructs a new informer for PodTemplate type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPodTemplateInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().PodTemplates(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().PodTemplates(namespace).Watch(options) - }, - }, - &core.PodTemplate{}, - resyncPeriod, - indexers, - ) -} - -func (f *podTemplateInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodTemplateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *podTemplateInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.PodTemplate{}, f.defaultInformer) -} - -func (f *podTemplateInformer) Lister() internalversion.PodTemplateLister { - return internalversion.NewPodTemplateLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/replicationcontroller.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/replicationcontroller.go deleted file mode 100644 index 1819ad981eab1..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/replicationcontroller.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// ReplicationControllerInformer provides access to a shared informer and lister for -// ReplicationControllers. -type ReplicationControllerInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ReplicationControllerLister -} - -type replicationControllerInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewReplicationControllerInformer constructs a new informer for ReplicationController type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewReplicationControllerInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredReplicationControllerInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredReplicationControllerInformer constructs a new informer for ReplicationController type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredReplicationControllerInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ReplicationControllers(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ReplicationControllers(namespace).Watch(options) - }, - }, - &core.ReplicationController{}, - resyncPeriod, - indexers, - ) -} - -func (f *replicationControllerInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredReplicationControllerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *replicationControllerInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.ReplicationController{}, f.defaultInformer) -} - -func (f *replicationControllerInformer) Lister() internalversion.ReplicationControllerLister { - return internalversion.NewReplicationControllerLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/resourcequota.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/resourcequota.go deleted file mode 100644 index 63a80dd89c90d..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/resourcequota.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// ResourceQuotaInformer provides access to a shared informer and lister for -// ResourceQuotas. -type ResourceQuotaInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ResourceQuotaLister -} - -type resourceQuotaInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewResourceQuotaInformer constructs a new informer for ResourceQuota type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewResourceQuotaInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceQuotaInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredResourceQuotaInformer constructs a new informer for ResourceQuota type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredResourceQuotaInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ResourceQuotas(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ResourceQuotas(namespace).Watch(options) - }, - }, - &core.ResourceQuota{}, - resyncPeriod, - indexers, - ) -} - -func (f *resourceQuotaInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceQuotaInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *resourceQuotaInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.ResourceQuota{}, f.defaultInformer) -} - -func (f *resourceQuotaInformer) Lister() internalversion.ResourceQuotaLister { - return internalversion.NewResourceQuotaLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/secret.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/secret.go deleted file mode 100644 index eb5ed238cbdb1..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/secret.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// SecretInformer provides access to a shared informer and lister for -// Secrets. -type SecretInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.SecretLister -} - -type secretInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewSecretInformer constructs a new informer for Secret type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewSecretInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredSecretInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredSecretInformer constructs a new informer for Secret type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredSecretInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Secrets(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Secrets(namespace).Watch(options) - }, - }, - &core.Secret{}, - resyncPeriod, - indexers, - ) -} - -func (f *secretInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredSecretInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *secretInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.Secret{}, f.defaultInformer) -} - -func (f *secretInformer) Lister() internalversion.SecretLister { - return internalversion.NewSecretLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/service.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/service.go deleted file mode 100644 index a1bbff4375bc4..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/service.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// ServiceInformer provides access to a shared informer and lister for -// Services. -type ServiceInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ServiceLister -} - -type serviceInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewServiceInformer constructs a new informer for Service type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewServiceInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredServiceInformer constructs a new informer for Service type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredServiceInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Services(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().Services(namespace).Watch(options) - }, - }, - &core.Service{}, - resyncPeriod, - indexers, - ) -} - -func (f *serviceInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *serviceInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.Service{}, f.defaultInformer) -} - -func (f *serviceInformer) Lister() internalversion.ServiceLister { - return internalversion.NewServiceLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/core/internalversion/serviceaccount.go b/pkg/client/informers/informers_generated/internalversion/core/internalversion/serviceaccount.go deleted file mode 100644 index 49e6de949291f..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/core/internalversion/serviceaccount.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion" -) - -// ServiceAccountInformer provides access to a shared informer and lister for -// ServiceAccounts. -type ServiceAccountInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ServiceAccountLister -} - -type serviceAccountInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewServiceAccountInformer constructs a new informer for ServiceAccount type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewServiceAccountInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceAccountInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredServiceAccountInformer constructs a new informer for ServiceAccount type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredServiceAccountInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ServiceAccounts(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Core().ServiceAccounts(namespace).Watch(options) - }, - }, - &core.ServiceAccount{}, - resyncPeriod, - indexers, - ) -} - -func (f *serviceAccountInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceAccountInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *serviceAccountInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&core.ServiceAccount{}, f.defaultInformer) -} - -func (f *serviceAccountInformer) Lister() internalversion.ServiceAccountLister { - return internalversion.NewServiceAccountLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/extensions/BUILD b/pkg/client/informers/informers_generated/internalversion/extensions/BUILD deleted file mode 100644 index df9dfcf4b0fa7..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/extensions/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/extensions", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/extensions/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/extensions/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/extensions/interface.go b/pkg/client/informers/informers_generated/internalversion/extensions/interface.go deleted file mode 100644 index 2cdeff7c72cc3..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/extensions/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package extensions - -import ( - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/extensions/internalversion" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/BUILD deleted file mode 100644 index c7558b2f7bcaf..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/BUILD +++ /dev/null @@ -1,41 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "daemonset.go", - "deployment.go", - "ingress.go", - "interface.go", - "replicaset.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/extensions/internalversion", - deps = [ - "//pkg/apis/extensions:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/extensions/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/daemonset.go b/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/daemonset.go deleted file mode 100644 index af07582557d74..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/daemonset.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - extensions "k8s.io/kubernetes/pkg/apis/extensions" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion" -) - -// DaemonSetInformer provides access to a shared informer and lister for -// DaemonSets. -type DaemonSetInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.DaemonSetLister -} - -type daemonSetInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewDaemonSetInformer constructs a new informer for DaemonSet type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewDaemonSetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDaemonSetInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredDaemonSetInformer constructs a new informer for DaemonSet type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredDaemonSetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Extensions().DaemonSets(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Extensions().DaemonSets(namespace).Watch(options) - }, - }, - &extensions.DaemonSet{}, - resyncPeriod, - indexers, - ) -} - -func (f *daemonSetInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDaemonSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *daemonSetInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&extensions.DaemonSet{}, f.defaultInformer) -} - -func (f *daemonSetInformer) Lister() internalversion.DaemonSetLister { - return internalversion.NewDaemonSetLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/deployment.go b/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/deployment.go deleted file mode 100644 index 76267c8f079a0..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/deployment.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - extensions "k8s.io/kubernetes/pkg/apis/extensions" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion" -) - -// DeploymentInformer provides access to a shared informer and lister for -// Deployments. -type DeploymentInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.DeploymentLister -} - -type deploymentInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewDeploymentInformer constructs a new informer for Deployment type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewDeploymentInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredDeploymentInformer constructs a new informer for Deployment type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredDeploymentInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Extensions().Deployments(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Extensions().Deployments(namespace).Watch(options) - }, - }, - &extensions.Deployment{}, - resyncPeriod, - indexers, - ) -} - -func (f *deploymentInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *deploymentInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&extensions.Deployment{}, f.defaultInformer) -} - -func (f *deploymentInformer) Lister() internalversion.DeploymentLister { - return internalversion.NewDeploymentLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/ingress.go b/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/ingress.go deleted file mode 100644 index 31a963ef789ab..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/ingress.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - extensions "k8s.io/kubernetes/pkg/apis/extensions" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion" -) - -// IngressInformer provides access to a shared informer and lister for -// Ingresses. -type IngressInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.IngressLister -} - -type ingressInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewIngressInformer constructs a new informer for Ingress type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewIngressInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredIngressInformer constructs a new informer for Ingress type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredIngressInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Extensions().Ingresses(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Extensions().Ingresses(namespace).Watch(options) - }, - }, - &extensions.Ingress{}, - resyncPeriod, - indexers, - ) -} - -func (f *ingressInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *ingressInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&extensions.Ingress{}, f.defaultInformer) -} - -func (f *ingressInformer) Lister() internalversion.IngressLister { - return internalversion.NewIngressLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/interface.go deleted file mode 100644 index a6c2aee0f423e..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/interface.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // DaemonSets returns a DaemonSetInformer. - DaemonSets() DaemonSetInformer - // Deployments returns a DeploymentInformer. - Deployments() DeploymentInformer - // Ingresses returns a IngressInformer. - Ingresses() IngressInformer - // ReplicaSets returns a ReplicaSetInformer. - ReplicaSets() ReplicaSetInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// DaemonSets returns a DaemonSetInformer. -func (v *version) DaemonSets() DaemonSetInformer { - return &daemonSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Deployments returns a DeploymentInformer. -func (v *version) Deployments() DeploymentInformer { - return &deploymentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Ingresses returns a IngressInformer. -func (v *version) Ingresses() IngressInformer { - return &ingressInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// ReplicaSets returns a ReplicaSetInformer. -func (v *version) ReplicaSets() ReplicaSetInformer { - return &replicaSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/replicaset.go b/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/replicaset.go deleted file mode 100644 index 9a8defe614903..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/extensions/internalversion/replicaset.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - extensions "k8s.io/kubernetes/pkg/apis/extensions" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion" -) - -// ReplicaSetInformer provides access to a shared informer and lister for -// ReplicaSets. -type ReplicaSetInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ReplicaSetLister -} - -type replicaSetInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewReplicaSetInformer constructs a new informer for ReplicaSet type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewReplicaSetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredReplicaSetInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredReplicaSetInformer constructs a new informer for ReplicaSet type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredReplicaSetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Extensions().ReplicaSets(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Extensions().ReplicaSets(namespace).Watch(options) - }, - }, - &extensions.ReplicaSet{}, - resyncPeriod, - indexers, - ) -} - -func (f *replicaSetInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredReplicaSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *replicaSetInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&extensions.ReplicaSet{}, f.defaultInformer) -} - -func (f *replicaSetInformer) Lister() internalversion.ReplicaSetLister { - return internalversion.NewReplicaSetLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/factory.go b/pkg/client/informers/informers_generated/internalversion/factory.go deleted file mode 100644 index 7997c6e859e12..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/factory.go +++ /dev/null @@ -1,264 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - reflect "reflect" - sync "sync" - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - schema "k8s.io/apimachinery/pkg/runtime/schema" - cache "k8s.io/client-go/tools/cache" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - admissionregistration "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/admissionregistration" - apps "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/apps" - auditregistration "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/auditregistration" - autoscaling "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/autoscaling" - batch "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/batch" - certificates "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/certificates" - coordination "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/coordination" - core "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/core" - extensions "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/extensions" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - networking "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/networking" - policy "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/policy" - rbac "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/rbac" - scheduling "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/scheduling" - settings "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/settings" - storage "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/storage" -) - -// SharedInformerOption defines the functional option type for SharedInformerFactory. -type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory - -type sharedInformerFactory struct { - client internalclientset.Interface - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc - lock sync.Mutex - defaultResync time.Duration - customResync map[reflect.Type]time.Duration - - informers map[reflect.Type]cache.SharedIndexInformer - // startedInformers is used for tracking which informers have been started. - // This allows Start() to be called multiple times safely. - startedInformers map[reflect.Type]bool -} - -// WithCustomResyncConfig sets a custom resync period for the specified informer types. -func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - for k, v := range resyncConfig { - factory.customResync[reflect.TypeOf(k)] = v - } - return factory - } -} - -// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. -func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - factory.tweakListOptions = tweakListOptions - return factory - } -} - -// WithNamespace limits the SharedInformerFactory to the specified namespace. -func WithNamespace(namespace string) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - factory.namespace = namespace - return factory - } -} - -// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. -func NewSharedInformerFactory(client internalclientset.Interface, defaultResync time.Duration) SharedInformerFactory { - return NewSharedInformerFactoryWithOptions(client, defaultResync) -} - -// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. -// Listers obtained via this SharedInformerFactory will be subject to the same filters -// as specified here. -// Deprecated: Please use NewSharedInformerFactoryWithOptions instead -func NewFilteredSharedInformerFactory(client internalclientset.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory { - return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) -} - -// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. -func NewSharedInformerFactoryWithOptions(client internalclientset.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory { - factory := &sharedInformerFactory{ - client: client, - namespace: v1.NamespaceAll, - defaultResync: defaultResync, - informers: make(map[reflect.Type]cache.SharedIndexInformer), - startedInformers: make(map[reflect.Type]bool), - customResync: make(map[reflect.Type]time.Duration), - } - - // Apply all options - for _, opt := range options { - factory = opt(factory) - } - - return factory -} - -// Start initializes all requested informers. -func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { - f.lock.Lock() - defer f.lock.Unlock() - - for informerType, informer := range f.informers { - if !f.startedInformers[informerType] { - go informer.Run(stopCh) - f.startedInformers[informerType] = true - } - } -} - -// WaitForCacheSync waits for all started informers' cache were synced. -func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { - informers := func() map[reflect.Type]cache.SharedIndexInformer { - f.lock.Lock() - defer f.lock.Unlock() - - informers := map[reflect.Type]cache.SharedIndexInformer{} - for informerType, informer := range f.informers { - if f.startedInformers[informerType] { - informers[informerType] = informer - } - } - return informers - }() - - res := map[reflect.Type]bool{} - for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) - } - return res -} - -// InternalInformerFor returns the SharedIndexInformer for obj using an internal -// client. -func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { - f.lock.Lock() - defer f.lock.Unlock() - - informerType := reflect.TypeOf(obj) - informer, exists := f.informers[informerType] - if exists { - return informer - } - - resyncPeriod, exists := f.customResync[informerType] - if !exists { - resyncPeriod = f.defaultResync - } - - informer = newFunc(f.client, resyncPeriod) - f.informers[informerType] = informer - - return informer -} - -// SharedInformerFactory provides shared informers for resources in all known -// API group versions. -type SharedInformerFactory interface { - internalinterfaces.SharedInformerFactory - ForResource(resource schema.GroupVersionResource) (GenericInformer, error) - WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool - - Admissionregistration() admissionregistration.Interface - Apps() apps.Interface - Auditregistration() auditregistration.Interface - Autoscaling() autoscaling.Interface - Batch() batch.Interface - Certificates() certificates.Interface - Coordination() coordination.Interface - Core() core.Interface - Extensions() extensions.Interface - Networking() networking.Interface - Policy() policy.Interface - Rbac() rbac.Interface - Scheduling() scheduling.Interface - Settings() settings.Interface - Storage() storage.Interface -} - -func (f *sharedInformerFactory) Admissionregistration() admissionregistration.Interface { - return admissionregistration.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Apps() apps.Interface { - return apps.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Auditregistration() auditregistration.Interface { - return auditregistration.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Autoscaling() autoscaling.Interface { - return autoscaling.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Batch() batch.Interface { - return batch.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Certificates() certificates.Interface { - return certificates.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Coordination() coordination.Interface { - return coordination.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Core() core.Interface { - return core.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Extensions() extensions.Interface { - return extensions.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Networking() networking.Interface { - return networking.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Policy() policy.Interface { - return policy.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Rbac() rbac.Interface { - return rbac.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Scheduling() scheduling.Interface { - return scheduling.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Settings() settings.Interface { - return settings.New(f, f.namespace, f.tweakListOptions) -} - -func (f *sharedInformerFactory) Storage() storage.Interface { - return storage.New(f, f.namespace, f.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/generic.go b/pkg/client/informers/informers_generated/internalversion/generic.go deleted file mode 100644 index 92a5c6d18af4e..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/generic.go +++ /dev/null @@ -1,186 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - "fmt" - - schema "k8s.io/apimachinery/pkg/runtime/schema" - cache "k8s.io/client-go/tools/cache" - admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration" - apps "k8s.io/kubernetes/pkg/apis/apps" - auditregistration "k8s.io/kubernetes/pkg/apis/auditregistration" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" - batch "k8s.io/kubernetes/pkg/apis/batch" - certificates "k8s.io/kubernetes/pkg/apis/certificates" - coordination "k8s.io/kubernetes/pkg/apis/coordination" - core "k8s.io/kubernetes/pkg/apis/core" - extensions "k8s.io/kubernetes/pkg/apis/extensions" - networking "k8s.io/kubernetes/pkg/apis/networking" - policy "k8s.io/kubernetes/pkg/apis/policy" - rbac "k8s.io/kubernetes/pkg/apis/rbac" - scheduling "k8s.io/kubernetes/pkg/apis/scheduling" - settings "k8s.io/kubernetes/pkg/apis/settings" - storage "k8s.io/kubernetes/pkg/apis/storage" -) - -// GenericInformer is type of SharedIndexInformer which will locate and delegate to other -// sharedInformers based on type -type GenericInformer interface { - Informer() cache.SharedIndexInformer - Lister() cache.GenericLister -} - -type genericInformer struct { - informer cache.SharedIndexInformer - resource schema.GroupResource -} - -// Informer returns the SharedIndexInformer. -func (f *genericInformer) Informer() cache.SharedIndexInformer { - return f.informer -} - -// Lister returns the GenericLister. -func (f *genericInformer) Lister() cache.GenericLister { - return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) -} - -// ForResource gives generic access to a shared informer of the matching type -// TODO extend this to unknown resources with a client pool -func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { - switch resource { - // Group=admissionregistration.k8s.io, Version=internalVersion - case admissionregistration.SchemeGroupVersion.WithResource("initializerconfigurations"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().InternalVersion().InitializerConfigurations().Informer()}, nil - case admissionregistration.SchemeGroupVersion.WithResource("mutatingwebhookconfigurations"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().InternalVersion().MutatingWebhookConfigurations().Informer()}, nil - case admissionregistration.SchemeGroupVersion.WithResource("validatingwebhookconfigurations"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().InternalVersion().ValidatingWebhookConfigurations().Informer()}, nil - - // Group=apps, Version=internalVersion - case apps.SchemeGroupVersion.WithResource("controllerrevisions"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().InternalVersion().ControllerRevisions().Informer()}, nil - case apps.SchemeGroupVersion.WithResource("statefulsets"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().InternalVersion().StatefulSets().Informer()}, nil - - // Group=auditregistration.k8s.io, Version=internalVersion - case auditregistration.SchemeGroupVersion.WithResource("auditsinks"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Auditregistration().InternalVersion().AuditSinks().Informer()}, nil - - // Group=autoscaling, Version=internalVersion - case autoscaling.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().InternalVersion().HorizontalPodAutoscalers().Informer()}, nil - - // Group=batch, Version=internalVersion - case batch.SchemeGroupVersion.WithResource("cronjobs"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Batch().InternalVersion().CronJobs().Informer()}, nil - case batch.SchemeGroupVersion.WithResource("jobs"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Batch().InternalVersion().Jobs().Informer()}, nil - - // Group=certificates.k8s.io, Version=internalVersion - case certificates.SchemeGroupVersion.WithResource("certificatesigningrequests"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().InternalVersion().CertificateSigningRequests().Informer()}, nil - - // Group=coordination.k8s.io, Version=internalVersion - case coordination.SchemeGroupVersion.WithResource("leases"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Coordination().InternalVersion().Leases().Informer()}, nil - - // Group=core, Version=internalVersion - case core.SchemeGroupVersion.WithResource("componentstatuses"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().ComponentStatuses().Informer()}, nil - case core.SchemeGroupVersion.WithResource("configmaps"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().ConfigMaps().Informer()}, nil - case core.SchemeGroupVersion.WithResource("endpoints"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().Endpoints().Informer()}, nil - case core.SchemeGroupVersion.WithResource("events"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().Events().Informer()}, nil - case core.SchemeGroupVersion.WithResource("limitranges"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().LimitRanges().Informer()}, nil - case core.SchemeGroupVersion.WithResource("namespaces"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().Namespaces().Informer()}, nil - case core.SchemeGroupVersion.WithResource("nodes"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().Nodes().Informer()}, nil - case core.SchemeGroupVersion.WithResource("persistentvolumes"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().PersistentVolumes().Informer()}, nil - case core.SchemeGroupVersion.WithResource("persistentvolumeclaims"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().PersistentVolumeClaims().Informer()}, nil - case core.SchemeGroupVersion.WithResource("pods"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().Pods().Informer()}, nil - case core.SchemeGroupVersion.WithResource("podtemplates"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().PodTemplates().Informer()}, nil - case core.SchemeGroupVersion.WithResource("replicationcontrollers"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().ReplicationControllers().Informer()}, nil - case core.SchemeGroupVersion.WithResource("resourcequotas"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().ResourceQuotas().Informer()}, nil - case core.SchemeGroupVersion.WithResource("secrets"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().Secrets().Informer()}, nil - case core.SchemeGroupVersion.WithResource("services"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().Services().Informer()}, nil - case core.SchemeGroupVersion.WithResource("serviceaccounts"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Core().InternalVersion().ServiceAccounts().Informer()}, nil - - // Group=extensions, Version=internalVersion - case extensions.SchemeGroupVersion.WithResource("daemonsets"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().InternalVersion().DaemonSets().Informer()}, nil - case extensions.SchemeGroupVersion.WithResource("deployments"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().InternalVersion().Deployments().Informer()}, nil - case extensions.SchemeGroupVersion.WithResource("ingresses"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().InternalVersion().Ingresses().Informer()}, nil - case extensions.SchemeGroupVersion.WithResource("replicasets"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().InternalVersion().ReplicaSets().Informer()}, nil - - // Group=networking.k8s.io, Version=internalVersion - case networking.SchemeGroupVersion.WithResource("networkpolicies"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().InternalVersion().NetworkPolicies().Informer()}, nil - - // Group=policy, Version=internalVersion - case policy.SchemeGroupVersion.WithResource("poddisruptionbudgets"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().InternalVersion().PodDisruptionBudgets().Informer()}, nil - case policy.SchemeGroupVersion.WithResource("podsecuritypolicies"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().InternalVersion().PodSecurityPolicies().Informer()}, nil - - // Group=rbac.authorization.k8s.io, Version=internalVersion - case rbac.SchemeGroupVersion.WithResource("clusterroles"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().InternalVersion().ClusterRoles().Informer()}, nil - case rbac.SchemeGroupVersion.WithResource("clusterrolebindings"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().InternalVersion().ClusterRoleBindings().Informer()}, nil - case rbac.SchemeGroupVersion.WithResource("roles"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().InternalVersion().Roles().Informer()}, nil - case rbac.SchemeGroupVersion.WithResource("rolebindings"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().InternalVersion().RoleBindings().Informer()}, nil - - // Group=scheduling.k8s.io, Version=internalVersion - case scheduling.SchemeGroupVersion.WithResource("priorityclasses"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().InternalVersion().PriorityClasses().Informer()}, nil - - // Group=settings.k8s.io, Version=internalVersion - case settings.SchemeGroupVersion.WithResource("podpresets"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Settings().InternalVersion().PodPresets().Informer()}, nil - - // Group=storage.k8s.io, Version=internalVersion - case storage.SchemeGroupVersion.WithResource("storageclasses"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().InternalVersion().StorageClasses().Informer()}, nil - case storage.SchemeGroupVersion.WithResource("volumeattachments"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().InternalVersion().VolumeAttachments().Informer()}, nil - - } - - return nil, fmt.Errorf("no informer found for %v", resource) -} diff --git a/pkg/client/informers/informers_generated/internalversion/internalinterfaces/BUILD b/pkg/client/informers/informers_generated/internalversion/internalinterfaces/BUILD deleted file mode 100644 index e9fd015388c2b..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/internalinterfaces/BUILD +++ /dev/null @@ -1,31 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["factory_interfaces.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces", - deps = [ - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/internalinterfaces/factory_interfaces.go b/pkg/client/informers/informers_generated/internalversion/internalinterfaces/factory_interfaces.go deleted file mode 100644 index 9c6981c89686c..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/internalinterfaces/factory_interfaces.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalinterfaces - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - cache "k8s.io/client-go/tools/cache" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" -) - -// NewInformerFunc takes internalclientset.Interface and time.Duration to return a SharedIndexInformer. -type NewInformerFunc func(internalclientset.Interface, time.Duration) cache.SharedIndexInformer - -// SharedInformerFactory a small interface to allow for adding an informer without an import cycle -type SharedInformerFactory interface { - Start(stopCh <-chan struct{}) - InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer -} - -// TweakListOptionsFunc is a function that transforms a v1.ListOptions. -type TweakListOptionsFunc func(*v1.ListOptions) diff --git a/pkg/client/informers/informers_generated/internalversion/networking/BUILD b/pkg/client/informers/informers_generated/internalversion/networking/BUILD deleted file mode 100644 index 20fb8535447ef..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/networking/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/networking", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/networking/internalversion:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/networking/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/networking/interface.go b/pkg/client/informers/informers_generated/internalversion/networking/interface.go deleted file mode 100644 index fe91bff98482a..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/networking/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package networking - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/networking/internalversion" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/networking/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/networking/internalversion/BUILD deleted file mode 100644 index 71b120233dcef..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/networking/internalversion/BUILD +++ /dev/null @@ -1,38 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "interface.go", - "networkpolicy.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/networking/internalversion", - deps = [ - "//pkg/apis/networking:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/networking/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/networking/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/networking/internalversion/interface.go deleted file mode 100644 index cc483b452000d..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/networking/internalversion/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // NetworkPolicies returns a NetworkPolicyInformer. - NetworkPolicies() NetworkPolicyInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// NetworkPolicies returns a NetworkPolicyInformer. -func (v *version) NetworkPolicies() NetworkPolicyInformer { - return &networkPolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/networking/internalversion/networkpolicy.go b/pkg/client/informers/informers_generated/internalversion/networking/internalversion/networkpolicy.go deleted file mode 100644 index 52628d6135a56..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/networking/internalversion/networkpolicy.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - networking "k8s.io/kubernetes/pkg/apis/networking" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/networking/internalversion" -) - -// NetworkPolicyInformer provides access to a shared informer and lister for -// NetworkPolicies. -type NetworkPolicyInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.NetworkPolicyLister -} - -type networkPolicyInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewNetworkPolicyInformer constructs a new informer for NetworkPolicy type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewNetworkPolicyInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNetworkPolicyInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredNetworkPolicyInformer constructs a new informer for NetworkPolicy type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredNetworkPolicyInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Networking().NetworkPolicies(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Networking().NetworkPolicies(namespace).Watch(options) - }, - }, - &networking.NetworkPolicy{}, - resyncPeriod, - indexers, - ) -} - -func (f *networkPolicyInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNetworkPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *networkPolicyInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&networking.NetworkPolicy{}, f.defaultInformer) -} - -func (f *networkPolicyInformer) Lister() internalversion.NetworkPolicyLister { - return internalversion.NewNetworkPolicyLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/policy/BUILD b/pkg/client/informers/informers_generated/internalversion/policy/BUILD deleted file mode 100644 index d7b4f7468b5f5..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/policy/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/policy", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/policy/internalversion:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/policy/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/policy/interface.go b/pkg/client/informers/informers_generated/internalversion/policy/interface.go deleted file mode 100644 index 0c9c08b965185..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/policy/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package policy - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/policy/internalversion" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/policy/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/policy/internalversion/BUILD deleted file mode 100644 index 946af4e1da328..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/policy/internalversion/BUILD +++ /dev/null @@ -1,39 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "interface.go", - "poddisruptionbudget.go", - "podsecuritypolicy.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/policy/internalversion", - deps = [ - "//pkg/apis/policy:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/policy/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/policy/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/policy/internalversion/interface.go deleted file mode 100644 index 9d76ddd328a94..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/policy/internalversion/interface.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // PodDisruptionBudgets returns a PodDisruptionBudgetInformer. - PodDisruptionBudgets() PodDisruptionBudgetInformer - // PodSecurityPolicies returns a PodSecurityPolicyInformer. - PodSecurityPolicies() PodSecurityPolicyInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// PodDisruptionBudgets returns a PodDisruptionBudgetInformer. -func (v *version) PodDisruptionBudgets() PodDisruptionBudgetInformer { - return &podDisruptionBudgetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// PodSecurityPolicies returns a PodSecurityPolicyInformer. -func (v *version) PodSecurityPolicies() PodSecurityPolicyInformer { - return &podSecurityPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/policy/internalversion/poddisruptionbudget.go b/pkg/client/informers/informers_generated/internalversion/policy/internalversion/poddisruptionbudget.go deleted file mode 100644 index 3ac3fa7f0d4b5..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/policy/internalversion/poddisruptionbudget.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - policy "k8s.io/kubernetes/pkg/apis/policy" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/policy/internalversion" -) - -// PodDisruptionBudgetInformer provides access to a shared informer and lister for -// PodDisruptionBudgets. -type PodDisruptionBudgetInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.PodDisruptionBudgetLister -} - -type podDisruptionBudgetInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewPodDisruptionBudgetInformer constructs a new informer for PodDisruptionBudget type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPodDisruptionBudgetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodDisruptionBudgetInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredPodDisruptionBudgetInformer constructs a new informer for PodDisruptionBudget type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPodDisruptionBudgetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Policy().PodDisruptionBudgets(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Policy().PodDisruptionBudgets(namespace).Watch(options) - }, - }, - &policy.PodDisruptionBudget{}, - resyncPeriod, - indexers, - ) -} - -func (f *podDisruptionBudgetInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodDisruptionBudgetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *podDisruptionBudgetInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&policy.PodDisruptionBudget{}, f.defaultInformer) -} - -func (f *podDisruptionBudgetInformer) Lister() internalversion.PodDisruptionBudgetLister { - return internalversion.NewPodDisruptionBudgetLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/policy/internalversion/podsecuritypolicy.go b/pkg/client/informers/informers_generated/internalversion/policy/internalversion/podsecuritypolicy.go deleted file mode 100644 index 2ef2d80321e73..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/policy/internalversion/podsecuritypolicy.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - policy "k8s.io/kubernetes/pkg/apis/policy" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/policy/internalversion" -) - -// PodSecurityPolicyInformer provides access to a shared informer and lister for -// PodSecurityPolicies. -type PodSecurityPolicyInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.PodSecurityPolicyLister -} - -type podSecurityPolicyInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewPodSecurityPolicyInformer constructs a new informer for PodSecurityPolicy type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPodSecurityPolicyInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodSecurityPolicyInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredPodSecurityPolicyInformer constructs a new informer for PodSecurityPolicy type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPodSecurityPolicyInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Policy().PodSecurityPolicies().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Policy().PodSecurityPolicies().Watch(options) - }, - }, - &policy.PodSecurityPolicy{}, - resyncPeriod, - indexers, - ) -} - -func (f *podSecurityPolicyInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodSecurityPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *podSecurityPolicyInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&policy.PodSecurityPolicy{}, f.defaultInformer) -} - -func (f *podSecurityPolicyInformer) Lister() internalversion.PodSecurityPolicyLister { - return internalversion.NewPodSecurityPolicyLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/rbac/BUILD b/pkg/client/informers/informers_generated/internalversion/rbac/BUILD deleted file mode 100644 index 4ee415c2803c9..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/rbac/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/rbac", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/rbac/internalversion:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/rbac/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/rbac/interface.go b/pkg/client/informers/informers_generated/internalversion/rbac/interface.go deleted file mode 100644 index f4c33811188f5..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/rbac/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package rbac - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/rbac/internalversion" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/BUILD deleted file mode 100644 index 8006d0a1a1dd5..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/BUILD +++ /dev/null @@ -1,41 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "clusterrole.go", - "clusterrolebinding.go", - "interface.go", - "role.go", - "rolebinding.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/rbac/internalversion", - deps = [ - "//pkg/apis/rbac:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/rbac/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/clusterrole.go b/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/clusterrole.go deleted file mode 100644 index 77667904778bd..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/clusterrole.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - rbac "k8s.io/kubernetes/pkg/apis/rbac" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/rbac/internalversion" -) - -// ClusterRoleInformer provides access to a shared informer and lister for -// ClusterRoles. -type ClusterRoleInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ClusterRoleLister -} - -type clusterRoleInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewClusterRoleInformer constructs a new informer for ClusterRole type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewClusterRoleInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterRoleInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredClusterRoleInformer constructs a new informer for ClusterRole type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredClusterRoleInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Rbac().ClusterRoles().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Rbac().ClusterRoles().Watch(options) - }, - }, - &rbac.ClusterRole{}, - resyncPeriod, - indexers, - ) -} - -func (f *clusterRoleInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *clusterRoleInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&rbac.ClusterRole{}, f.defaultInformer) -} - -func (f *clusterRoleInformer) Lister() internalversion.ClusterRoleLister { - return internalversion.NewClusterRoleLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/clusterrolebinding.go b/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/clusterrolebinding.go deleted file mode 100644 index 60dfa9d737190..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/clusterrolebinding.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - rbac "k8s.io/kubernetes/pkg/apis/rbac" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/rbac/internalversion" -) - -// ClusterRoleBindingInformer provides access to a shared informer and lister for -// ClusterRoleBindings. -type ClusterRoleBindingInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.ClusterRoleBindingLister -} - -type clusterRoleBindingInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewClusterRoleBindingInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredClusterRoleBindingInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Rbac().ClusterRoleBindings().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Rbac().ClusterRoleBindings().Watch(options) - }, - }, - &rbac.ClusterRoleBinding{}, - resyncPeriod, - indexers, - ) -} - -func (f *clusterRoleBindingInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *clusterRoleBindingInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&rbac.ClusterRoleBinding{}, f.defaultInformer) -} - -func (f *clusterRoleBindingInformer) Lister() internalversion.ClusterRoleBindingLister { - return internalversion.NewClusterRoleBindingLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/interface.go deleted file mode 100644 index 12bcb26c7a114..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/interface.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // ClusterRoles returns a ClusterRoleInformer. - ClusterRoles() ClusterRoleInformer - // ClusterRoleBindings returns a ClusterRoleBindingInformer. - ClusterRoleBindings() ClusterRoleBindingInformer - // Roles returns a RoleInformer. - Roles() RoleInformer - // RoleBindings returns a RoleBindingInformer. - RoleBindings() RoleBindingInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// ClusterRoles returns a ClusterRoleInformer. -func (v *version) ClusterRoles() ClusterRoleInformer { - return &clusterRoleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// ClusterRoleBindings returns a ClusterRoleBindingInformer. -func (v *version) ClusterRoleBindings() ClusterRoleBindingInformer { - return &clusterRoleBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// Roles returns a RoleInformer. -func (v *version) Roles() RoleInformer { - return &roleInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// RoleBindings returns a RoleBindingInformer. -func (v *version) RoleBindings() RoleBindingInformer { - return &roleBindingInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/role.go b/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/role.go deleted file mode 100644 index 712b26b25c692..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/role.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - rbac "k8s.io/kubernetes/pkg/apis/rbac" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/rbac/internalversion" -) - -// RoleInformer provides access to a shared informer and lister for -// Roles. -type RoleInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.RoleLister -} - -type roleInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewRoleInformer constructs a new informer for Role type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewRoleInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRoleInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredRoleInformer constructs a new informer for Role type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredRoleInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Rbac().Roles(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Rbac().Roles(namespace).Watch(options) - }, - }, - &rbac.Role{}, - resyncPeriod, - indexers, - ) -} - -func (f *roleInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRoleInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *roleInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&rbac.Role{}, f.defaultInformer) -} - -func (f *roleInformer) Lister() internalversion.RoleLister { - return internalversion.NewRoleLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/rolebinding.go b/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/rolebinding.go deleted file mode 100644 index ee4be7307c412..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/rbac/internalversion/rolebinding.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - rbac "k8s.io/kubernetes/pkg/apis/rbac" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/rbac/internalversion" -) - -// RoleBindingInformer provides access to a shared informer and lister for -// RoleBindings. -type RoleBindingInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.RoleBindingLister -} - -type roleBindingInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewRoleBindingInformer constructs a new informer for RoleBinding type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewRoleBindingInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRoleBindingInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredRoleBindingInformer constructs a new informer for RoleBinding type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredRoleBindingInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Rbac().RoleBindings(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Rbac().RoleBindings(namespace).Watch(options) - }, - }, - &rbac.RoleBinding{}, - resyncPeriod, - indexers, - ) -} - -func (f *roleBindingInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRoleBindingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *roleBindingInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&rbac.RoleBinding{}, f.defaultInformer) -} - -func (f *roleBindingInformer) Lister() internalversion.RoleBindingLister { - return internalversion.NewRoleBindingLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/scheduling/BUILD b/pkg/client/informers/informers_generated/internalversion/scheduling/BUILD deleted file mode 100644 index e7fd05be0fcd0..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/scheduling/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/scheduling", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/scheduling/internalversion:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/scheduling/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/scheduling/interface.go b/pkg/client/informers/informers_generated/internalversion/scheduling/interface.go deleted file mode 100644 index ee1cf8a8ea632..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/scheduling/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package scheduling - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/BUILD deleted file mode 100644 index f68075ae50b75..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/BUILD +++ /dev/null @@ -1,38 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "interface.go", - "priorityclass.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion", - deps = [ - "//pkg/apis/scheduling:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/scheduling/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/interface.go deleted file mode 100644 index eb0b548905fd9..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // PriorityClasses returns a PriorityClassInformer. - PriorityClasses() PriorityClassInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// PriorityClasses returns a PriorityClassInformer. -func (v *version) PriorityClasses() PriorityClassInformer { - return &priorityClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/priorityclass.go b/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/priorityclass.go deleted file mode 100644 index c01ad50f7e4ff..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/scheduling/internalversion/priorityclass.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - scheduling "k8s.io/kubernetes/pkg/apis/scheduling" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/scheduling/internalversion" -) - -// PriorityClassInformer provides access to a shared informer and lister for -// PriorityClasses. -type PriorityClassInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.PriorityClassLister -} - -type priorityClassInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewPriorityClassInformer constructs a new informer for PriorityClass type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPriorityClassInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPriorityClassInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredPriorityClassInformer constructs a new informer for PriorityClass type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPriorityClassInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Scheduling().PriorityClasses().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Scheduling().PriorityClasses().Watch(options) - }, - }, - &scheduling.PriorityClass{}, - resyncPeriod, - indexers, - ) -} - -func (f *priorityClassInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPriorityClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *priorityClassInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&scheduling.PriorityClass{}, f.defaultInformer) -} - -func (f *priorityClassInformer) Lister() internalversion.PriorityClassLister { - return internalversion.NewPriorityClassLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/settings/BUILD b/pkg/client/informers/informers_generated/internalversion/settings/BUILD deleted file mode 100644 index bae632755fd00..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/settings/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/settings", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/settings/internalversion:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/settings/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/settings/interface.go b/pkg/client/informers/informers_generated/internalversion/settings/interface.go deleted file mode 100644 index da1e47c4ec04a..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/settings/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package settings - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/settings/internalversion" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/settings/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/settings/internalversion/BUILD deleted file mode 100644 index 327959e1afb2b..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/settings/internalversion/BUILD +++ /dev/null @@ -1,38 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "interface.go", - "podpreset.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/settings/internalversion", - deps = [ - "//pkg/apis/settings:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/settings/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/settings/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/settings/internalversion/interface.go deleted file mode 100644 index aa899a8ca46c8..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/settings/internalversion/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // PodPresets returns a PodPresetInformer. - PodPresets() PodPresetInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// PodPresets returns a PodPresetInformer. -func (v *version) PodPresets() PodPresetInformer { - return &podPresetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/settings/internalversion/podpreset.go b/pkg/client/informers/informers_generated/internalversion/settings/internalversion/podpreset.go deleted file mode 100644 index 21e72d2853af4..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/settings/internalversion/podpreset.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - settings "k8s.io/kubernetes/pkg/apis/settings" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/settings/internalversion" -) - -// PodPresetInformer provides access to a shared informer and lister for -// PodPresets. -type PodPresetInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.PodPresetLister -} - -type podPresetInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewPodPresetInformer constructs a new informer for PodPreset type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPodPresetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodPresetInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredPodPresetInformer constructs a new informer for PodPreset type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPodPresetInformer(client internalclientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Settings().PodPresets(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Settings().PodPresets(namespace).Watch(options) - }, - }, - &settings.PodPreset{}, - resyncPeriod, - indexers, - ) -} - -func (f *podPresetInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodPresetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *podPresetInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&settings.PodPreset{}, f.defaultInformer) -} - -func (f *podPresetInformer) Lister() internalversion.PodPresetLister { - return internalversion.NewPodPresetLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/storage/BUILD b/pkg/client/informers/informers_generated/internalversion/storage/BUILD deleted file mode 100644 index b7af74c6a71f0..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/storage/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/storage", - deps = [ - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/storage/internalversion:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//pkg/client/informers/informers_generated/internalversion/storage/internalversion:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/pkg/client/informers/informers_generated/internalversion/storage/interface.go b/pkg/client/informers/informers_generated/internalversion/storage/interface.go deleted file mode 100644 index 781e411096376..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/storage/interface.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package storage - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/storage/internalversion" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // InternalVersion provides access to shared informers for resources in InternalVersion. - InternalVersion() internalversion.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// InternalVersion returns a new internalversion.Interface. -func (g *group) InternalVersion() internalversion.Interface { - return internalversion.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/informers_generated/internalversion/storage/internalversion/BUILD b/pkg/client/informers/informers_generated/internalversion/storage/internalversion/BUILD deleted file mode 100644 index b49afe63ae10a..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/storage/internalversion/BUILD +++ /dev/null @@ -1,39 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "interface.go", - "storageclass.go", - "volumeattachment.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/storage/internalversion", - deps = [ - "//pkg/apis/storage:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion/internalinterfaces:go_default_library", - "//pkg/client/listers/storage/internalversion:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/informers/informers_generated/internalversion/storage/internalversion/interface.go b/pkg/client/informers/informers_generated/internalversion/storage/internalversion/interface.go deleted file mode 100644 index 4ba68c40774d8..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/storage/internalversion/interface.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // StorageClasses returns a StorageClassInformer. - StorageClasses() StorageClassInformer - // VolumeAttachments returns a VolumeAttachmentInformer. - VolumeAttachments() VolumeAttachmentInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// StorageClasses returns a StorageClassInformer. -func (v *version) StorageClasses() StorageClassInformer { - return &storageClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - -// VolumeAttachments returns a VolumeAttachmentInformer. -func (v *version) VolumeAttachments() VolumeAttachmentInformer { - return &volumeAttachmentInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/informers_generated/internalversion/storage/internalversion/storageclass.go b/pkg/client/informers/informers_generated/internalversion/storage/internalversion/storageclass.go deleted file mode 100644 index a6c635aa92505..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/storage/internalversion/storageclass.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - storage "k8s.io/kubernetes/pkg/apis/storage" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/storage/internalversion" -) - -// StorageClassInformer provides access to a shared informer and lister for -// StorageClasses. -type StorageClassInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.StorageClassLister -} - -type storageClassInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewStorageClassInformer constructs a new informer for StorageClass type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewStorageClassInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStorageClassInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredStorageClassInformer constructs a new informer for StorageClass type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredStorageClassInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Storage().StorageClasses().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Storage().StorageClasses().Watch(options) - }, - }, - &storage.StorageClass{}, - resyncPeriod, - indexers, - ) -} - -func (f *storageClassInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStorageClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *storageClassInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&storage.StorageClass{}, f.defaultInformer) -} - -func (f *storageClassInformer) Lister() internalversion.StorageClassLister { - return internalversion.NewStorageClassLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/informers_generated/internalversion/storage/internalversion/volumeattachment.go b/pkg/client/informers/informers_generated/internalversion/storage/internalversion/volumeattachment.go deleted file mode 100644 index 965f87b85bfa0..0000000000000 --- a/pkg/client/informers/informers_generated/internalversion/storage/internalversion/volumeattachment.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package internalversion - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - storage "k8s.io/kubernetes/pkg/apis/storage" - internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinterfaces "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/internalinterfaces" - internalversion "k8s.io/kubernetes/pkg/client/listers/storage/internalversion" -) - -// VolumeAttachmentInformer provides access to a shared informer and lister for -// VolumeAttachments. -type VolumeAttachmentInformer interface { - Informer() cache.SharedIndexInformer - Lister() internalversion.VolumeAttachmentLister -} - -type volumeAttachmentInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewVolumeAttachmentInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredVolumeAttachmentInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Storage().VolumeAttachments().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.Storage().VolumeAttachments().Watch(options) - }, - }, - &storage.VolumeAttachment{}, - resyncPeriod, - indexers, - ) -} - -func (f *volumeAttachmentInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *volumeAttachmentInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&storage.VolumeAttachment{}, f.defaultInformer) -} - -func (f *volumeAttachmentInformer) Lister() internalversion.VolumeAttachmentLister { - return internalversion.NewVolumeAttachmentLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/listers/admissionregistration/internalversion/BUILD b/pkg/client/listers/admissionregistration/internalversion/BUILD deleted file mode 100644 index 67c5b08783000..0000000000000 --- a/pkg/client/listers/admissionregistration/internalversion/BUILD +++ /dev/null @@ -1,36 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "initializerconfiguration.go", - "mutatingwebhookconfiguration.go", - "validatingwebhookconfiguration.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/admissionregistration/internalversion", - deps = [ - "//pkg/apis/admissionregistration:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/admissionregistration/internalversion/expansion_generated.go b/pkg/client/listers/admissionregistration/internalversion/expansion_generated.go deleted file mode 100644 index 125c1a9ff1294..0000000000000 --- a/pkg/client/listers/admissionregistration/internalversion/expansion_generated.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// InitializerConfigurationListerExpansion allows custom methods to be added to -// InitializerConfigurationLister. -type InitializerConfigurationListerExpansion interface{} - -// MutatingWebhookConfigurationListerExpansion allows custom methods to be added to -// MutatingWebhookConfigurationLister. -type MutatingWebhookConfigurationListerExpansion interface{} - -// ValidatingWebhookConfigurationListerExpansion allows custom methods to be added to -// ValidatingWebhookConfigurationLister. -type ValidatingWebhookConfigurationListerExpansion interface{} diff --git a/pkg/client/listers/admissionregistration/internalversion/initializerconfiguration.go b/pkg/client/listers/admissionregistration/internalversion/initializerconfiguration.go deleted file mode 100644 index 8563e203d5756..0000000000000 --- a/pkg/client/listers/admissionregistration/internalversion/initializerconfiguration.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration" -) - -// InitializerConfigurationLister helps list InitializerConfigurations. -type InitializerConfigurationLister interface { - // List lists all InitializerConfigurations in the indexer. - List(selector labels.Selector) (ret []*admissionregistration.InitializerConfiguration, err error) - // Get retrieves the InitializerConfiguration from the index for a given name. - Get(name string) (*admissionregistration.InitializerConfiguration, error) - InitializerConfigurationListerExpansion -} - -// initializerConfigurationLister implements the InitializerConfigurationLister interface. -type initializerConfigurationLister struct { - indexer cache.Indexer -} - -// NewInitializerConfigurationLister returns a new InitializerConfigurationLister. -func NewInitializerConfigurationLister(indexer cache.Indexer) InitializerConfigurationLister { - return &initializerConfigurationLister{indexer: indexer} -} - -// List lists all InitializerConfigurations in the indexer. -func (s *initializerConfigurationLister) List(selector labels.Selector) (ret []*admissionregistration.InitializerConfiguration, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*admissionregistration.InitializerConfiguration)) - }) - return ret, err -} - -// Get retrieves the InitializerConfiguration from the index for a given name. -func (s *initializerConfigurationLister) Get(name string) (*admissionregistration.InitializerConfiguration, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(admissionregistration.Resource("initializerconfiguration"), name) - } - return obj.(*admissionregistration.InitializerConfiguration), nil -} diff --git a/pkg/client/listers/admissionregistration/internalversion/mutatingwebhookconfiguration.go b/pkg/client/listers/admissionregistration/internalversion/mutatingwebhookconfiguration.go deleted file mode 100644 index bb8d590db9afe..0000000000000 --- a/pkg/client/listers/admissionregistration/internalversion/mutatingwebhookconfiguration.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration" -) - -// MutatingWebhookConfigurationLister helps list MutatingWebhookConfigurations. -type MutatingWebhookConfigurationLister interface { - // List lists all MutatingWebhookConfigurations in the indexer. - List(selector labels.Selector) (ret []*admissionregistration.MutatingWebhookConfiguration, err error) - // Get retrieves the MutatingWebhookConfiguration from the index for a given name. - Get(name string) (*admissionregistration.MutatingWebhookConfiguration, error) - MutatingWebhookConfigurationListerExpansion -} - -// mutatingWebhookConfigurationLister implements the MutatingWebhookConfigurationLister interface. -type mutatingWebhookConfigurationLister struct { - indexer cache.Indexer -} - -// NewMutatingWebhookConfigurationLister returns a new MutatingWebhookConfigurationLister. -func NewMutatingWebhookConfigurationLister(indexer cache.Indexer) MutatingWebhookConfigurationLister { - return &mutatingWebhookConfigurationLister{indexer: indexer} -} - -// List lists all MutatingWebhookConfigurations in the indexer. -func (s *mutatingWebhookConfigurationLister) List(selector labels.Selector) (ret []*admissionregistration.MutatingWebhookConfiguration, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*admissionregistration.MutatingWebhookConfiguration)) - }) - return ret, err -} - -// Get retrieves the MutatingWebhookConfiguration from the index for a given name. -func (s *mutatingWebhookConfigurationLister) Get(name string) (*admissionregistration.MutatingWebhookConfiguration, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(admissionregistration.Resource("mutatingwebhookconfiguration"), name) - } - return obj.(*admissionregistration.MutatingWebhookConfiguration), nil -} diff --git a/pkg/client/listers/admissionregistration/internalversion/validatingwebhookconfiguration.go b/pkg/client/listers/admissionregistration/internalversion/validatingwebhookconfiguration.go deleted file mode 100644 index 12f38aba4a119..0000000000000 --- a/pkg/client/listers/admissionregistration/internalversion/validatingwebhookconfiguration.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration" -) - -// ValidatingWebhookConfigurationLister helps list ValidatingWebhookConfigurations. -type ValidatingWebhookConfigurationLister interface { - // List lists all ValidatingWebhookConfigurations in the indexer. - List(selector labels.Selector) (ret []*admissionregistration.ValidatingWebhookConfiguration, err error) - // Get retrieves the ValidatingWebhookConfiguration from the index for a given name. - Get(name string) (*admissionregistration.ValidatingWebhookConfiguration, error) - ValidatingWebhookConfigurationListerExpansion -} - -// validatingWebhookConfigurationLister implements the ValidatingWebhookConfigurationLister interface. -type validatingWebhookConfigurationLister struct { - indexer cache.Indexer -} - -// NewValidatingWebhookConfigurationLister returns a new ValidatingWebhookConfigurationLister. -func NewValidatingWebhookConfigurationLister(indexer cache.Indexer) ValidatingWebhookConfigurationLister { - return &validatingWebhookConfigurationLister{indexer: indexer} -} - -// List lists all ValidatingWebhookConfigurations in the indexer. -func (s *validatingWebhookConfigurationLister) List(selector labels.Selector) (ret []*admissionregistration.ValidatingWebhookConfiguration, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*admissionregistration.ValidatingWebhookConfiguration)) - }) - return ret, err -} - -// Get retrieves the ValidatingWebhookConfiguration from the index for a given name. -func (s *validatingWebhookConfigurationLister) Get(name string) (*admissionregistration.ValidatingWebhookConfiguration, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(admissionregistration.Resource("validatingwebhookconfiguration"), name) - } - return obj.(*admissionregistration.ValidatingWebhookConfiguration), nil -} diff --git a/pkg/client/listers/apps/internalversion/BUILD b/pkg/client/listers/apps/internalversion/BUILD deleted file mode 100644 index 9ee7b39aad880..0000000000000 --- a/pkg/client/listers/apps/internalversion/BUILD +++ /dev/null @@ -1,38 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "controllerrevision.go", - "expansion_generated.go", - "statefulset.go", - "statefulset_expansion.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/apps/internalversion", - deps = [ - "//pkg/apis/apps:go_default_library", - "//pkg/apis/core: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/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/apps/internalversion/controllerrevision.go b/pkg/client/listers/apps/internalversion/controllerrevision.go deleted file mode 100644 index 0814c4f11017c..0000000000000 --- a/pkg/client/listers/apps/internalversion/controllerrevision.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - apps "k8s.io/kubernetes/pkg/apis/apps" -) - -// ControllerRevisionLister helps list ControllerRevisions. -type ControllerRevisionLister interface { - // List lists all ControllerRevisions in the indexer. - List(selector labels.Selector) (ret []*apps.ControllerRevision, err error) - // ControllerRevisions returns an object that can list and get ControllerRevisions. - ControllerRevisions(namespace string) ControllerRevisionNamespaceLister - ControllerRevisionListerExpansion -} - -// controllerRevisionLister implements the ControllerRevisionLister interface. -type controllerRevisionLister struct { - indexer cache.Indexer -} - -// NewControllerRevisionLister returns a new ControllerRevisionLister. -func NewControllerRevisionLister(indexer cache.Indexer) ControllerRevisionLister { - return &controllerRevisionLister{indexer: indexer} -} - -// List lists all ControllerRevisions in the indexer. -func (s *controllerRevisionLister) List(selector labels.Selector) (ret []*apps.ControllerRevision, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*apps.ControllerRevision)) - }) - return ret, err -} - -// ControllerRevisions returns an object that can list and get ControllerRevisions. -func (s *controllerRevisionLister) ControllerRevisions(namespace string) ControllerRevisionNamespaceLister { - return controllerRevisionNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ControllerRevisionNamespaceLister helps list and get ControllerRevisions. -type ControllerRevisionNamespaceLister interface { - // List lists all ControllerRevisions in the indexer for a given namespace. - List(selector labels.Selector) (ret []*apps.ControllerRevision, err error) - // Get retrieves the ControllerRevision from the indexer for a given namespace and name. - Get(name string) (*apps.ControllerRevision, error) - ControllerRevisionNamespaceListerExpansion -} - -// controllerRevisionNamespaceLister implements the ControllerRevisionNamespaceLister -// interface. -type controllerRevisionNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all ControllerRevisions in the indexer for a given namespace. -func (s controllerRevisionNamespaceLister) List(selector labels.Selector) (ret []*apps.ControllerRevision, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*apps.ControllerRevision)) - }) - return ret, err -} - -// Get retrieves the ControllerRevision from the indexer for a given namespace and name. -func (s controllerRevisionNamespaceLister) Get(name string) (*apps.ControllerRevision, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(apps.Resource("controllerrevision"), name) - } - return obj.(*apps.ControllerRevision), nil -} diff --git a/pkg/client/listers/apps/internalversion/expansion_generated.go b/pkg/client/listers/apps/internalversion/expansion_generated.go deleted file mode 100644 index 7278af3da72a6..0000000000000 --- a/pkg/client/listers/apps/internalversion/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// ControllerRevisionListerExpansion allows custom methods to be added to -// ControllerRevisionLister. -type ControllerRevisionListerExpansion interface{} - -// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to -// ControllerRevisionNamespaceLister. -type ControllerRevisionNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/apps/internalversion/statefulset.go b/pkg/client/listers/apps/internalversion/statefulset.go deleted file mode 100644 index 4accadc1e4878..0000000000000 --- a/pkg/client/listers/apps/internalversion/statefulset.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - apps "k8s.io/kubernetes/pkg/apis/apps" -) - -// StatefulSetLister helps list StatefulSets. -type StatefulSetLister interface { - // List lists all StatefulSets in the indexer. - List(selector labels.Selector) (ret []*apps.StatefulSet, err error) - // StatefulSets returns an object that can list and get StatefulSets. - StatefulSets(namespace string) StatefulSetNamespaceLister - StatefulSetListerExpansion -} - -// statefulSetLister implements the StatefulSetLister interface. -type statefulSetLister struct { - indexer cache.Indexer -} - -// NewStatefulSetLister returns a new StatefulSetLister. -func NewStatefulSetLister(indexer cache.Indexer) StatefulSetLister { - return &statefulSetLister{indexer: indexer} -} - -// List lists all StatefulSets in the indexer. -func (s *statefulSetLister) List(selector labels.Selector) (ret []*apps.StatefulSet, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*apps.StatefulSet)) - }) - return ret, err -} - -// StatefulSets returns an object that can list and get StatefulSets. -func (s *statefulSetLister) StatefulSets(namespace string) StatefulSetNamespaceLister { - return statefulSetNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// StatefulSetNamespaceLister helps list and get StatefulSets. -type StatefulSetNamespaceLister interface { - // List lists all StatefulSets in the indexer for a given namespace. - List(selector labels.Selector) (ret []*apps.StatefulSet, err error) - // Get retrieves the StatefulSet from the indexer for a given namespace and name. - Get(name string) (*apps.StatefulSet, error) - StatefulSetNamespaceListerExpansion -} - -// statefulSetNamespaceLister implements the StatefulSetNamespaceLister -// interface. -type statefulSetNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all StatefulSets in the indexer for a given namespace. -func (s statefulSetNamespaceLister) List(selector labels.Selector) (ret []*apps.StatefulSet, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*apps.StatefulSet)) - }) - return ret, err -} - -// Get retrieves the StatefulSet from the indexer for a given namespace and name. -func (s statefulSetNamespaceLister) Get(name string) (*apps.StatefulSet, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(apps.Resource("statefulset"), name) - } - return obj.(*apps.StatefulSet), nil -} diff --git a/pkg/client/listers/apps/internalversion/statefulset_expansion.go b/pkg/client/listers/apps/internalversion/statefulset_expansion.go deleted file mode 100644 index 8798f7249bc90..0000000000000 --- a/pkg/client/listers/apps/internalversion/statefulset_expansion.go +++ /dev/null @@ -1,75 +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 internalversion - -import ( - "fmt" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/kubernetes/pkg/apis/apps" - api "k8s.io/kubernetes/pkg/apis/core" -) - -// StatefulSetListerExpansion allows custom methods to be added to -// StatefulSetLister. -type StatefulSetListerExpansion interface { - GetPodStatefulSets(pod *api.Pod) ([]*apps.StatefulSet, error) -} - -// StatefulSetNamespaceListerExpansion allows custom methods to be added to -// StatefulSetNamespaceLister. -type StatefulSetNamespaceListerExpansion interface{} - -// GetPodStatefulSets returns a list of StatefulSets that potentially match a pod. -// Only the one specified in the Pod's ControllerRef will actually manage it. -// Returns an error only if no matching StatefulSets are found. -func (s *statefulSetLister) GetPodStatefulSets(pod *api.Pod) ([]*apps.StatefulSet, error) { - var selector labels.Selector - - if len(pod.Labels) == 0 { - return nil, fmt.Errorf("no StatefulSets found for pod %v because it has no labels", pod.Name) - } - - list, err := s.StatefulSets(pod.Namespace).List(labels.Everything()) - if err != nil { - return nil, err - } - - var psList []*apps.StatefulSet - for _, ps := range list { - if ps.Namespace != pod.Namespace { - continue - } - selector, err = metav1.LabelSelectorAsSelector(ps.Spec.Selector) - if err != nil { - return nil, fmt.Errorf("invalid selector: %v", err) - } - - // If a StatefulSet with a nil or empty selector creeps in, it should match nothing, not everything. - if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { - continue - } - psList = append(psList, ps) - } - - if len(psList) == 0 { - return nil, fmt.Errorf("could not find StatefulSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) - } - - return psList, nil -} diff --git a/pkg/client/listers/auditregistration/internalversion/BUILD b/pkg/client/listers/auditregistration/internalversion/BUILD deleted file mode 100644 index 2c4c3481acd42..0000000000000 --- a/pkg/client/listers/auditregistration/internalversion/BUILD +++ /dev/null @@ -1,31 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "auditsink.go", - "expansion_generated.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/auditregistration/internalversion", - visibility = ["//visibility:public"], - deps = [ - "//pkg/apis/auditregistration:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/auditregistration/internalversion/auditsink.go b/pkg/client/listers/auditregistration/internalversion/auditsink.go deleted file mode 100644 index f42c39da31699..0000000000000 --- a/pkg/client/listers/auditregistration/internalversion/auditsink.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - auditregistration "k8s.io/kubernetes/pkg/apis/auditregistration" -) - -// AuditSinkLister helps list AuditSinks. -type AuditSinkLister interface { - // List lists all AuditSinks in the indexer. - List(selector labels.Selector) (ret []*auditregistration.AuditSink, err error) - // Get retrieves the AuditSink from the index for a given name. - Get(name string) (*auditregistration.AuditSink, error) - AuditSinkListerExpansion -} - -// auditSinkLister implements the AuditSinkLister interface. -type auditSinkLister struct { - indexer cache.Indexer -} - -// NewAuditSinkLister returns a new AuditSinkLister. -func NewAuditSinkLister(indexer cache.Indexer) AuditSinkLister { - return &auditSinkLister{indexer: indexer} -} - -// List lists all AuditSinks in the indexer. -func (s *auditSinkLister) List(selector labels.Selector) (ret []*auditregistration.AuditSink, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*auditregistration.AuditSink)) - }) - return ret, err -} - -// Get retrieves the AuditSink from the index for a given name. -func (s *auditSinkLister) Get(name string) (*auditregistration.AuditSink, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(auditregistration.Resource("auditsink"), name) - } - return obj.(*auditregistration.AuditSink), nil -} diff --git a/pkg/client/listers/auditregistration/internalversion/expansion_generated.go b/pkg/client/listers/auditregistration/internalversion/expansion_generated.go deleted file mode 100644 index 2b38d67733f83..0000000000000 --- a/pkg/client/listers/auditregistration/internalversion/expansion_generated.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// AuditSinkListerExpansion allows custom methods to be added to -// AuditSinkLister. -type AuditSinkListerExpansion interface{} diff --git a/pkg/client/listers/authentication/internalversion/BUILD b/pkg/client/listers/authentication/internalversion/BUILD deleted file mode 100644 index 00d89396f7716..0000000000000 --- a/pkg/client/listers/authentication/internalversion/BUILD +++ /dev/null @@ -1,34 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "tokenreview.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/authentication/internalversion", - deps = [ - "//pkg/apis/authentication:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/authentication/internalversion/expansion_generated.go b/pkg/client/listers/authentication/internalversion/expansion_generated.go deleted file mode 100644 index 7bb8df82b931b..0000000000000 --- a/pkg/client/listers/authentication/internalversion/expansion_generated.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// TokenReviewListerExpansion allows custom methods to be added to -// TokenReviewLister. -type TokenReviewListerExpansion interface{} diff --git a/pkg/client/listers/authentication/internalversion/tokenreview.go b/pkg/client/listers/authentication/internalversion/tokenreview.go deleted file mode 100644 index c516414296a62..0000000000000 --- a/pkg/client/listers/authentication/internalversion/tokenreview.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - authentication "k8s.io/kubernetes/pkg/apis/authentication" -) - -// TokenReviewLister helps list TokenReviews. -type TokenReviewLister interface { - // List lists all TokenReviews in the indexer. - List(selector labels.Selector) (ret []*authentication.TokenReview, err error) - // Get retrieves the TokenReview from the index for a given name. - Get(name string) (*authentication.TokenReview, error) - TokenReviewListerExpansion -} - -// tokenReviewLister implements the TokenReviewLister interface. -type tokenReviewLister struct { - indexer cache.Indexer -} - -// NewTokenReviewLister returns a new TokenReviewLister. -func NewTokenReviewLister(indexer cache.Indexer) TokenReviewLister { - return &tokenReviewLister{indexer: indexer} -} - -// List lists all TokenReviews in the indexer. -func (s *tokenReviewLister) List(selector labels.Selector) (ret []*authentication.TokenReview, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*authentication.TokenReview)) - }) - return ret, err -} - -// Get retrieves the TokenReview from the index for a given name. -func (s *tokenReviewLister) Get(name string) (*authentication.TokenReview, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(authentication.Resource("tokenreview"), name) - } - return obj.(*authentication.TokenReview), nil -} diff --git a/pkg/client/listers/authorization/internalversion/BUILD b/pkg/client/listers/authorization/internalversion/BUILD deleted file mode 100644 index 05caa1b8c17a6..0000000000000 --- a/pkg/client/listers/authorization/internalversion/BUILD +++ /dev/null @@ -1,37 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "localsubjectaccessreview.go", - "selfsubjectaccessreview.go", - "selfsubjectrulesreview.go", - "subjectaccessreview.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/authorization/internalversion", - deps = [ - "//pkg/apis/authorization:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/authorization/internalversion/expansion_generated.go b/pkg/client/listers/authorization/internalversion/expansion_generated.go deleted file mode 100644 index 8f43988626e33..0000000000000 --- a/pkg/client/listers/authorization/internalversion/expansion_generated.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// LocalSubjectAccessReviewListerExpansion allows custom methods to be added to -// LocalSubjectAccessReviewLister. -type LocalSubjectAccessReviewListerExpansion interface{} - -// LocalSubjectAccessReviewNamespaceListerExpansion allows custom methods to be added to -// LocalSubjectAccessReviewNamespaceLister. -type LocalSubjectAccessReviewNamespaceListerExpansion interface{} - -// SelfSubjectAccessReviewListerExpansion allows custom methods to be added to -// SelfSubjectAccessReviewLister. -type SelfSubjectAccessReviewListerExpansion interface{} - -// SelfSubjectRulesReviewListerExpansion allows custom methods to be added to -// SelfSubjectRulesReviewLister. -type SelfSubjectRulesReviewListerExpansion interface{} - -// SubjectAccessReviewListerExpansion allows custom methods to be added to -// SubjectAccessReviewLister. -type SubjectAccessReviewListerExpansion interface{} diff --git a/pkg/client/listers/authorization/internalversion/localsubjectaccessreview.go b/pkg/client/listers/authorization/internalversion/localsubjectaccessreview.go deleted file mode 100644 index cecd1a8954776..0000000000000 --- a/pkg/client/listers/authorization/internalversion/localsubjectaccessreview.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - authorization "k8s.io/kubernetes/pkg/apis/authorization" -) - -// LocalSubjectAccessReviewLister helps list LocalSubjectAccessReviews. -type LocalSubjectAccessReviewLister interface { - // List lists all LocalSubjectAccessReviews in the indexer. - List(selector labels.Selector) (ret []*authorization.LocalSubjectAccessReview, err error) - // LocalSubjectAccessReviews returns an object that can list and get LocalSubjectAccessReviews. - LocalSubjectAccessReviews(namespace string) LocalSubjectAccessReviewNamespaceLister - LocalSubjectAccessReviewListerExpansion -} - -// localSubjectAccessReviewLister implements the LocalSubjectAccessReviewLister interface. -type localSubjectAccessReviewLister struct { - indexer cache.Indexer -} - -// NewLocalSubjectAccessReviewLister returns a new LocalSubjectAccessReviewLister. -func NewLocalSubjectAccessReviewLister(indexer cache.Indexer) LocalSubjectAccessReviewLister { - return &localSubjectAccessReviewLister{indexer: indexer} -} - -// List lists all LocalSubjectAccessReviews in the indexer. -func (s *localSubjectAccessReviewLister) List(selector labels.Selector) (ret []*authorization.LocalSubjectAccessReview, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*authorization.LocalSubjectAccessReview)) - }) - return ret, err -} - -// LocalSubjectAccessReviews returns an object that can list and get LocalSubjectAccessReviews. -func (s *localSubjectAccessReviewLister) LocalSubjectAccessReviews(namespace string) LocalSubjectAccessReviewNamespaceLister { - return localSubjectAccessReviewNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// LocalSubjectAccessReviewNamespaceLister helps list and get LocalSubjectAccessReviews. -type LocalSubjectAccessReviewNamespaceLister interface { - // List lists all LocalSubjectAccessReviews in the indexer for a given namespace. - List(selector labels.Selector) (ret []*authorization.LocalSubjectAccessReview, err error) - // Get retrieves the LocalSubjectAccessReview from the indexer for a given namespace and name. - Get(name string) (*authorization.LocalSubjectAccessReview, error) - LocalSubjectAccessReviewNamespaceListerExpansion -} - -// localSubjectAccessReviewNamespaceLister implements the LocalSubjectAccessReviewNamespaceLister -// interface. -type localSubjectAccessReviewNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all LocalSubjectAccessReviews in the indexer for a given namespace. -func (s localSubjectAccessReviewNamespaceLister) List(selector labels.Selector) (ret []*authorization.LocalSubjectAccessReview, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*authorization.LocalSubjectAccessReview)) - }) - return ret, err -} - -// Get retrieves the LocalSubjectAccessReview from the indexer for a given namespace and name. -func (s localSubjectAccessReviewNamespaceLister) Get(name string) (*authorization.LocalSubjectAccessReview, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(authorization.Resource("localsubjectaccessreview"), name) - } - return obj.(*authorization.LocalSubjectAccessReview), nil -} diff --git a/pkg/client/listers/authorization/internalversion/selfsubjectaccessreview.go b/pkg/client/listers/authorization/internalversion/selfsubjectaccessreview.go deleted file mode 100644 index d1ce35880d835..0000000000000 --- a/pkg/client/listers/authorization/internalversion/selfsubjectaccessreview.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - authorization "k8s.io/kubernetes/pkg/apis/authorization" -) - -// SelfSubjectAccessReviewLister helps list SelfSubjectAccessReviews. -type SelfSubjectAccessReviewLister interface { - // List lists all SelfSubjectAccessReviews in the indexer. - List(selector labels.Selector) (ret []*authorization.SelfSubjectAccessReview, err error) - // Get retrieves the SelfSubjectAccessReview from the index for a given name. - Get(name string) (*authorization.SelfSubjectAccessReview, error) - SelfSubjectAccessReviewListerExpansion -} - -// selfSubjectAccessReviewLister implements the SelfSubjectAccessReviewLister interface. -type selfSubjectAccessReviewLister struct { - indexer cache.Indexer -} - -// NewSelfSubjectAccessReviewLister returns a new SelfSubjectAccessReviewLister. -func NewSelfSubjectAccessReviewLister(indexer cache.Indexer) SelfSubjectAccessReviewLister { - return &selfSubjectAccessReviewLister{indexer: indexer} -} - -// List lists all SelfSubjectAccessReviews in the indexer. -func (s *selfSubjectAccessReviewLister) List(selector labels.Selector) (ret []*authorization.SelfSubjectAccessReview, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*authorization.SelfSubjectAccessReview)) - }) - return ret, err -} - -// Get retrieves the SelfSubjectAccessReview from the index for a given name. -func (s *selfSubjectAccessReviewLister) Get(name string) (*authorization.SelfSubjectAccessReview, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(authorization.Resource("selfsubjectaccessreview"), name) - } - return obj.(*authorization.SelfSubjectAccessReview), nil -} diff --git a/pkg/client/listers/authorization/internalversion/selfsubjectrulesreview.go b/pkg/client/listers/authorization/internalversion/selfsubjectrulesreview.go deleted file mode 100644 index b70603e6caf8d..0000000000000 --- a/pkg/client/listers/authorization/internalversion/selfsubjectrulesreview.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - authorization "k8s.io/kubernetes/pkg/apis/authorization" -) - -// SelfSubjectRulesReviewLister helps list SelfSubjectRulesReviews. -type SelfSubjectRulesReviewLister interface { - // List lists all SelfSubjectRulesReviews in the indexer. - List(selector labels.Selector) (ret []*authorization.SelfSubjectRulesReview, err error) - // Get retrieves the SelfSubjectRulesReview from the index for a given name. - Get(name string) (*authorization.SelfSubjectRulesReview, error) - SelfSubjectRulesReviewListerExpansion -} - -// selfSubjectRulesReviewLister implements the SelfSubjectRulesReviewLister interface. -type selfSubjectRulesReviewLister struct { - indexer cache.Indexer -} - -// NewSelfSubjectRulesReviewLister returns a new SelfSubjectRulesReviewLister. -func NewSelfSubjectRulesReviewLister(indexer cache.Indexer) SelfSubjectRulesReviewLister { - return &selfSubjectRulesReviewLister{indexer: indexer} -} - -// List lists all SelfSubjectRulesReviews in the indexer. -func (s *selfSubjectRulesReviewLister) List(selector labels.Selector) (ret []*authorization.SelfSubjectRulesReview, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*authorization.SelfSubjectRulesReview)) - }) - return ret, err -} - -// Get retrieves the SelfSubjectRulesReview from the index for a given name. -func (s *selfSubjectRulesReviewLister) Get(name string) (*authorization.SelfSubjectRulesReview, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(authorization.Resource("selfsubjectrulesreview"), name) - } - return obj.(*authorization.SelfSubjectRulesReview), nil -} diff --git a/pkg/client/listers/authorization/internalversion/subjectaccessreview.go b/pkg/client/listers/authorization/internalversion/subjectaccessreview.go deleted file mode 100644 index ba9dc8fdaf2f4..0000000000000 --- a/pkg/client/listers/authorization/internalversion/subjectaccessreview.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - authorization "k8s.io/kubernetes/pkg/apis/authorization" -) - -// SubjectAccessReviewLister helps list SubjectAccessReviews. -type SubjectAccessReviewLister interface { - // List lists all SubjectAccessReviews in the indexer. - List(selector labels.Selector) (ret []*authorization.SubjectAccessReview, err error) - // Get retrieves the SubjectAccessReview from the index for a given name. - Get(name string) (*authorization.SubjectAccessReview, error) - SubjectAccessReviewListerExpansion -} - -// subjectAccessReviewLister implements the SubjectAccessReviewLister interface. -type subjectAccessReviewLister struct { - indexer cache.Indexer -} - -// NewSubjectAccessReviewLister returns a new SubjectAccessReviewLister. -func NewSubjectAccessReviewLister(indexer cache.Indexer) SubjectAccessReviewLister { - return &subjectAccessReviewLister{indexer: indexer} -} - -// List lists all SubjectAccessReviews in the indexer. -func (s *subjectAccessReviewLister) List(selector labels.Selector) (ret []*authorization.SubjectAccessReview, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*authorization.SubjectAccessReview)) - }) - return ret, err -} - -// Get retrieves the SubjectAccessReview from the index for a given name. -func (s *subjectAccessReviewLister) Get(name string) (*authorization.SubjectAccessReview, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(authorization.Resource("subjectaccessreview"), name) - } - return obj.(*authorization.SubjectAccessReview), nil -} diff --git a/pkg/client/listers/autoscaling/internalversion/BUILD b/pkg/client/listers/autoscaling/internalversion/BUILD deleted file mode 100644 index bd374cf85797a..0000000000000 --- a/pkg/client/listers/autoscaling/internalversion/BUILD +++ /dev/null @@ -1,34 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "horizontalpodautoscaler.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/autoscaling/internalversion", - deps = [ - "//pkg/apis/autoscaling:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/autoscaling/internalversion/expansion_generated.go b/pkg/client/listers/autoscaling/internalversion/expansion_generated.go deleted file mode 100644 index 4cc32824d30b5..0000000000000 --- a/pkg/client/listers/autoscaling/internalversion/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// HorizontalPodAutoscalerListerExpansion allows custom methods to be added to -// HorizontalPodAutoscalerLister. -type HorizontalPodAutoscalerListerExpansion interface{} - -// HorizontalPodAutoscalerNamespaceListerExpansion allows custom methods to be added to -// HorizontalPodAutoscalerNamespaceLister. -type HorizontalPodAutoscalerNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/autoscaling/internalversion/horizontalpodautoscaler.go b/pkg/client/listers/autoscaling/internalversion/horizontalpodautoscaler.go deleted file mode 100644 index 9f8451420c100..0000000000000 --- a/pkg/client/listers/autoscaling/internalversion/horizontalpodautoscaler.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" -) - -// HorizontalPodAutoscalerLister helps list HorizontalPodAutoscalers. -type HorizontalPodAutoscalerLister interface { - // List lists all HorizontalPodAutoscalers in the indexer. - List(selector labels.Selector) (ret []*autoscaling.HorizontalPodAutoscaler, err error) - // HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. - HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister - HorizontalPodAutoscalerListerExpansion -} - -// horizontalPodAutoscalerLister implements the HorizontalPodAutoscalerLister interface. -type horizontalPodAutoscalerLister struct { - indexer cache.Indexer -} - -// NewHorizontalPodAutoscalerLister returns a new HorizontalPodAutoscalerLister. -func NewHorizontalPodAutoscalerLister(indexer cache.Indexer) HorizontalPodAutoscalerLister { - return &horizontalPodAutoscalerLister{indexer: indexer} -} - -// List lists all HorizontalPodAutoscalers in the indexer. -func (s *horizontalPodAutoscalerLister) List(selector labels.Selector) (ret []*autoscaling.HorizontalPodAutoscaler, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*autoscaling.HorizontalPodAutoscaler)) - }) - return ret, err -} - -// HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. -func (s *horizontalPodAutoscalerLister) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister { - return horizontalPodAutoscalerNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// HorizontalPodAutoscalerNamespaceLister helps list and get HorizontalPodAutoscalers. -type HorizontalPodAutoscalerNamespaceLister interface { - // List lists all HorizontalPodAutoscalers in the indexer for a given namespace. - List(selector labels.Selector) (ret []*autoscaling.HorizontalPodAutoscaler, err error) - // Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. - Get(name string) (*autoscaling.HorizontalPodAutoscaler, error) - HorizontalPodAutoscalerNamespaceListerExpansion -} - -// horizontalPodAutoscalerNamespaceLister implements the HorizontalPodAutoscalerNamespaceLister -// interface. -type horizontalPodAutoscalerNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all HorizontalPodAutoscalers in the indexer for a given namespace. -func (s horizontalPodAutoscalerNamespaceLister) List(selector labels.Selector) (ret []*autoscaling.HorizontalPodAutoscaler, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*autoscaling.HorizontalPodAutoscaler)) - }) - return ret, err -} - -// Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. -func (s horizontalPodAutoscalerNamespaceLister) Get(name string) (*autoscaling.HorizontalPodAutoscaler, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(autoscaling.Resource("horizontalpodautoscaler"), name) - } - return obj.(*autoscaling.HorizontalPodAutoscaler), nil -} diff --git a/pkg/client/listers/batch/internalversion/BUILD b/pkg/client/listers/batch/internalversion/BUILD deleted file mode 100644 index b813cb35d7b18..0000000000000 --- a/pkg/client/listers/batch/internalversion/BUILD +++ /dev/null @@ -1,53 +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 = [ - "cronjob.go", - "expansion_generated.go", - "job.go", - "job_expansion.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/batch/internalversion", - deps = [ - "//pkg/apis/batch:go_default_library", - "//pkg/apis/core: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/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache:go_default_library", - ], -) - -go_test( - name = "go_default_test", - srcs = ["job_test.go"], - embed = [":go_default_library"], - deps = [ - "//pkg/apis/batch:go_default_library", - "//pkg/apis/core:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/batch/internalversion/cronjob.go b/pkg/client/listers/batch/internalversion/cronjob.go deleted file mode 100644 index aeebb4f4d7ed4..0000000000000 --- a/pkg/client/listers/batch/internalversion/cronjob.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - batch "k8s.io/kubernetes/pkg/apis/batch" -) - -// CronJobLister helps list CronJobs. -type CronJobLister interface { - // List lists all CronJobs in the indexer. - List(selector labels.Selector) (ret []*batch.CronJob, err error) - // CronJobs returns an object that can list and get CronJobs. - CronJobs(namespace string) CronJobNamespaceLister - CronJobListerExpansion -} - -// cronJobLister implements the CronJobLister interface. -type cronJobLister struct { - indexer cache.Indexer -} - -// NewCronJobLister returns a new CronJobLister. -func NewCronJobLister(indexer cache.Indexer) CronJobLister { - return &cronJobLister{indexer: indexer} -} - -// List lists all CronJobs in the indexer. -func (s *cronJobLister) List(selector labels.Selector) (ret []*batch.CronJob, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*batch.CronJob)) - }) - return ret, err -} - -// CronJobs returns an object that can list and get CronJobs. -func (s *cronJobLister) CronJobs(namespace string) CronJobNamespaceLister { - return cronJobNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// CronJobNamespaceLister helps list and get CronJobs. -type CronJobNamespaceLister interface { - // List lists all CronJobs in the indexer for a given namespace. - List(selector labels.Selector) (ret []*batch.CronJob, err error) - // Get retrieves the CronJob from the indexer for a given namespace and name. - Get(name string) (*batch.CronJob, error) - CronJobNamespaceListerExpansion -} - -// cronJobNamespaceLister implements the CronJobNamespaceLister -// interface. -type cronJobNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all CronJobs in the indexer for a given namespace. -func (s cronJobNamespaceLister) List(selector labels.Selector) (ret []*batch.CronJob, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*batch.CronJob)) - }) - return ret, err -} - -// Get retrieves the CronJob from the indexer for a given namespace and name. -func (s cronJobNamespaceLister) Get(name string) (*batch.CronJob, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(batch.Resource("cronjob"), name) - } - return obj.(*batch.CronJob), nil -} diff --git a/pkg/client/listers/batch/internalversion/expansion_generated.go b/pkg/client/listers/batch/internalversion/expansion_generated.go deleted file mode 100644 index 2bf27b1d6b833..0000000000000 --- a/pkg/client/listers/batch/internalversion/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// CronJobListerExpansion allows custom methods to be added to -// CronJobLister. -type CronJobListerExpansion interface{} - -// CronJobNamespaceListerExpansion allows custom methods to be added to -// CronJobNamespaceLister. -type CronJobNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/batch/internalversion/job.go b/pkg/client/listers/batch/internalversion/job.go deleted file mode 100644 index b67b84e7b4150..0000000000000 --- a/pkg/client/listers/batch/internalversion/job.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - batch "k8s.io/kubernetes/pkg/apis/batch" -) - -// JobLister helps list Jobs. -type JobLister interface { - // List lists all Jobs in the indexer. - List(selector labels.Selector) (ret []*batch.Job, err error) - // Jobs returns an object that can list and get Jobs. - Jobs(namespace string) JobNamespaceLister - JobListerExpansion -} - -// jobLister implements the JobLister interface. -type jobLister struct { - indexer cache.Indexer -} - -// NewJobLister returns a new JobLister. -func NewJobLister(indexer cache.Indexer) JobLister { - return &jobLister{indexer: indexer} -} - -// List lists all Jobs in the indexer. -func (s *jobLister) List(selector labels.Selector) (ret []*batch.Job, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*batch.Job)) - }) - return ret, err -} - -// Jobs returns an object that can list and get Jobs. -func (s *jobLister) Jobs(namespace string) JobNamespaceLister { - return jobNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// JobNamespaceLister helps list and get Jobs. -type JobNamespaceLister interface { - // List lists all Jobs in the indexer for a given namespace. - List(selector labels.Selector) (ret []*batch.Job, err error) - // Get retrieves the Job from the indexer for a given namespace and name. - Get(name string) (*batch.Job, error) - JobNamespaceListerExpansion -} - -// jobNamespaceLister implements the JobNamespaceLister -// interface. -type jobNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Jobs in the indexer for a given namespace. -func (s jobNamespaceLister) List(selector labels.Selector) (ret []*batch.Job, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*batch.Job)) - }) - return ret, err -} - -// Get retrieves the Job from the indexer for a given namespace and name. -func (s jobNamespaceLister) Get(name string) (*batch.Job, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(batch.Resource("job"), name) - } - return obj.(*batch.Job), nil -} diff --git a/pkg/client/listers/batch/internalversion/job_expansion.go b/pkg/client/listers/batch/internalversion/job_expansion.go deleted file mode 100644 index 083453d90f1cd..0000000000000 --- a/pkg/client/listers/batch/internalversion/job_expansion.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2016 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 internalversion - -import ( - "fmt" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/kubernetes/pkg/apis/batch" - api "k8s.io/kubernetes/pkg/apis/core" -) - -// JobListerExpansion allows custom methods to be added to -// JobLister. -type JobListerExpansion interface { - // GetPodJobs returns a list of Jobs that potentially - // match a Pod. Only the one specified in the Pod's ControllerRef - // will actually manage it. - // Returns an error only if no matching Jobs are found. - GetPodJobs(pod *api.Pod) (jobs []batch.Job, err error) -} - -// GetPodJobs returns a list of Jobs that potentially -// match a Pod. Only the one specified in the Pod's ControllerRef -// will actually manage it. -// Returns an error only if no matching Jobs are found. -func (l *jobLister) GetPodJobs(pod *api.Pod) (jobs []batch.Job, err error) { - if len(pod.Labels) == 0 { - err = fmt.Errorf("no jobs found for pod %v because it has no labels", pod.Name) - return - } - - var list []*batch.Job - list, err = l.Jobs(pod.Namespace).List(labels.Everything()) - if err != nil { - return - } - for _, job := range list { - selector, _ := metav1.LabelSelectorAsSelector(job.Spec.Selector) - if !selector.Matches(labels.Set(pod.Labels)) { - continue - } - jobs = append(jobs, *job) - } - if len(jobs) == 0 { - err = fmt.Errorf("could not find jobs for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) - } - return -} - -// JobNamespaceListerExpansion allows custom methods to be added to -// JobNamespaceLister. -type JobNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/batch/internalversion/job_test.go b/pkg/client/listers/batch/internalversion/job_test.go deleted file mode 100644 index b4c60de3e9e34..0000000000000 --- a/pkg/client/listers/batch/internalversion/job_test.go +++ /dev/null @@ -1,219 +0,0 @@ -/* -Copyright 2016 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 internalversion - -import ( - "testing" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/tools/cache" - "k8s.io/kubernetes/pkg/apis/batch" - api "k8s.io/kubernetes/pkg/apis/core" -) - -func TestJobLister(t *testing.T) { - indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) - lister := NewJobLister(indexer) - testCases := []struct { - inJobs []*batch.Job - list func() ([]*batch.Job, error) - outJobNames sets.String - expectErr bool - msg string - }{ - // Basic listing - { - inJobs: []*batch.Job{ - {ObjectMeta: metav1.ObjectMeta{Name: "basic"}}, - }, - list: func() ([]*batch.Job, error) { - list, err := lister.List(labels.Everything()) - return list, err - }, - outJobNames: sets.NewString("basic"), - msg: "basic listing failed", - }, - // Listing multiple jobs - { - inJobs: []*batch.Job{ - {ObjectMeta: metav1.ObjectMeta{Name: "basic"}}, - {ObjectMeta: metav1.ObjectMeta{Name: "complex"}}, - {ObjectMeta: metav1.ObjectMeta{Name: "complex2"}}, - }, - list: func() ([]*batch.Job, error) { - list, err := lister.List(labels.Everything()) - return list, err - }, - outJobNames: sets.NewString("basic", "complex", "complex2"), - msg: "listing multiple jobs failed", - }, - // No pod labels - { - inJobs: []*batch.Job{ - { - ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"}, - Spec: batch.JobSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"foo": "baz"}, - }, - }, - }, - }, - list: func() ([]*batch.Job, error) { - pod := &api.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "pod", Namespace: "ns"}, - } - podJobs, err := lister.GetPodJobs(pod) - jobs := make([]*batch.Job, 0, len(podJobs)) - for i := range podJobs { - jobs = append(jobs, &podJobs[i]) - } - return jobs, err - }, - outJobNames: sets.NewString(), - expectErr: true, - msg: "listing jobs failed when pod has no labels: expected error, got none", - }, - // No Job selectors - { - inJobs: []*batch.Job{ - { - ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"}, - }, - }, - list: func() ([]*batch.Job, error) { - pod := &api.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod", - Namespace: "ns", - Labels: map[string]string{"foo": "bar"}, - }, - } - podJobs, err := lister.GetPodJobs(pod) - jobs := make([]*batch.Job, 0, len(podJobs)) - for i := range podJobs { - jobs = append(jobs, &podJobs[i]) - } - return jobs, err - }, - outJobNames: sets.NewString(), - expectErr: true, - msg: "listing jobs failed when job has no selector: expected error, got none", - }, - // Matching labels to selectors and namespace - { - inJobs: []*batch.Job{ - { - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: batch.JobSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"foo": "bar"}, - }, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "ns"}, - Spec: batch.JobSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"foo": "bar"}, - }, - }, - }, - }, - list: func() ([]*batch.Job, error) { - pod := &api.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod", - Labels: map[string]string{"foo": "bar"}, - Namespace: "ns", - }, - } - podJobs, err := lister.GetPodJobs(pod) - jobs := make([]*batch.Job, 0, len(podJobs)) - for i := range podJobs { - jobs = append(jobs, &podJobs[i]) - } - return jobs, err - }, - outJobNames: sets.NewString("bar"), - msg: "listing jobs with namespace and selector failed", - }, - // Matching labels to selectors and namespace, error case - { - inJobs: []*batch.Job{ - { - ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "foo"}, - Spec: batch.JobSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"foo": "bar"}, - }, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "bar"}, - Spec: batch.JobSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"foo": "bar"}, - }, - }, - }, - }, - list: func() ([]*batch.Job, error) { - pod := &api.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod", - Labels: map[string]string{"foo": "bar"}, - Namespace: "baz", - }, - } - podJobs, err := lister.GetPodJobs(pod) - jobs := make([]*batch.Job, 0, len(podJobs)) - for i := range podJobs { - jobs = append(jobs, &podJobs[i]) - } - return jobs, err - }, - expectErr: true, - msg: "listing jobs with namespace and selector failed: expected error, got none", - }, - } - for _, c := range testCases { - for _, r := range c.inJobs { - indexer.Add(r) - } - - Jobs, err := c.list() - if err != nil && c.expectErr { - continue - } else if c.expectErr { - t.Errorf("%v", c.msg) - continue - } else if err != nil { - t.Errorf("Unexpected error %#v", err) - continue - } - JobNames := make([]string, len(Jobs)) - for ix := range Jobs { - JobNames[ix] = Jobs[ix].Name - } - if !c.outJobNames.HasAll(JobNames...) || len(JobNames) != len(c.outJobNames) { - t.Errorf("%v : expected %v, got %v", c.msg, JobNames, c.outJobNames) - } - } -} diff --git a/pkg/client/listers/certificates/internalversion/BUILD b/pkg/client/listers/certificates/internalversion/BUILD deleted file mode 100644 index b027621569930..0000000000000 --- a/pkg/client/listers/certificates/internalversion/BUILD +++ /dev/null @@ -1,34 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "certificatesigningrequest.go", - "expansion_generated.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/certificates/internalversion", - deps = [ - "//pkg/apis/certificates:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/certificates/internalversion/certificatesigningrequest.go b/pkg/client/listers/certificates/internalversion/certificatesigningrequest.go deleted file mode 100644 index 76c80a37305e4..0000000000000 --- a/pkg/client/listers/certificates/internalversion/certificatesigningrequest.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - certificates "k8s.io/kubernetes/pkg/apis/certificates" -) - -// CertificateSigningRequestLister helps list CertificateSigningRequests. -type CertificateSigningRequestLister interface { - // List lists all CertificateSigningRequests in the indexer. - List(selector labels.Selector) (ret []*certificates.CertificateSigningRequest, err error) - // Get retrieves the CertificateSigningRequest from the index for a given name. - Get(name string) (*certificates.CertificateSigningRequest, error) - CertificateSigningRequestListerExpansion -} - -// certificateSigningRequestLister implements the CertificateSigningRequestLister interface. -type certificateSigningRequestLister struct { - indexer cache.Indexer -} - -// NewCertificateSigningRequestLister returns a new CertificateSigningRequestLister. -func NewCertificateSigningRequestLister(indexer cache.Indexer) CertificateSigningRequestLister { - return &certificateSigningRequestLister{indexer: indexer} -} - -// List lists all CertificateSigningRequests in the indexer. -func (s *certificateSigningRequestLister) List(selector labels.Selector) (ret []*certificates.CertificateSigningRequest, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*certificates.CertificateSigningRequest)) - }) - return ret, err -} - -// Get retrieves the CertificateSigningRequest from the index for a given name. -func (s *certificateSigningRequestLister) Get(name string) (*certificates.CertificateSigningRequest, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(certificates.Resource("certificatesigningrequest"), name) - } - return obj.(*certificates.CertificateSigningRequest), nil -} diff --git a/pkg/client/listers/certificates/internalversion/expansion_generated.go b/pkg/client/listers/certificates/internalversion/expansion_generated.go deleted file mode 100644 index b859350757ad3..0000000000000 --- a/pkg/client/listers/certificates/internalversion/expansion_generated.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// CertificateSigningRequestListerExpansion allows custom methods to be added to -// CertificateSigningRequestLister. -type CertificateSigningRequestListerExpansion interface{} diff --git a/pkg/client/listers/coordination/internalversion/expansion_generated.go b/pkg/client/listers/coordination/internalversion/expansion_generated.go deleted file mode 100644 index 83cb52767fa54..0000000000000 --- a/pkg/client/listers/coordination/internalversion/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// LeaseListerExpansion allows custom methods to be added to -// LeaseLister. -type LeaseListerExpansion interface{} - -// LeaseNamespaceListerExpansion allows custom methods to be added to -// LeaseNamespaceLister. -type LeaseNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/coordination/internalversion/lease.go b/pkg/client/listers/coordination/internalversion/lease.go deleted file mode 100644 index 9cf35866e6f1d..0000000000000 --- a/pkg/client/listers/coordination/internalversion/lease.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - coordination "k8s.io/kubernetes/pkg/apis/coordination" -) - -// LeaseLister helps list Leases. -type LeaseLister interface { - // List lists all Leases in the indexer. - List(selector labels.Selector) (ret []*coordination.Lease, err error) - // Leases returns an object that can list and get Leases. - Leases(namespace string) LeaseNamespaceLister - LeaseListerExpansion -} - -// leaseLister implements the LeaseLister interface. -type leaseLister struct { - indexer cache.Indexer -} - -// NewLeaseLister returns a new LeaseLister. -func NewLeaseLister(indexer cache.Indexer) LeaseLister { - return &leaseLister{indexer: indexer} -} - -// List lists all Leases in the indexer. -func (s *leaseLister) List(selector labels.Selector) (ret []*coordination.Lease, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*coordination.Lease)) - }) - return ret, err -} - -// Leases returns an object that can list and get Leases. -func (s *leaseLister) Leases(namespace string) LeaseNamespaceLister { - return leaseNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// LeaseNamespaceLister helps list and get Leases. -type LeaseNamespaceLister interface { - // List lists all Leases in the indexer for a given namespace. - List(selector labels.Selector) (ret []*coordination.Lease, err error) - // Get retrieves the Lease from the indexer for a given namespace and name. - Get(name string) (*coordination.Lease, error) - LeaseNamespaceListerExpansion -} - -// leaseNamespaceLister implements the LeaseNamespaceLister -// interface. -type leaseNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Leases in the indexer for a given namespace. -func (s leaseNamespaceLister) List(selector labels.Selector) (ret []*coordination.Lease, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*coordination.Lease)) - }) - return ret, err -} - -// Get retrieves the Lease from the indexer for a given namespace and name. -func (s leaseNamespaceLister) Get(name string) (*coordination.Lease, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(coordination.Resource("lease"), name) - } - return obj.(*coordination.Lease), nil -} diff --git a/pkg/client/listers/core/internalversion/BUILD b/pkg/client/listers/core/internalversion/BUILD deleted file mode 100644 index 5ba8c353b8063..0000000000000 --- a/pkg/client/listers/core/internalversion/BUILD +++ /dev/null @@ -1,51 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "componentstatus.go", - "configmap.go", - "endpoints.go", - "event.go", - "expansion_generated.go", - "limitrange.go", - "namespace.go", - "node.go", - "persistentvolume.go", - "persistentvolumeclaim.go", - "pod.go", - "podtemplate.go", - "replicationcontroller.go", - "replicationcontroller_expansion.go", - "resourcequota.go", - "secret.go", - "service.go", - "service_expansion.go", - "serviceaccount.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/core/internalversion", - deps = [ - "//pkg/apis/core:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/core/internalversion/componentstatus.go b/pkg/client/listers/core/internalversion/componentstatus.go deleted file mode 100644 index 821247b4dec8c..0000000000000 --- a/pkg/client/listers/core/internalversion/componentstatus.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// ComponentStatusLister helps list ComponentStatuses. -type ComponentStatusLister interface { - // List lists all ComponentStatuses in the indexer. - List(selector labels.Selector) (ret []*core.ComponentStatus, err error) - // Get retrieves the ComponentStatus from the index for a given name. - Get(name string) (*core.ComponentStatus, error) - ComponentStatusListerExpansion -} - -// componentStatusLister implements the ComponentStatusLister interface. -type componentStatusLister struct { - indexer cache.Indexer -} - -// NewComponentStatusLister returns a new ComponentStatusLister. -func NewComponentStatusLister(indexer cache.Indexer) ComponentStatusLister { - return &componentStatusLister{indexer: indexer} -} - -// List lists all ComponentStatuses in the indexer. -func (s *componentStatusLister) List(selector labels.Selector) (ret []*core.ComponentStatus, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.ComponentStatus)) - }) - return ret, err -} - -// Get retrieves the ComponentStatus from the index for a given name. -func (s *componentStatusLister) Get(name string) (*core.ComponentStatus, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("componentstatus"), name) - } - return obj.(*core.ComponentStatus), nil -} diff --git a/pkg/client/listers/core/internalversion/configmap.go b/pkg/client/listers/core/internalversion/configmap.go deleted file mode 100644 index 46780e148d075..0000000000000 --- a/pkg/client/listers/core/internalversion/configmap.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// ConfigMapLister helps list ConfigMaps. -type ConfigMapLister interface { - // List lists all ConfigMaps in the indexer. - List(selector labels.Selector) (ret []*core.ConfigMap, err error) - // ConfigMaps returns an object that can list and get ConfigMaps. - ConfigMaps(namespace string) ConfigMapNamespaceLister - ConfigMapListerExpansion -} - -// configMapLister implements the ConfigMapLister interface. -type configMapLister struct { - indexer cache.Indexer -} - -// NewConfigMapLister returns a new ConfigMapLister. -func NewConfigMapLister(indexer cache.Indexer) ConfigMapLister { - return &configMapLister{indexer: indexer} -} - -// List lists all ConfigMaps in the indexer. -func (s *configMapLister) List(selector labels.Selector) (ret []*core.ConfigMap, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.ConfigMap)) - }) - return ret, err -} - -// ConfigMaps returns an object that can list and get ConfigMaps. -func (s *configMapLister) ConfigMaps(namespace string) ConfigMapNamespaceLister { - return configMapNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ConfigMapNamespaceLister helps list and get ConfigMaps. -type ConfigMapNamespaceLister interface { - // List lists all ConfigMaps in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.ConfigMap, err error) - // Get retrieves the ConfigMap from the indexer for a given namespace and name. - Get(name string) (*core.ConfigMap, error) - ConfigMapNamespaceListerExpansion -} - -// configMapNamespaceLister implements the ConfigMapNamespaceLister -// interface. -type configMapNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all ConfigMaps in the indexer for a given namespace. -func (s configMapNamespaceLister) List(selector labels.Selector) (ret []*core.ConfigMap, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.ConfigMap)) - }) - return ret, err -} - -// Get retrieves the ConfigMap from the indexer for a given namespace and name. -func (s configMapNamespaceLister) Get(name string) (*core.ConfigMap, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("configmap"), name) - } - return obj.(*core.ConfigMap), nil -} diff --git a/pkg/client/listers/core/internalversion/endpoints.go b/pkg/client/listers/core/internalversion/endpoints.go deleted file mode 100644 index d46e1bdd46d32..0000000000000 --- a/pkg/client/listers/core/internalversion/endpoints.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// EndpointsLister helps list Endpoints. -type EndpointsLister interface { - // List lists all Endpoints in the indexer. - List(selector labels.Selector) (ret []*core.Endpoints, err error) - // Endpoints returns an object that can list and get Endpoints. - Endpoints(namespace string) EndpointsNamespaceLister - EndpointsListerExpansion -} - -// endpointsLister implements the EndpointsLister interface. -type endpointsLister struct { - indexer cache.Indexer -} - -// NewEndpointsLister returns a new EndpointsLister. -func NewEndpointsLister(indexer cache.Indexer) EndpointsLister { - return &endpointsLister{indexer: indexer} -} - -// List lists all Endpoints in the indexer. -func (s *endpointsLister) List(selector labels.Selector) (ret []*core.Endpoints, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.Endpoints)) - }) - return ret, err -} - -// Endpoints returns an object that can list and get Endpoints. -func (s *endpointsLister) Endpoints(namespace string) EndpointsNamespaceLister { - return endpointsNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// EndpointsNamespaceLister helps list and get Endpoints. -type EndpointsNamespaceLister interface { - // List lists all Endpoints in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.Endpoints, err error) - // Get retrieves the Endpoints from the indexer for a given namespace and name. - Get(name string) (*core.Endpoints, error) - EndpointsNamespaceListerExpansion -} - -// endpointsNamespaceLister implements the EndpointsNamespaceLister -// interface. -type endpointsNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Endpoints in the indexer for a given namespace. -func (s endpointsNamespaceLister) List(selector labels.Selector) (ret []*core.Endpoints, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.Endpoints)) - }) - return ret, err -} - -// Get retrieves the Endpoints from the indexer for a given namespace and name. -func (s endpointsNamespaceLister) Get(name string) (*core.Endpoints, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("endpoints"), name) - } - return obj.(*core.Endpoints), nil -} diff --git a/pkg/client/listers/core/internalversion/event.go b/pkg/client/listers/core/internalversion/event.go deleted file mode 100644 index 017333fb19780..0000000000000 --- a/pkg/client/listers/core/internalversion/event.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// EventLister helps list Events. -type EventLister interface { - // List lists all Events in the indexer. - List(selector labels.Selector) (ret []*core.Event, err error) - // Events returns an object that can list and get Events. - Events(namespace string) EventNamespaceLister - EventListerExpansion -} - -// eventLister implements the EventLister interface. -type eventLister struct { - indexer cache.Indexer -} - -// NewEventLister returns a new EventLister. -func NewEventLister(indexer cache.Indexer) EventLister { - return &eventLister{indexer: indexer} -} - -// List lists all Events in the indexer. -func (s *eventLister) List(selector labels.Selector) (ret []*core.Event, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.Event)) - }) - return ret, err -} - -// Events returns an object that can list and get Events. -func (s *eventLister) Events(namespace string) EventNamespaceLister { - return eventNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// EventNamespaceLister helps list and get Events. -type EventNamespaceLister interface { - // List lists all Events in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.Event, err error) - // Get retrieves the Event from the indexer for a given namespace and name. - Get(name string) (*core.Event, error) - EventNamespaceListerExpansion -} - -// eventNamespaceLister implements the EventNamespaceLister -// interface. -type eventNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Events in the indexer for a given namespace. -func (s eventNamespaceLister) List(selector labels.Selector) (ret []*core.Event, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.Event)) - }) - return ret, err -} - -// Get retrieves the Event from the indexer for a given namespace and name. -func (s eventNamespaceLister) Get(name string) (*core.Event, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("event"), name) - } - return obj.(*core.Event), nil -} diff --git a/pkg/client/listers/core/internalversion/expansion_generated.go b/pkg/client/listers/core/internalversion/expansion_generated.go deleted file mode 100644 index 9fa5dfe6c2c9e..0000000000000 --- a/pkg/client/listers/core/internalversion/expansion_generated.go +++ /dev/null @@ -1,115 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// ComponentStatusListerExpansion allows custom methods to be added to -// ComponentStatusLister. -type ComponentStatusListerExpansion interface{} - -// ConfigMapListerExpansion allows custom methods to be added to -// ConfigMapLister. -type ConfigMapListerExpansion interface{} - -// ConfigMapNamespaceListerExpansion allows custom methods to be added to -// ConfigMapNamespaceLister. -type ConfigMapNamespaceListerExpansion interface{} - -// EndpointsListerExpansion allows custom methods to be added to -// EndpointsLister. -type EndpointsListerExpansion interface{} - -// EndpointsNamespaceListerExpansion allows custom methods to be added to -// EndpointsNamespaceLister. -type EndpointsNamespaceListerExpansion interface{} - -// EventListerExpansion allows custom methods to be added to -// EventLister. -type EventListerExpansion interface{} - -// EventNamespaceListerExpansion allows custom methods to be added to -// EventNamespaceLister. -type EventNamespaceListerExpansion interface{} - -// LimitRangeListerExpansion allows custom methods to be added to -// LimitRangeLister. -type LimitRangeListerExpansion interface{} - -// LimitRangeNamespaceListerExpansion allows custom methods to be added to -// LimitRangeNamespaceLister. -type LimitRangeNamespaceListerExpansion interface{} - -// NamespaceListerExpansion allows custom methods to be added to -// NamespaceLister. -type NamespaceListerExpansion interface{} - -// NodeListerExpansion allows custom methods to be added to -// NodeLister. -type NodeListerExpansion interface{} - -// PersistentVolumeListerExpansion allows custom methods to be added to -// PersistentVolumeLister. -type PersistentVolumeListerExpansion interface{} - -// PersistentVolumeClaimListerExpansion allows custom methods to be added to -// PersistentVolumeClaimLister. -type PersistentVolumeClaimListerExpansion interface{} - -// PersistentVolumeClaimNamespaceListerExpansion allows custom methods to be added to -// PersistentVolumeClaimNamespaceLister. -type PersistentVolumeClaimNamespaceListerExpansion interface{} - -// PodListerExpansion allows custom methods to be added to -// PodLister. -type PodListerExpansion interface{} - -// PodNamespaceListerExpansion allows custom methods to be added to -// PodNamespaceLister. -type PodNamespaceListerExpansion interface{} - -// PodTemplateListerExpansion allows custom methods to be added to -// PodTemplateLister. -type PodTemplateListerExpansion interface{} - -// PodTemplateNamespaceListerExpansion allows custom methods to be added to -// PodTemplateNamespaceLister. -type PodTemplateNamespaceListerExpansion interface{} - -// ResourceQuotaListerExpansion allows custom methods to be added to -// ResourceQuotaLister. -type ResourceQuotaListerExpansion interface{} - -// ResourceQuotaNamespaceListerExpansion allows custom methods to be added to -// ResourceQuotaNamespaceLister. -type ResourceQuotaNamespaceListerExpansion interface{} - -// SecretListerExpansion allows custom methods to be added to -// SecretLister. -type SecretListerExpansion interface{} - -// SecretNamespaceListerExpansion allows custom methods to be added to -// SecretNamespaceLister. -type SecretNamespaceListerExpansion interface{} - -// ServiceAccountListerExpansion allows custom methods to be added to -// ServiceAccountLister. -type ServiceAccountListerExpansion interface{} - -// ServiceAccountNamespaceListerExpansion allows custom methods to be added to -// ServiceAccountNamespaceLister. -type ServiceAccountNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/core/internalversion/limitrange.go b/pkg/client/listers/core/internalversion/limitrange.go deleted file mode 100644 index 4d76d078c24f6..0000000000000 --- a/pkg/client/listers/core/internalversion/limitrange.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// LimitRangeLister helps list LimitRanges. -type LimitRangeLister interface { - // List lists all LimitRanges in the indexer. - List(selector labels.Selector) (ret []*core.LimitRange, err error) - // LimitRanges returns an object that can list and get LimitRanges. - LimitRanges(namespace string) LimitRangeNamespaceLister - LimitRangeListerExpansion -} - -// limitRangeLister implements the LimitRangeLister interface. -type limitRangeLister struct { - indexer cache.Indexer -} - -// NewLimitRangeLister returns a new LimitRangeLister. -func NewLimitRangeLister(indexer cache.Indexer) LimitRangeLister { - return &limitRangeLister{indexer: indexer} -} - -// List lists all LimitRanges in the indexer. -func (s *limitRangeLister) List(selector labels.Selector) (ret []*core.LimitRange, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.LimitRange)) - }) - return ret, err -} - -// LimitRanges returns an object that can list and get LimitRanges. -func (s *limitRangeLister) LimitRanges(namespace string) LimitRangeNamespaceLister { - return limitRangeNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// LimitRangeNamespaceLister helps list and get LimitRanges. -type LimitRangeNamespaceLister interface { - // List lists all LimitRanges in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.LimitRange, err error) - // Get retrieves the LimitRange from the indexer for a given namespace and name. - Get(name string) (*core.LimitRange, error) - LimitRangeNamespaceListerExpansion -} - -// limitRangeNamespaceLister implements the LimitRangeNamespaceLister -// interface. -type limitRangeNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all LimitRanges in the indexer for a given namespace. -func (s limitRangeNamespaceLister) List(selector labels.Selector) (ret []*core.LimitRange, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.LimitRange)) - }) - return ret, err -} - -// Get retrieves the LimitRange from the indexer for a given namespace and name. -func (s limitRangeNamespaceLister) Get(name string) (*core.LimitRange, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("limitrange"), name) - } - return obj.(*core.LimitRange), nil -} diff --git a/pkg/client/listers/core/internalversion/namespace.go b/pkg/client/listers/core/internalversion/namespace.go deleted file mode 100644 index 1f4f19182f802..0000000000000 --- a/pkg/client/listers/core/internalversion/namespace.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// NamespaceLister helps list Namespaces. -type NamespaceLister interface { - // List lists all Namespaces in the indexer. - List(selector labels.Selector) (ret []*core.Namespace, err error) - // Get retrieves the Namespace from the index for a given name. - Get(name string) (*core.Namespace, error) - NamespaceListerExpansion -} - -// namespaceLister implements the NamespaceLister interface. -type namespaceLister struct { - indexer cache.Indexer -} - -// NewNamespaceLister returns a new NamespaceLister. -func NewNamespaceLister(indexer cache.Indexer) NamespaceLister { - return &namespaceLister{indexer: indexer} -} - -// List lists all Namespaces in the indexer. -func (s *namespaceLister) List(selector labels.Selector) (ret []*core.Namespace, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.Namespace)) - }) - return ret, err -} - -// Get retrieves the Namespace from the index for a given name. -func (s *namespaceLister) Get(name string) (*core.Namespace, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("namespace"), name) - } - return obj.(*core.Namespace), nil -} diff --git a/pkg/client/listers/core/internalversion/node.go b/pkg/client/listers/core/internalversion/node.go deleted file mode 100644 index f68c94f29468b..0000000000000 --- a/pkg/client/listers/core/internalversion/node.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// NodeLister helps list Nodes. -type NodeLister interface { - // List lists all Nodes in the indexer. - List(selector labels.Selector) (ret []*core.Node, err error) - // Get retrieves the Node from the index for a given name. - Get(name string) (*core.Node, error) - NodeListerExpansion -} - -// nodeLister implements the NodeLister interface. -type nodeLister struct { - indexer cache.Indexer -} - -// NewNodeLister returns a new NodeLister. -func NewNodeLister(indexer cache.Indexer) NodeLister { - return &nodeLister{indexer: indexer} -} - -// List lists all Nodes in the indexer. -func (s *nodeLister) List(selector labels.Selector) (ret []*core.Node, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.Node)) - }) - return ret, err -} - -// Get retrieves the Node from the index for a given name. -func (s *nodeLister) Get(name string) (*core.Node, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("node"), name) - } - return obj.(*core.Node), nil -} diff --git a/pkg/client/listers/core/internalversion/persistentvolume.go b/pkg/client/listers/core/internalversion/persistentvolume.go deleted file mode 100644 index 450096a48e3ff..0000000000000 --- a/pkg/client/listers/core/internalversion/persistentvolume.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// PersistentVolumeLister helps list PersistentVolumes. -type PersistentVolumeLister interface { - // List lists all PersistentVolumes in the indexer. - List(selector labels.Selector) (ret []*core.PersistentVolume, err error) - // Get retrieves the PersistentVolume from the index for a given name. - Get(name string) (*core.PersistentVolume, error) - PersistentVolumeListerExpansion -} - -// persistentVolumeLister implements the PersistentVolumeLister interface. -type persistentVolumeLister struct { - indexer cache.Indexer -} - -// NewPersistentVolumeLister returns a new PersistentVolumeLister. -func NewPersistentVolumeLister(indexer cache.Indexer) PersistentVolumeLister { - return &persistentVolumeLister{indexer: indexer} -} - -// List lists all PersistentVolumes in the indexer. -func (s *persistentVolumeLister) List(selector labels.Selector) (ret []*core.PersistentVolume, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.PersistentVolume)) - }) - return ret, err -} - -// Get retrieves the PersistentVolume from the index for a given name. -func (s *persistentVolumeLister) Get(name string) (*core.PersistentVolume, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("persistentvolume"), name) - } - return obj.(*core.PersistentVolume), nil -} diff --git a/pkg/client/listers/core/internalversion/persistentvolumeclaim.go b/pkg/client/listers/core/internalversion/persistentvolumeclaim.go deleted file mode 100644 index 431d7a4ce912e..0000000000000 --- a/pkg/client/listers/core/internalversion/persistentvolumeclaim.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// PersistentVolumeClaimLister helps list PersistentVolumeClaims. -type PersistentVolumeClaimLister interface { - // List lists all PersistentVolumeClaims in the indexer. - List(selector labels.Selector) (ret []*core.PersistentVolumeClaim, err error) - // PersistentVolumeClaims returns an object that can list and get PersistentVolumeClaims. - PersistentVolumeClaims(namespace string) PersistentVolumeClaimNamespaceLister - PersistentVolumeClaimListerExpansion -} - -// persistentVolumeClaimLister implements the PersistentVolumeClaimLister interface. -type persistentVolumeClaimLister struct { - indexer cache.Indexer -} - -// NewPersistentVolumeClaimLister returns a new PersistentVolumeClaimLister. -func NewPersistentVolumeClaimLister(indexer cache.Indexer) PersistentVolumeClaimLister { - return &persistentVolumeClaimLister{indexer: indexer} -} - -// List lists all PersistentVolumeClaims in the indexer. -func (s *persistentVolumeClaimLister) List(selector labels.Selector) (ret []*core.PersistentVolumeClaim, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.PersistentVolumeClaim)) - }) - return ret, err -} - -// PersistentVolumeClaims returns an object that can list and get PersistentVolumeClaims. -func (s *persistentVolumeClaimLister) PersistentVolumeClaims(namespace string) PersistentVolumeClaimNamespaceLister { - return persistentVolumeClaimNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// PersistentVolumeClaimNamespaceLister helps list and get PersistentVolumeClaims. -type PersistentVolumeClaimNamespaceLister interface { - // List lists all PersistentVolumeClaims in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.PersistentVolumeClaim, err error) - // Get retrieves the PersistentVolumeClaim from the indexer for a given namespace and name. - Get(name string) (*core.PersistentVolumeClaim, error) - PersistentVolumeClaimNamespaceListerExpansion -} - -// persistentVolumeClaimNamespaceLister implements the PersistentVolumeClaimNamespaceLister -// interface. -type persistentVolumeClaimNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all PersistentVolumeClaims in the indexer for a given namespace. -func (s persistentVolumeClaimNamespaceLister) List(selector labels.Selector) (ret []*core.PersistentVolumeClaim, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.PersistentVolumeClaim)) - }) - return ret, err -} - -// Get retrieves the PersistentVolumeClaim from the indexer for a given namespace and name. -func (s persistentVolumeClaimNamespaceLister) Get(name string) (*core.PersistentVolumeClaim, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("persistentvolumeclaim"), name) - } - return obj.(*core.PersistentVolumeClaim), nil -} diff --git a/pkg/client/listers/core/internalversion/pod.go b/pkg/client/listers/core/internalversion/pod.go deleted file mode 100644 index 55918afc68c3a..0000000000000 --- a/pkg/client/listers/core/internalversion/pod.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// PodLister helps list Pods. -type PodLister interface { - // List lists all Pods in the indexer. - List(selector labels.Selector) (ret []*core.Pod, err error) - // Pods returns an object that can list and get Pods. - Pods(namespace string) PodNamespaceLister - PodListerExpansion -} - -// podLister implements the PodLister interface. -type podLister struct { - indexer cache.Indexer -} - -// NewPodLister returns a new PodLister. -func NewPodLister(indexer cache.Indexer) PodLister { - return &podLister{indexer: indexer} -} - -// List lists all Pods in the indexer. -func (s *podLister) List(selector labels.Selector) (ret []*core.Pod, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.Pod)) - }) - return ret, err -} - -// Pods returns an object that can list and get Pods. -func (s *podLister) Pods(namespace string) PodNamespaceLister { - return podNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// PodNamespaceLister helps list and get Pods. -type PodNamespaceLister interface { - // List lists all Pods in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.Pod, err error) - // Get retrieves the Pod from the indexer for a given namespace and name. - Get(name string) (*core.Pod, error) - PodNamespaceListerExpansion -} - -// podNamespaceLister implements the PodNamespaceLister -// interface. -type podNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Pods in the indexer for a given namespace. -func (s podNamespaceLister) List(selector labels.Selector) (ret []*core.Pod, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.Pod)) - }) - return ret, err -} - -// Get retrieves the Pod from the indexer for a given namespace and name. -func (s podNamespaceLister) Get(name string) (*core.Pod, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("pod"), name) - } - return obj.(*core.Pod), nil -} diff --git a/pkg/client/listers/core/internalversion/podtemplate.go b/pkg/client/listers/core/internalversion/podtemplate.go deleted file mode 100644 index 73fb61bc3d333..0000000000000 --- a/pkg/client/listers/core/internalversion/podtemplate.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// PodTemplateLister helps list PodTemplates. -type PodTemplateLister interface { - // List lists all PodTemplates in the indexer. - List(selector labels.Selector) (ret []*core.PodTemplate, err error) - // PodTemplates returns an object that can list and get PodTemplates. - PodTemplates(namespace string) PodTemplateNamespaceLister - PodTemplateListerExpansion -} - -// podTemplateLister implements the PodTemplateLister interface. -type podTemplateLister struct { - indexer cache.Indexer -} - -// NewPodTemplateLister returns a new PodTemplateLister. -func NewPodTemplateLister(indexer cache.Indexer) PodTemplateLister { - return &podTemplateLister{indexer: indexer} -} - -// List lists all PodTemplates in the indexer. -func (s *podTemplateLister) List(selector labels.Selector) (ret []*core.PodTemplate, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.PodTemplate)) - }) - return ret, err -} - -// PodTemplates returns an object that can list and get PodTemplates. -func (s *podTemplateLister) PodTemplates(namespace string) PodTemplateNamespaceLister { - return podTemplateNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// PodTemplateNamespaceLister helps list and get PodTemplates. -type PodTemplateNamespaceLister interface { - // List lists all PodTemplates in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.PodTemplate, err error) - // Get retrieves the PodTemplate from the indexer for a given namespace and name. - Get(name string) (*core.PodTemplate, error) - PodTemplateNamespaceListerExpansion -} - -// podTemplateNamespaceLister implements the PodTemplateNamespaceLister -// interface. -type podTemplateNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all PodTemplates in the indexer for a given namespace. -func (s podTemplateNamespaceLister) List(selector labels.Selector) (ret []*core.PodTemplate, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.PodTemplate)) - }) - return ret, err -} - -// Get retrieves the PodTemplate from the indexer for a given namespace and name. -func (s podTemplateNamespaceLister) Get(name string) (*core.PodTemplate, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("podtemplate"), name) - } - return obj.(*core.PodTemplate), nil -} diff --git a/pkg/client/listers/core/internalversion/replicationcontroller.go b/pkg/client/listers/core/internalversion/replicationcontroller.go deleted file mode 100644 index a16fa0ebe948a..0000000000000 --- a/pkg/client/listers/core/internalversion/replicationcontroller.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// ReplicationControllerLister helps list ReplicationControllers. -type ReplicationControllerLister interface { - // List lists all ReplicationControllers in the indexer. - List(selector labels.Selector) (ret []*core.ReplicationController, err error) - // ReplicationControllers returns an object that can list and get ReplicationControllers. - ReplicationControllers(namespace string) ReplicationControllerNamespaceLister - ReplicationControllerListerExpansion -} - -// replicationControllerLister implements the ReplicationControllerLister interface. -type replicationControllerLister struct { - indexer cache.Indexer -} - -// NewReplicationControllerLister returns a new ReplicationControllerLister. -func NewReplicationControllerLister(indexer cache.Indexer) ReplicationControllerLister { - return &replicationControllerLister{indexer: indexer} -} - -// List lists all ReplicationControllers in the indexer. -func (s *replicationControllerLister) List(selector labels.Selector) (ret []*core.ReplicationController, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.ReplicationController)) - }) - return ret, err -} - -// ReplicationControllers returns an object that can list and get ReplicationControllers. -func (s *replicationControllerLister) ReplicationControllers(namespace string) ReplicationControllerNamespaceLister { - return replicationControllerNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ReplicationControllerNamespaceLister helps list and get ReplicationControllers. -type ReplicationControllerNamespaceLister interface { - // List lists all ReplicationControllers in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.ReplicationController, err error) - // Get retrieves the ReplicationController from the indexer for a given namespace and name. - Get(name string) (*core.ReplicationController, error) - ReplicationControllerNamespaceListerExpansion -} - -// replicationControllerNamespaceLister implements the ReplicationControllerNamespaceLister -// interface. -type replicationControllerNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all ReplicationControllers in the indexer for a given namespace. -func (s replicationControllerNamespaceLister) List(selector labels.Selector) (ret []*core.ReplicationController, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.ReplicationController)) - }) - return ret, err -} - -// Get retrieves the ReplicationController from the indexer for a given namespace and name. -func (s replicationControllerNamespaceLister) Get(name string) (*core.ReplicationController, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("replicationcontroller"), name) - } - return obj.(*core.ReplicationController), nil -} diff --git a/pkg/client/listers/core/internalversion/replicationcontroller_expansion.go b/pkg/client/listers/core/internalversion/replicationcontroller_expansion.go deleted file mode 100644 index bd9029160dad9..0000000000000 --- a/pkg/client/listers/core/internalversion/replicationcontroller_expansion.go +++ /dev/null @@ -1,66 +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 internalversion - -import ( - "fmt" - - "k8s.io/apimachinery/pkg/labels" - api "k8s.io/kubernetes/pkg/apis/core" -) - -// ReplicationControllerListerExpansion allows custom methods to be added to -// ReplicationControllerLister. -type ReplicationControllerListerExpansion interface { - GetPodControllers(pod *api.Pod) ([]*api.ReplicationController, error) -} - -// ReplicationControllerNamespaceListerExpansion allows custom methods to be added to -// ReplicationControllerNamespaceLister. -type ReplicationControllerNamespaceListerExpansion interface{} - -// GetPodControllers returns a list of ReplicationControllers that potentially match a pod. -// Only the one specified in the Pod's ControllerRef will actually manage it. -// Returns an error only if no matching ReplicationControllers are found. -func (s *replicationControllerLister) GetPodControllers(pod *api.Pod) ([]*api.ReplicationController, error) { - if len(pod.Labels) == 0 { - return nil, fmt.Errorf("no controllers found for pod %v because it has no labels", pod.Name) - } - - items, err := s.ReplicationControllers(pod.Namespace).List(labels.Everything()) - if err != nil { - return nil, err - } - - var controllers []*api.ReplicationController - for i := range items { - rc := items[i] - selector := labels.Set(rc.Spec.Selector).AsSelectorPreValidated() - - // If an rc with a nil or empty selector creeps in, it should match nothing, not everything. - if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { - continue - } - controllers = append(controllers, rc) - } - - if len(controllers) == 0 { - return nil, fmt.Errorf("could not find controller for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) - } - - return controllers, nil -} diff --git a/pkg/client/listers/core/internalversion/resourcequota.go b/pkg/client/listers/core/internalversion/resourcequota.go deleted file mode 100644 index 9b9e4bc96b840..0000000000000 --- a/pkg/client/listers/core/internalversion/resourcequota.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// ResourceQuotaLister helps list ResourceQuotas. -type ResourceQuotaLister interface { - // List lists all ResourceQuotas in the indexer. - List(selector labels.Selector) (ret []*core.ResourceQuota, err error) - // ResourceQuotas returns an object that can list and get ResourceQuotas. - ResourceQuotas(namespace string) ResourceQuotaNamespaceLister - ResourceQuotaListerExpansion -} - -// resourceQuotaLister implements the ResourceQuotaLister interface. -type resourceQuotaLister struct { - indexer cache.Indexer -} - -// NewResourceQuotaLister returns a new ResourceQuotaLister. -func NewResourceQuotaLister(indexer cache.Indexer) ResourceQuotaLister { - return &resourceQuotaLister{indexer: indexer} -} - -// List lists all ResourceQuotas in the indexer. -func (s *resourceQuotaLister) List(selector labels.Selector) (ret []*core.ResourceQuota, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.ResourceQuota)) - }) - return ret, err -} - -// ResourceQuotas returns an object that can list and get ResourceQuotas. -func (s *resourceQuotaLister) ResourceQuotas(namespace string) ResourceQuotaNamespaceLister { - return resourceQuotaNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ResourceQuotaNamespaceLister helps list and get ResourceQuotas. -type ResourceQuotaNamespaceLister interface { - // List lists all ResourceQuotas in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.ResourceQuota, err error) - // Get retrieves the ResourceQuota from the indexer for a given namespace and name. - Get(name string) (*core.ResourceQuota, error) - ResourceQuotaNamespaceListerExpansion -} - -// resourceQuotaNamespaceLister implements the ResourceQuotaNamespaceLister -// interface. -type resourceQuotaNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all ResourceQuotas in the indexer for a given namespace. -func (s resourceQuotaNamespaceLister) List(selector labels.Selector) (ret []*core.ResourceQuota, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.ResourceQuota)) - }) - return ret, err -} - -// Get retrieves the ResourceQuota from the indexer for a given namespace and name. -func (s resourceQuotaNamespaceLister) Get(name string) (*core.ResourceQuota, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("resourcequota"), name) - } - return obj.(*core.ResourceQuota), nil -} diff --git a/pkg/client/listers/core/internalversion/secret.go b/pkg/client/listers/core/internalversion/secret.go deleted file mode 100644 index 71c76488d1146..0000000000000 --- a/pkg/client/listers/core/internalversion/secret.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// SecretLister helps list Secrets. -type SecretLister interface { - // List lists all Secrets in the indexer. - List(selector labels.Selector) (ret []*core.Secret, err error) - // Secrets returns an object that can list and get Secrets. - Secrets(namespace string) SecretNamespaceLister - SecretListerExpansion -} - -// secretLister implements the SecretLister interface. -type secretLister struct { - indexer cache.Indexer -} - -// NewSecretLister returns a new SecretLister. -func NewSecretLister(indexer cache.Indexer) SecretLister { - return &secretLister{indexer: indexer} -} - -// List lists all Secrets in the indexer. -func (s *secretLister) List(selector labels.Selector) (ret []*core.Secret, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.Secret)) - }) - return ret, err -} - -// Secrets returns an object that can list and get Secrets. -func (s *secretLister) Secrets(namespace string) SecretNamespaceLister { - return secretNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// SecretNamespaceLister helps list and get Secrets. -type SecretNamespaceLister interface { - // List lists all Secrets in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.Secret, err error) - // Get retrieves the Secret from the indexer for a given namespace and name. - Get(name string) (*core.Secret, error) - SecretNamespaceListerExpansion -} - -// secretNamespaceLister implements the SecretNamespaceLister -// interface. -type secretNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Secrets in the indexer for a given namespace. -func (s secretNamespaceLister) List(selector labels.Selector) (ret []*core.Secret, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.Secret)) - }) - return ret, err -} - -// Get retrieves the Secret from the indexer for a given namespace and name. -func (s secretNamespaceLister) Get(name string) (*core.Secret, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("secret"), name) - } - return obj.(*core.Secret), nil -} diff --git a/pkg/client/listers/core/internalversion/service.go b/pkg/client/listers/core/internalversion/service.go deleted file mode 100644 index 4dd38cb08f16b..0000000000000 --- a/pkg/client/listers/core/internalversion/service.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// ServiceLister helps list Services. -type ServiceLister interface { - // List lists all Services in the indexer. - List(selector labels.Selector) (ret []*core.Service, err error) - // Services returns an object that can list and get Services. - Services(namespace string) ServiceNamespaceLister - ServiceListerExpansion -} - -// serviceLister implements the ServiceLister interface. -type serviceLister struct { - indexer cache.Indexer -} - -// NewServiceLister returns a new ServiceLister. -func NewServiceLister(indexer cache.Indexer) ServiceLister { - return &serviceLister{indexer: indexer} -} - -// List lists all Services in the indexer. -func (s *serviceLister) List(selector labels.Selector) (ret []*core.Service, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.Service)) - }) - return ret, err -} - -// Services returns an object that can list and get Services. -func (s *serviceLister) Services(namespace string) ServiceNamespaceLister { - return serviceNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ServiceNamespaceLister helps list and get Services. -type ServiceNamespaceLister interface { - // List lists all Services in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.Service, err error) - // Get retrieves the Service from the indexer for a given namespace and name. - Get(name string) (*core.Service, error) - ServiceNamespaceListerExpansion -} - -// serviceNamespaceLister implements the ServiceNamespaceLister -// interface. -type serviceNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Services in the indexer for a given namespace. -func (s serviceNamespaceLister) List(selector labels.Selector) (ret []*core.Service, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.Service)) - }) - return ret, err -} - -// Get retrieves the Service from the indexer for a given namespace and name. -func (s serviceNamespaceLister) Get(name string) (*core.Service, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("service"), name) - } - return obj.(*core.Service), nil -} diff --git a/pkg/client/listers/core/internalversion/service_expansion.go b/pkg/client/listers/core/internalversion/service_expansion.go deleted file mode 100644 index 6a951cabfd319..0000000000000 --- a/pkg/client/listers/core/internalversion/service_expansion.go +++ /dev/null @@ -1,56 +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 internalversion - -import ( - "k8s.io/apimachinery/pkg/labels" - api "k8s.io/kubernetes/pkg/apis/core" -) - -// ServiceListerExpansion allows custom methods to be added to -// ServiceLister. -type ServiceListerExpansion interface { - GetPodServices(pod *api.Pod) ([]*api.Service, error) -} - -// ServiceNamespaceListerExpansion allows custom methods to be added to -// ServiceNamespaceLister. -type ServiceNamespaceListerExpansion interface{} - -// TODO: Move this back to scheduler as a helper function that takes a Store, -// rather than a method of ServiceLister. -func (s *serviceLister) GetPodServices(pod *api.Pod) ([]*api.Service, error) { - allServices, err := s.Services(pod.Namespace).List(labels.Everything()) - if err != nil { - return nil, err - } - - var services []*api.Service - for i := range allServices { - service := allServices[i] - if service.Spec.Selector == nil { - // services with nil selectors match nothing, not everything. - continue - } - selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated() - if selector.Matches(labels.Set(pod.Labels)) { - services = append(services, service) - } - } - - return services, nil -} diff --git a/pkg/client/listers/core/internalversion/serviceaccount.go b/pkg/client/listers/core/internalversion/serviceaccount.go deleted file mode 100644 index c8dfce6f853e7..0000000000000 --- a/pkg/client/listers/core/internalversion/serviceaccount.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// ServiceAccountLister helps list ServiceAccounts. -type ServiceAccountLister interface { - // List lists all ServiceAccounts in the indexer. - List(selector labels.Selector) (ret []*core.ServiceAccount, err error) - // ServiceAccounts returns an object that can list and get ServiceAccounts. - ServiceAccounts(namespace string) ServiceAccountNamespaceLister - ServiceAccountListerExpansion -} - -// serviceAccountLister implements the ServiceAccountLister interface. -type serviceAccountLister struct { - indexer cache.Indexer -} - -// NewServiceAccountLister returns a new ServiceAccountLister. -func NewServiceAccountLister(indexer cache.Indexer) ServiceAccountLister { - return &serviceAccountLister{indexer: indexer} -} - -// List lists all ServiceAccounts in the indexer. -func (s *serviceAccountLister) List(selector labels.Selector) (ret []*core.ServiceAccount, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*core.ServiceAccount)) - }) - return ret, err -} - -// ServiceAccounts returns an object that can list and get ServiceAccounts. -func (s *serviceAccountLister) ServiceAccounts(namespace string) ServiceAccountNamespaceLister { - return serviceAccountNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ServiceAccountNamespaceLister helps list and get ServiceAccounts. -type ServiceAccountNamespaceLister interface { - // List lists all ServiceAccounts in the indexer for a given namespace. - List(selector labels.Selector) (ret []*core.ServiceAccount, err error) - // Get retrieves the ServiceAccount from the indexer for a given namespace and name. - Get(name string) (*core.ServiceAccount, error) - ServiceAccountNamespaceListerExpansion -} - -// serviceAccountNamespaceLister implements the ServiceAccountNamespaceLister -// interface. -type serviceAccountNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all ServiceAccounts in the indexer for a given namespace. -func (s serviceAccountNamespaceLister) List(selector labels.Selector) (ret []*core.ServiceAccount, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*core.ServiceAccount)) - }) - return ret, err -} - -// Get retrieves the ServiceAccount from the indexer for a given namespace and name. -func (s serviceAccountNamespaceLister) Get(name string) (*core.ServiceAccount, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(core.Resource("serviceaccount"), name) - } - return obj.(*core.ServiceAccount), nil -} diff --git a/pkg/client/listers/extensions/internalversion/BUILD b/pkg/client/listers/extensions/internalversion/BUILD deleted file mode 100644 index 091d60cee7f01..0000000000000 --- a/pkg/client/listers/extensions/internalversion/BUILD +++ /dev/null @@ -1,57 +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 = [ - "daemonset.go", - "daemonset_expansion.go", - "deployment.go", - "deployment_expansion.go", - "expansion_generated.go", - "ingress.go", - "replicaset.go", - "replicaset_expansion.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion", - deps = [ - "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions: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/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], -) - -go_test( - name = "go_default_test", - srcs = ["daemonset_expansion_test.go"], - embed = [":go_default_library"], - deps = [ - "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache:go_default_library", - ], -) diff --git a/pkg/client/listers/extensions/internalversion/daemonset.go b/pkg/client/listers/extensions/internalversion/daemonset.go deleted file mode 100644 index d6725e9846692..0000000000000 --- a/pkg/client/listers/extensions/internalversion/daemonset.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - extensions "k8s.io/kubernetes/pkg/apis/extensions" -) - -// DaemonSetLister helps list DaemonSets. -type DaemonSetLister interface { - // List lists all DaemonSets in the indexer. - List(selector labels.Selector) (ret []*extensions.DaemonSet, err error) - // DaemonSets returns an object that can list and get DaemonSets. - DaemonSets(namespace string) DaemonSetNamespaceLister - DaemonSetListerExpansion -} - -// daemonSetLister implements the DaemonSetLister interface. -type daemonSetLister struct { - indexer cache.Indexer -} - -// NewDaemonSetLister returns a new DaemonSetLister. -func NewDaemonSetLister(indexer cache.Indexer) DaemonSetLister { - return &daemonSetLister{indexer: indexer} -} - -// List lists all DaemonSets in the indexer. -func (s *daemonSetLister) List(selector labels.Selector) (ret []*extensions.DaemonSet, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*extensions.DaemonSet)) - }) - return ret, err -} - -// DaemonSets returns an object that can list and get DaemonSets. -func (s *daemonSetLister) DaemonSets(namespace string) DaemonSetNamespaceLister { - return daemonSetNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// DaemonSetNamespaceLister helps list and get DaemonSets. -type DaemonSetNamespaceLister interface { - // List lists all DaemonSets in the indexer for a given namespace. - List(selector labels.Selector) (ret []*extensions.DaemonSet, err error) - // Get retrieves the DaemonSet from the indexer for a given namespace and name. - Get(name string) (*extensions.DaemonSet, error) - DaemonSetNamespaceListerExpansion -} - -// daemonSetNamespaceLister implements the DaemonSetNamespaceLister -// interface. -type daemonSetNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all DaemonSets in the indexer for a given namespace. -func (s daemonSetNamespaceLister) List(selector labels.Selector) (ret []*extensions.DaemonSet, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*extensions.DaemonSet)) - }) - return ret, err -} - -// Get retrieves the DaemonSet from the indexer for a given namespace and name. -func (s daemonSetNamespaceLister) Get(name string) (*extensions.DaemonSet, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(extensions.Resource("daemonset"), name) - } - return obj.(*extensions.DaemonSet), nil -} diff --git a/pkg/client/listers/extensions/internalversion/daemonset_expansion.go b/pkg/client/listers/extensions/internalversion/daemonset_expansion.go deleted file mode 100644 index dd9eee743112c..0000000000000 --- a/pkg/client/listers/extensions/internalversion/daemonset_expansion.go +++ /dev/null @@ -1,78 +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 internalversion - -import ( - "fmt" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" -) - -// DaemonSetListerExpansion allows custom methods to be added to -// DaemonSetLister. -type DaemonSetListerExpansion interface { - GetPodDaemonSets(pod *api.Pod) ([]*extensions.DaemonSet, error) -} - -// DaemonSetNamespaceListerExpansion allows custom methods to be added to -// DaemonSetNamespaceLister. -type DaemonSetNamespaceListerExpansion interface{} - -// GetPodDaemonSets returns a list of DaemonSets that potentially match a pod. -// Only the one specified in the Pod's ControllerRef will actually manage it. -// Returns an error only if no matching DaemonSets are found. -func (s *daemonSetLister) GetPodDaemonSets(pod *api.Pod) ([]*extensions.DaemonSet, error) { - var selector labels.Selector - var daemonSet *extensions.DaemonSet - - if len(pod.Labels) == 0 { - return nil, fmt.Errorf("no daemon sets found for pod %v because it has no labels", pod.Name) - } - - list, err := s.DaemonSets(pod.Namespace).List(labels.Everything()) - if err != nil { - return nil, err - } - - var daemonSets []*extensions.DaemonSet - for i := range list { - daemonSet = list[i] - if daemonSet.Namespace != pod.Namespace { - continue - } - selector, err = metav1.LabelSelectorAsSelector(daemonSet.Spec.Selector) - if err != nil { - // this should not happen if the DaemonSet passed validation - return nil, err - } - - // If a daemonSet with a nil or empty selector creeps in, it should match nothing, not everything. - if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { - continue - } - daemonSets = append(daemonSets, daemonSet) - } - - if len(daemonSets) == 0 { - return nil, fmt.Errorf("could not find daemon set for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) - } - - return daemonSets, nil -} diff --git a/pkg/client/listers/extensions/internalversion/daemonset_expansion_test.go b/pkg/client/listers/extensions/internalversion/daemonset_expansion_test.go deleted file mode 100644 index 2455b5271ab9b..0000000000000 --- a/pkg/client/listers/extensions/internalversion/daemonset_expansion_test.go +++ /dev/null @@ -1,152 +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 internalversion - -import ( - "testing" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/tools/cache" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" -) - -func TestDaemonSetLister(t *testing.T) { - store := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}) - lister := NewDaemonSetLister(store) - testCases := []struct { - inDSs []*extensions.DaemonSet - list func() ([]*extensions.DaemonSet, error) - outDaemonSetNames sets.String - expectErr bool - }{ - // Basic listing - { - inDSs: []*extensions.DaemonSet{ - {ObjectMeta: metav1.ObjectMeta{Name: "basic"}}, - }, - list: func() ([]*extensions.DaemonSet, error) { - return lister.List(labels.Everything()) - }, - outDaemonSetNames: sets.NewString("basic"), - }, - // Listing multiple daemon sets - { - inDSs: []*extensions.DaemonSet{ - {ObjectMeta: metav1.ObjectMeta{Name: "basic"}}, - {ObjectMeta: metav1.ObjectMeta{Name: "complex"}}, - {ObjectMeta: metav1.ObjectMeta{Name: "complex2"}}, - }, - list: func() ([]*extensions.DaemonSet, error) { - return lister.List(labels.Everything()) - }, - outDaemonSetNames: sets.NewString("basic", "complex", "complex2"), - }, - // No pod labels - { - inDSs: []*extensions.DaemonSet{ - { - ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}}, - }, - }, - }, - list: func() ([]*extensions.DaemonSet, error) { - pod := &api.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "pod1", Namespace: "ns"}, - } - return lister.GetPodDaemonSets(pod) - }, - outDaemonSetNames: sets.NewString(), - expectErr: true, - }, - // No DS selectors - { - inDSs: []*extensions.DaemonSet{ - { - ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"}, - }, - }, - list: func() ([]*extensions.DaemonSet, error) { - pod := &api.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod1", - Namespace: "ns", - Labels: map[string]string{"foo": "bar"}, - }, - } - return lister.GetPodDaemonSets(pod) - }, - outDaemonSetNames: sets.NewString(), - expectErr: true, - }, - // Matching labels to selectors and namespace - { - inDSs: []*extensions.DaemonSet{ - { - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "ns"}, - Spec: extensions.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, - }, - }, - }, - list: func() ([]*extensions.DaemonSet, error) { - pod := &api.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod1", - Labels: map[string]string{"foo": "bar"}, - Namespace: "ns", - }, - } - return lister.GetPodDaemonSets(pod) - }, - outDaemonSetNames: sets.NewString("bar"), - }, - } - for _, c := range testCases { - for _, r := range c.inDSs { - store.Add(r) - } - - daemonSets, err := c.list() - if err != nil && c.expectErr { - continue - } else if c.expectErr { - t.Error("Expected error, got none") - continue - } else if err != nil { - t.Errorf("Unexpected error %#v", err) - continue - } - daemonSetNames := make([]string, len(daemonSets)) - for ix := range daemonSets { - daemonSetNames[ix] = daemonSets[ix].Name - } - if !c.outDaemonSetNames.HasAll(daemonSetNames...) || len(daemonSetNames) != len(c.outDaemonSetNames) { - t.Errorf("Unexpected got controllers %+v expected %+v", daemonSetNames, c.outDaemonSetNames) - } - } -} diff --git a/pkg/client/listers/extensions/internalversion/deployment.go b/pkg/client/listers/extensions/internalversion/deployment.go deleted file mode 100644 index f18e6d4b89e39..0000000000000 --- a/pkg/client/listers/extensions/internalversion/deployment.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - extensions "k8s.io/kubernetes/pkg/apis/extensions" -) - -// DeploymentLister helps list Deployments. -type DeploymentLister interface { - // List lists all Deployments in the indexer. - List(selector labels.Selector) (ret []*extensions.Deployment, err error) - // Deployments returns an object that can list and get Deployments. - Deployments(namespace string) DeploymentNamespaceLister - DeploymentListerExpansion -} - -// deploymentLister implements the DeploymentLister interface. -type deploymentLister struct { - indexer cache.Indexer -} - -// NewDeploymentLister returns a new DeploymentLister. -func NewDeploymentLister(indexer cache.Indexer) DeploymentLister { - return &deploymentLister{indexer: indexer} -} - -// List lists all Deployments in the indexer. -func (s *deploymentLister) List(selector labels.Selector) (ret []*extensions.Deployment, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*extensions.Deployment)) - }) - return ret, err -} - -// Deployments returns an object that can list and get Deployments. -func (s *deploymentLister) Deployments(namespace string) DeploymentNamespaceLister { - return deploymentNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// DeploymentNamespaceLister helps list and get Deployments. -type DeploymentNamespaceLister interface { - // List lists all Deployments in the indexer for a given namespace. - List(selector labels.Selector) (ret []*extensions.Deployment, err error) - // Get retrieves the Deployment from the indexer for a given namespace and name. - Get(name string) (*extensions.Deployment, error) - DeploymentNamespaceListerExpansion -} - -// deploymentNamespaceLister implements the DeploymentNamespaceLister -// interface. -type deploymentNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Deployments in the indexer for a given namespace. -func (s deploymentNamespaceLister) List(selector labels.Selector) (ret []*extensions.Deployment, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*extensions.Deployment)) - }) - return ret, err -} - -// Get retrieves the Deployment from the indexer for a given namespace and name. -func (s deploymentNamespaceLister) Get(name string) (*extensions.Deployment, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(extensions.Resource("deployment"), name) - } - return obj.(*extensions.Deployment), nil -} diff --git a/pkg/client/listers/extensions/internalversion/deployment_expansion.go b/pkg/client/listers/extensions/internalversion/deployment_expansion.go deleted file mode 100644 index 0755a402704d4..0000000000000 --- a/pkg/client/listers/extensions/internalversion/deployment_expansion.go +++ /dev/null @@ -1,70 +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 internalversion - -import ( - "fmt" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/kubernetes/pkg/apis/extensions" -) - -// DeploymentListerExpansion allows custom methods to be added to -// DeploymentLister. -type DeploymentListerExpansion interface { - GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) ([]*extensions.Deployment, error) -} - -// DeploymentNamespaceListerExpansion allows custom methods to be added to -// DeploymentNamespaceLister. -type DeploymentNamespaceListerExpansion interface{} - -// GetDeploymentsForReplicaSet returns a list of Deployments that potentially -// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef -// will actually manage it. -// Returns an error only if no matching Deployments are found. -func (s *deploymentLister) GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) ([]*extensions.Deployment, error) { - if len(rs.Labels) == 0 { - return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name) - } - - // TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label - dList, err := s.Deployments(rs.Namespace).List(labels.Everything()) - if err != nil { - return nil, err - } - - var deployments []*extensions.Deployment - for _, d := range dList { - selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector) - if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) - } - // If a deployment with a nil or empty selector creeps in, it should match nothing, not everything. - if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) { - continue - } - deployments = append(deployments, d) - } - - if len(deployments) == 0 { - return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels) - } - - return deployments, nil -} diff --git a/pkg/client/listers/extensions/internalversion/expansion_generated.go b/pkg/client/listers/extensions/internalversion/expansion_generated.go deleted file mode 100644 index 546c98520dffd..0000000000000 --- a/pkg/client/listers/extensions/internalversion/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// IngressListerExpansion allows custom methods to be added to -// IngressLister. -type IngressListerExpansion interface{} - -// IngressNamespaceListerExpansion allows custom methods to be added to -// IngressNamespaceLister. -type IngressNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/extensions/internalversion/ingress.go b/pkg/client/listers/extensions/internalversion/ingress.go deleted file mode 100644 index 185b67891b158..0000000000000 --- a/pkg/client/listers/extensions/internalversion/ingress.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - extensions "k8s.io/kubernetes/pkg/apis/extensions" -) - -// IngressLister helps list Ingresses. -type IngressLister interface { - // List lists all Ingresses in the indexer. - List(selector labels.Selector) (ret []*extensions.Ingress, err error) - // Ingresses returns an object that can list and get Ingresses. - Ingresses(namespace string) IngressNamespaceLister - IngressListerExpansion -} - -// ingressLister implements the IngressLister interface. -type ingressLister struct { - indexer cache.Indexer -} - -// NewIngressLister returns a new IngressLister. -func NewIngressLister(indexer cache.Indexer) IngressLister { - return &ingressLister{indexer: indexer} -} - -// List lists all Ingresses in the indexer. -func (s *ingressLister) List(selector labels.Selector) (ret []*extensions.Ingress, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*extensions.Ingress)) - }) - return ret, err -} - -// Ingresses returns an object that can list and get Ingresses. -func (s *ingressLister) Ingresses(namespace string) IngressNamespaceLister { - return ingressNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// IngressNamespaceLister helps list and get Ingresses. -type IngressNamespaceLister interface { - // List lists all Ingresses in the indexer for a given namespace. - List(selector labels.Selector) (ret []*extensions.Ingress, err error) - // Get retrieves the Ingress from the indexer for a given namespace and name. - Get(name string) (*extensions.Ingress, error) - IngressNamespaceListerExpansion -} - -// ingressNamespaceLister implements the IngressNamespaceLister -// interface. -type ingressNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Ingresses in the indexer for a given namespace. -func (s ingressNamespaceLister) List(selector labels.Selector) (ret []*extensions.Ingress, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*extensions.Ingress)) - }) - return ret, err -} - -// Get retrieves the Ingress from the indexer for a given namespace and name. -func (s ingressNamespaceLister) Get(name string) (*extensions.Ingress, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(extensions.Resource("ingress"), name) - } - return obj.(*extensions.Ingress), nil -} diff --git a/pkg/client/listers/extensions/internalversion/replicaset.go b/pkg/client/listers/extensions/internalversion/replicaset.go deleted file mode 100644 index 439713235f11d..0000000000000 --- a/pkg/client/listers/extensions/internalversion/replicaset.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - extensions "k8s.io/kubernetes/pkg/apis/extensions" -) - -// ReplicaSetLister helps list ReplicaSets. -type ReplicaSetLister interface { - // List lists all ReplicaSets in the indexer. - List(selector labels.Selector) (ret []*extensions.ReplicaSet, err error) - // ReplicaSets returns an object that can list and get ReplicaSets. - ReplicaSets(namespace string) ReplicaSetNamespaceLister - ReplicaSetListerExpansion -} - -// replicaSetLister implements the ReplicaSetLister interface. -type replicaSetLister struct { - indexer cache.Indexer -} - -// NewReplicaSetLister returns a new ReplicaSetLister. -func NewReplicaSetLister(indexer cache.Indexer) ReplicaSetLister { - return &replicaSetLister{indexer: indexer} -} - -// List lists all ReplicaSets in the indexer. -func (s *replicaSetLister) List(selector labels.Selector) (ret []*extensions.ReplicaSet, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*extensions.ReplicaSet)) - }) - return ret, err -} - -// ReplicaSets returns an object that can list and get ReplicaSets. -func (s *replicaSetLister) ReplicaSets(namespace string) ReplicaSetNamespaceLister { - return replicaSetNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ReplicaSetNamespaceLister helps list and get ReplicaSets. -type ReplicaSetNamespaceLister interface { - // List lists all ReplicaSets in the indexer for a given namespace. - List(selector labels.Selector) (ret []*extensions.ReplicaSet, err error) - // Get retrieves the ReplicaSet from the indexer for a given namespace and name. - Get(name string) (*extensions.ReplicaSet, error) - ReplicaSetNamespaceListerExpansion -} - -// replicaSetNamespaceLister implements the ReplicaSetNamespaceLister -// interface. -type replicaSetNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all ReplicaSets in the indexer for a given namespace. -func (s replicaSetNamespaceLister) List(selector labels.Selector) (ret []*extensions.ReplicaSet, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*extensions.ReplicaSet)) - }) - return ret, err -} - -// Get retrieves the ReplicaSet from the indexer for a given namespace and name. -func (s replicaSetNamespaceLister) Get(name string) (*extensions.ReplicaSet, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(extensions.Resource("replicaset"), name) - } - return obj.(*extensions.ReplicaSet), nil -} diff --git a/pkg/client/listers/extensions/internalversion/replicaset_expansion.go b/pkg/client/listers/extensions/internalversion/replicaset_expansion.go deleted file mode 100644 index 3b3cfc361f48f..0000000000000 --- a/pkg/client/listers/extensions/internalversion/replicaset_expansion.go +++ /dev/null @@ -1,73 +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 internalversion - -import ( - "fmt" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" -) - -// ReplicaSetListerExpansion allows custom methods to be added to -// ReplicaSetLister. -type ReplicaSetListerExpansion interface { - GetPodReplicaSets(pod *api.Pod) ([]*extensions.ReplicaSet, error) -} - -// ReplicaSetNamespaceListerExpansion allows custom methods to be added to -// ReplicaSetNamespaceLister. -type ReplicaSetNamespaceListerExpansion interface{} - -// GetPodReplicaSets returns a list of ReplicaSets that potentially match a pod. -// Only the one specified in the Pod's ControllerRef will actually manage it. -// Returns an error only if no matching ReplicaSets are found. -func (s *replicaSetLister) GetPodReplicaSets(pod *api.Pod) ([]*extensions.ReplicaSet, error) { - if len(pod.Labels) == 0 { - return nil, fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name) - } - - list, err := s.ReplicaSets(pod.Namespace).List(labels.Everything()) - if err != nil { - return nil, err - } - - var rss []*extensions.ReplicaSet - for _, rs := range list { - if rs.Namespace != pod.Namespace { - continue - } - selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) - if err != nil { - return nil, fmt.Errorf("invalid selector: %v", err) - } - - // If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything. - if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { - continue - } - rss = append(rss, rs) - } - - if len(rss) == 0 { - return nil, fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) - } - - return rss, nil -} diff --git a/pkg/client/listers/imagepolicy/internalversion/BUILD b/pkg/client/listers/imagepolicy/internalversion/BUILD deleted file mode 100644 index ae80fe6c2e37f..0000000000000 --- a/pkg/client/listers/imagepolicy/internalversion/BUILD +++ /dev/null @@ -1,34 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "imagereview.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/imagepolicy/internalversion", - deps = [ - "//pkg/apis/imagepolicy:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/imagepolicy/internalversion/expansion_generated.go b/pkg/client/listers/imagepolicy/internalversion/expansion_generated.go deleted file mode 100644 index 95bf10fab2e43..0000000000000 --- a/pkg/client/listers/imagepolicy/internalversion/expansion_generated.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// ImageReviewListerExpansion allows custom methods to be added to -// ImageReviewLister. -type ImageReviewListerExpansion interface{} diff --git a/pkg/client/listers/imagepolicy/internalversion/imagereview.go b/pkg/client/listers/imagepolicy/internalversion/imagereview.go deleted file mode 100644 index c2dbfe1b90754..0000000000000 --- a/pkg/client/listers/imagepolicy/internalversion/imagereview.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - imagepolicy "k8s.io/kubernetes/pkg/apis/imagepolicy" -) - -// ImageReviewLister helps list ImageReviews. -type ImageReviewLister interface { - // List lists all ImageReviews in the indexer. - List(selector labels.Selector) (ret []*imagepolicy.ImageReview, err error) - // Get retrieves the ImageReview from the index for a given name. - Get(name string) (*imagepolicy.ImageReview, error) - ImageReviewListerExpansion -} - -// imageReviewLister implements the ImageReviewLister interface. -type imageReviewLister struct { - indexer cache.Indexer -} - -// NewImageReviewLister returns a new ImageReviewLister. -func NewImageReviewLister(indexer cache.Indexer) ImageReviewLister { - return &imageReviewLister{indexer: indexer} -} - -// List lists all ImageReviews in the indexer. -func (s *imageReviewLister) List(selector labels.Selector) (ret []*imagepolicy.ImageReview, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*imagepolicy.ImageReview)) - }) - return ret, err -} - -// Get retrieves the ImageReview from the index for a given name. -func (s *imageReviewLister) Get(name string) (*imagepolicy.ImageReview, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(imagepolicy.Resource("imagereview"), name) - } - return obj.(*imagepolicy.ImageReview), nil -} diff --git a/pkg/client/listers/networking/internalversion/BUILD b/pkg/client/listers/networking/internalversion/BUILD deleted file mode 100644 index 32f3dbb598cf6..0000000000000 --- a/pkg/client/listers/networking/internalversion/BUILD +++ /dev/null @@ -1,34 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "networkpolicy.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/networking/internalversion", - deps = [ - "//pkg/apis/networking:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/networking/internalversion/expansion_generated.go b/pkg/client/listers/networking/internalversion/expansion_generated.go deleted file mode 100644 index 0f3b48a7dce04..0000000000000 --- a/pkg/client/listers/networking/internalversion/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// NetworkPolicyListerExpansion allows custom methods to be added to -// NetworkPolicyLister. -type NetworkPolicyListerExpansion interface{} - -// NetworkPolicyNamespaceListerExpansion allows custom methods to be added to -// NetworkPolicyNamespaceLister. -type NetworkPolicyNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/networking/internalversion/networkpolicy.go b/pkg/client/listers/networking/internalversion/networkpolicy.go deleted file mode 100644 index bfde8db6ab088..0000000000000 --- a/pkg/client/listers/networking/internalversion/networkpolicy.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - networking "k8s.io/kubernetes/pkg/apis/networking" -) - -// NetworkPolicyLister helps list NetworkPolicies. -type NetworkPolicyLister interface { - // List lists all NetworkPolicies in the indexer. - List(selector labels.Selector) (ret []*networking.NetworkPolicy, err error) - // NetworkPolicies returns an object that can list and get NetworkPolicies. - NetworkPolicies(namespace string) NetworkPolicyNamespaceLister - NetworkPolicyListerExpansion -} - -// networkPolicyLister implements the NetworkPolicyLister interface. -type networkPolicyLister struct { - indexer cache.Indexer -} - -// NewNetworkPolicyLister returns a new NetworkPolicyLister. -func NewNetworkPolicyLister(indexer cache.Indexer) NetworkPolicyLister { - return &networkPolicyLister{indexer: indexer} -} - -// List lists all NetworkPolicies in the indexer. -func (s *networkPolicyLister) List(selector labels.Selector) (ret []*networking.NetworkPolicy, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*networking.NetworkPolicy)) - }) - return ret, err -} - -// NetworkPolicies returns an object that can list and get NetworkPolicies. -func (s *networkPolicyLister) NetworkPolicies(namespace string) NetworkPolicyNamespaceLister { - return networkPolicyNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// NetworkPolicyNamespaceLister helps list and get NetworkPolicies. -type NetworkPolicyNamespaceLister interface { - // List lists all NetworkPolicies in the indexer for a given namespace. - List(selector labels.Selector) (ret []*networking.NetworkPolicy, err error) - // Get retrieves the NetworkPolicy from the indexer for a given namespace and name. - Get(name string) (*networking.NetworkPolicy, error) - NetworkPolicyNamespaceListerExpansion -} - -// networkPolicyNamespaceLister implements the NetworkPolicyNamespaceLister -// interface. -type networkPolicyNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all NetworkPolicies in the indexer for a given namespace. -func (s networkPolicyNamespaceLister) List(selector labels.Selector) (ret []*networking.NetworkPolicy, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*networking.NetworkPolicy)) - }) - return ret, err -} - -// Get retrieves the NetworkPolicy from the indexer for a given namespace and name. -func (s networkPolicyNamespaceLister) Get(name string) (*networking.NetworkPolicy, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(networking.Resource("networkpolicy"), name) - } - return obj.(*networking.NetworkPolicy), nil -} diff --git a/pkg/client/listers/policy/internalversion/BUILD b/pkg/client/listers/policy/internalversion/BUILD deleted file mode 100644 index 300ae5af2cfff..0000000000000 --- a/pkg/client/listers/policy/internalversion/BUILD +++ /dev/null @@ -1,40 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "eviction.go", - "expansion_generated.go", - "poddisruptionbudget.go", - "poddisruptionbudget_expansion.go", - "podsecuritypolicy.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/policy/internalversion", - deps = [ - "//pkg/apis/core:go_default_library", - "//pkg/apis/policy: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/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache:go_default_library", - "//vendor/github.com/golang/glog: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/pkg/client/listers/policy/internalversion/eviction.go b/pkg/client/listers/policy/internalversion/eviction.go deleted file mode 100644 index 29acba5d8dfa3..0000000000000 --- a/pkg/client/listers/policy/internalversion/eviction.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - policy "k8s.io/kubernetes/pkg/apis/policy" -) - -// EvictionLister helps list Evictions. -type EvictionLister interface { - // List lists all Evictions in the indexer. - List(selector labels.Selector) (ret []*policy.Eviction, err error) - // Evictions returns an object that can list and get Evictions. - Evictions(namespace string) EvictionNamespaceLister - EvictionListerExpansion -} - -// evictionLister implements the EvictionLister interface. -type evictionLister struct { - indexer cache.Indexer -} - -// NewEvictionLister returns a new EvictionLister. -func NewEvictionLister(indexer cache.Indexer) EvictionLister { - return &evictionLister{indexer: indexer} -} - -// List lists all Evictions in the indexer. -func (s *evictionLister) List(selector labels.Selector) (ret []*policy.Eviction, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*policy.Eviction)) - }) - return ret, err -} - -// Evictions returns an object that can list and get Evictions. -func (s *evictionLister) Evictions(namespace string) EvictionNamespaceLister { - return evictionNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// EvictionNamespaceLister helps list and get Evictions. -type EvictionNamespaceLister interface { - // List lists all Evictions in the indexer for a given namespace. - List(selector labels.Selector) (ret []*policy.Eviction, err error) - // Get retrieves the Eviction from the indexer for a given namespace and name. - Get(name string) (*policy.Eviction, error) - EvictionNamespaceListerExpansion -} - -// evictionNamespaceLister implements the EvictionNamespaceLister -// interface. -type evictionNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Evictions in the indexer for a given namespace. -func (s evictionNamespaceLister) List(selector labels.Selector) (ret []*policy.Eviction, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*policy.Eviction)) - }) - return ret, err -} - -// Get retrieves the Eviction from the indexer for a given namespace and name. -func (s evictionNamespaceLister) Get(name string) (*policy.Eviction, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(policy.Resource("eviction"), name) - } - return obj.(*policy.Eviction), nil -} diff --git a/pkg/client/listers/policy/internalversion/expansion_generated.go b/pkg/client/listers/policy/internalversion/expansion_generated.go deleted file mode 100644 index 663d240e6858d..0000000000000 --- a/pkg/client/listers/policy/internalversion/expansion_generated.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// EvictionListerExpansion allows custom methods to be added to -// EvictionLister. -type EvictionListerExpansion interface{} - -// EvictionNamespaceListerExpansion allows custom methods to be added to -// EvictionNamespaceLister. -type EvictionNamespaceListerExpansion interface{} - -// PodSecurityPolicyListerExpansion allows custom methods to be added to -// PodSecurityPolicyLister. -type PodSecurityPolicyListerExpansion interface{} diff --git a/pkg/client/listers/policy/internalversion/poddisruptionbudget.go b/pkg/client/listers/policy/internalversion/poddisruptionbudget.go deleted file mode 100644 index 1549f8a93a357..0000000000000 --- a/pkg/client/listers/policy/internalversion/poddisruptionbudget.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - policy "k8s.io/kubernetes/pkg/apis/policy" -) - -// PodDisruptionBudgetLister helps list PodDisruptionBudgets. -type PodDisruptionBudgetLister interface { - // List lists all PodDisruptionBudgets in the indexer. - List(selector labels.Selector) (ret []*policy.PodDisruptionBudget, err error) - // PodDisruptionBudgets returns an object that can list and get PodDisruptionBudgets. - PodDisruptionBudgets(namespace string) PodDisruptionBudgetNamespaceLister - PodDisruptionBudgetListerExpansion -} - -// podDisruptionBudgetLister implements the PodDisruptionBudgetLister interface. -type podDisruptionBudgetLister struct { - indexer cache.Indexer -} - -// NewPodDisruptionBudgetLister returns a new PodDisruptionBudgetLister. -func NewPodDisruptionBudgetLister(indexer cache.Indexer) PodDisruptionBudgetLister { - return &podDisruptionBudgetLister{indexer: indexer} -} - -// List lists all PodDisruptionBudgets in the indexer. -func (s *podDisruptionBudgetLister) List(selector labels.Selector) (ret []*policy.PodDisruptionBudget, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*policy.PodDisruptionBudget)) - }) - return ret, err -} - -// PodDisruptionBudgets returns an object that can list and get PodDisruptionBudgets. -func (s *podDisruptionBudgetLister) PodDisruptionBudgets(namespace string) PodDisruptionBudgetNamespaceLister { - return podDisruptionBudgetNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// PodDisruptionBudgetNamespaceLister helps list and get PodDisruptionBudgets. -type PodDisruptionBudgetNamespaceLister interface { - // List lists all PodDisruptionBudgets in the indexer for a given namespace. - List(selector labels.Selector) (ret []*policy.PodDisruptionBudget, err error) - // Get retrieves the PodDisruptionBudget from the indexer for a given namespace and name. - Get(name string) (*policy.PodDisruptionBudget, error) - PodDisruptionBudgetNamespaceListerExpansion -} - -// podDisruptionBudgetNamespaceLister implements the PodDisruptionBudgetNamespaceLister -// interface. -type podDisruptionBudgetNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all PodDisruptionBudgets in the indexer for a given namespace. -func (s podDisruptionBudgetNamespaceLister) List(selector labels.Selector) (ret []*policy.PodDisruptionBudget, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*policy.PodDisruptionBudget)) - }) - return ret, err -} - -// Get retrieves the PodDisruptionBudget from the indexer for a given namespace and name. -func (s podDisruptionBudgetNamespaceLister) Get(name string) (*policy.PodDisruptionBudget, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(policy.Resource("poddisruptionbudget"), name) - } - return obj.(*policy.PodDisruptionBudget), nil -} diff --git a/pkg/client/listers/policy/internalversion/poddisruptionbudget_expansion.go b/pkg/client/listers/policy/internalversion/poddisruptionbudget_expansion.go deleted file mode 100644 index fcbc88bc8d072..0000000000000 --- a/pkg/client/listers/policy/internalversion/poddisruptionbudget_expansion.go +++ /dev/null @@ -1,74 +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 internalversion - -import ( - "fmt" - - "github.com/golang/glog" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/policy" -) - -// PodDisruptionBudgetListerExpansion allows custom methods to be added to -// PodDisruptionBudgetLister. -type PodDisruptionBudgetListerExpansion interface { - GetPodPodDisruptionBudgets(pod *api.Pod) ([]*policy.PodDisruptionBudget, error) -} - -// PodDisruptionBudgetNamespaceListerExpansion allows custom methods to be added to -// PodDisruptionBudgetNamespaceLister. -type PodDisruptionBudgetNamespaceListerExpansion interface{} - -// GetPodPodDisruptionBudgets returns a list of PodDisruptionBudgets matching a pod. Returns an error only if no matching PodDisruptionBudgets are found. -func (s *podDisruptionBudgetLister) GetPodPodDisruptionBudgets(pod *api.Pod) ([]*policy.PodDisruptionBudget, error) { - var selector labels.Selector - - if len(pod.Labels) == 0 { - return nil, fmt.Errorf("no PodDisruptionBudgets found for pod %v because it has no labels", pod.Name) - } - - list, err := s.PodDisruptionBudgets(pod.Namespace).List(labels.Everything()) - if err != nil { - return nil, err - } - - var pdbList []*policy.PodDisruptionBudget - for i := range list { - pdb := list[i] - selector, err = metav1.LabelSelectorAsSelector(pdb.Spec.Selector) - if err != nil { - glog.Warningf("invalid selector: %v", err) - // TODO(mml): add an event to the PDB - continue - } - - // If a PDB with a nil or empty selector creeps in, it should match nothing, not everything. - if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { - continue - } - pdbList = append(pdbList, pdb) - } - - if len(pdbList) == 0 { - return nil, fmt.Errorf("could not find PodDisruptionBudget for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) - } - - return pdbList, nil -} diff --git a/pkg/client/listers/policy/internalversion/podsecuritypolicy.go b/pkg/client/listers/policy/internalversion/podsecuritypolicy.go deleted file mode 100644 index f1464f78bb7d3..0000000000000 --- a/pkg/client/listers/policy/internalversion/podsecuritypolicy.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - policy "k8s.io/kubernetes/pkg/apis/policy" -) - -// PodSecurityPolicyLister helps list PodSecurityPolicies. -type PodSecurityPolicyLister interface { - // List lists all PodSecurityPolicies in the indexer. - List(selector labels.Selector) (ret []*policy.PodSecurityPolicy, err error) - // Get retrieves the PodSecurityPolicy from the index for a given name. - Get(name string) (*policy.PodSecurityPolicy, error) - PodSecurityPolicyListerExpansion -} - -// podSecurityPolicyLister implements the PodSecurityPolicyLister interface. -type podSecurityPolicyLister struct { - indexer cache.Indexer -} - -// NewPodSecurityPolicyLister returns a new PodSecurityPolicyLister. -func NewPodSecurityPolicyLister(indexer cache.Indexer) PodSecurityPolicyLister { - return &podSecurityPolicyLister{indexer: indexer} -} - -// List lists all PodSecurityPolicies in the indexer. -func (s *podSecurityPolicyLister) List(selector labels.Selector) (ret []*policy.PodSecurityPolicy, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*policy.PodSecurityPolicy)) - }) - return ret, err -} - -// Get retrieves the PodSecurityPolicy from the index for a given name. -func (s *podSecurityPolicyLister) Get(name string) (*policy.PodSecurityPolicy, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(policy.Resource("podsecuritypolicy"), name) - } - return obj.(*policy.PodSecurityPolicy), nil -} diff --git a/pkg/client/listers/rbac/internalversion/BUILD b/pkg/client/listers/rbac/internalversion/BUILD deleted file mode 100644 index 8b77d6ef6a56c..0000000000000 --- a/pkg/client/listers/rbac/internalversion/BUILD +++ /dev/null @@ -1,37 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "clusterrole.go", - "clusterrolebinding.go", - "expansion_generated.go", - "role.go", - "rolebinding.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/rbac/internalversion", - deps = [ - "//pkg/apis/rbac:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/rbac/internalversion/clusterrole.go b/pkg/client/listers/rbac/internalversion/clusterrole.go deleted file mode 100644 index 36288ec37a2a4..0000000000000 --- a/pkg/client/listers/rbac/internalversion/clusterrole.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - rbac "k8s.io/kubernetes/pkg/apis/rbac" -) - -// ClusterRoleLister helps list ClusterRoles. -type ClusterRoleLister interface { - // List lists all ClusterRoles in the indexer. - List(selector labels.Selector) (ret []*rbac.ClusterRole, err error) - // Get retrieves the ClusterRole from the index for a given name. - Get(name string) (*rbac.ClusterRole, error) - ClusterRoleListerExpansion -} - -// clusterRoleLister implements the ClusterRoleLister interface. -type clusterRoleLister struct { - indexer cache.Indexer -} - -// NewClusterRoleLister returns a new ClusterRoleLister. -func NewClusterRoleLister(indexer cache.Indexer) ClusterRoleLister { - return &clusterRoleLister{indexer: indexer} -} - -// List lists all ClusterRoles in the indexer. -func (s *clusterRoleLister) List(selector labels.Selector) (ret []*rbac.ClusterRole, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*rbac.ClusterRole)) - }) - return ret, err -} - -// Get retrieves the ClusterRole from the index for a given name. -func (s *clusterRoleLister) Get(name string) (*rbac.ClusterRole, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(rbac.Resource("clusterrole"), name) - } - return obj.(*rbac.ClusterRole), nil -} diff --git a/pkg/client/listers/rbac/internalversion/clusterrolebinding.go b/pkg/client/listers/rbac/internalversion/clusterrolebinding.go deleted file mode 100644 index d2bc6eabdaf83..0000000000000 --- a/pkg/client/listers/rbac/internalversion/clusterrolebinding.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - rbac "k8s.io/kubernetes/pkg/apis/rbac" -) - -// ClusterRoleBindingLister helps list ClusterRoleBindings. -type ClusterRoleBindingLister interface { - // List lists all ClusterRoleBindings in the indexer. - List(selector labels.Selector) (ret []*rbac.ClusterRoleBinding, err error) - // Get retrieves the ClusterRoleBinding from the index for a given name. - Get(name string) (*rbac.ClusterRoleBinding, error) - ClusterRoleBindingListerExpansion -} - -// clusterRoleBindingLister implements the ClusterRoleBindingLister interface. -type clusterRoleBindingLister struct { - indexer cache.Indexer -} - -// NewClusterRoleBindingLister returns a new ClusterRoleBindingLister. -func NewClusterRoleBindingLister(indexer cache.Indexer) ClusterRoleBindingLister { - return &clusterRoleBindingLister{indexer: indexer} -} - -// List lists all ClusterRoleBindings in the indexer. -func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*rbac.ClusterRoleBinding, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*rbac.ClusterRoleBinding)) - }) - return ret, err -} - -// Get retrieves the ClusterRoleBinding from the index for a given name. -func (s *clusterRoleBindingLister) Get(name string) (*rbac.ClusterRoleBinding, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(rbac.Resource("clusterrolebinding"), name) - } - return obj.(*rbac.ClusterRoleBinding), nil -} diff --git a/pkg/client/listers/rbac/internalversion/expansion_generated.go b/pkg/client/listers/rbac/internalversion/expansion_generated.go deleted file mode 100644 index e0b20a5b80398..0000000000000 --- a/pkg/client/listers/rbac/internalversion/expansion_generated.go +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// ClusterRoleListerExpansion allows custom methods to be added to -// ClusterRoleLister. -type ClusterRoleListerExpansion interface{} - -// ClusterRoleBindingListerExpansion allows custom methods to be added to -// ClusterRoleBindingLister. -type ClusterRoleBindingListerExpansion interface{} - -// RoleListerExpansion allows custom methods to be added to -// RoleLister. -type RoleListerExpansion interface{} - -// RoleNamespaceListerExpansion allows custom methods to be added to -// RoleNamespaceLister. -type RoleNamespaceListerExpansion interface{} - -// RoleBindingListerExpansion allows custom methods to be added to -// RoleBindingLister. -type RoleBindingListerExpansion interface{} - -// RoleBindingNamespaceListerExpansion allows custom methods to be added to -// RoleBindingNamespaceLister. -type RoleBindingNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/rbac/internalversion/role.go b/pkg/client/listers/rbac/internalversion/role.go deleted file mode 100644 index 2eb554d53a28a..0000000000000 --- a/pkg/client/listers/rbac/internalversion/role.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - rbac "k8s.io/kubernetes/pkg/apis/rbac" -) - -// RoleLister helps list Roles. -type RoleLister interface { - // List lists all Roles in the indexer. - List(selector labels.Selector) (ret []*rbac.Role, err error) - // Roles returns an object that can list and get Roles. - Roles(namespace string) RoleNamespaceLister - RoleListerExpansion -} - -// roleLister implements the RoleLister interface. -type roleLister struct { - indexer cache.Indexer -} - -// NewRoleLister returns a new RoleLister. -func NewRoleLister(indexer cache.Indexer) RoleLister { - return &roleLister{indexer: indexer} -} - -// List lists all Roles in the indexer. -func (s *roleLister) List(selector labels.Selector) (ret []*rbac.Role, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*rbac.Role)) - }) - return ret, err -} - -// Roles returns an object that can list and get Roles. -func (s *roleLister) Roles(namespace string) RoleNamespaceLister { - return roleNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// RoleNamespaceLister helps list and get Roles. -type RoleNamespaceLister interface { - // List lists all Roles in the indexer for a given namespace. - List(selector labels.Selector) (ret []*rbac.Role, err error) - // Get retrieves the Role from the indexer for a given namespace and name. - Get(name string) (*rbac.Role, error) - RoleNamespaceListerExpansion -} - -// roleNamespaceLister implements the RoleNamespaceLister -// interface. -type roleNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Roles in the indexer for a given namespace. -func (s roleNamespaceLister) List(selector labels.Selector) (ret []*rbac.Role, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*rbac.Role)) - }) - return ret, err -} - -// Get retrieves the Role from the indexer for a given namespace and name. -func (s roleNamespaceLister) Get(name string) (*rbac.Role, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(rbac.Resource("role"), name) - } - return obj.(*rbac.Role), nil -} diff --git a/pkg/client/listers/rbac/internalversion/rolebinding.go b/pkg/client/listers/rbac/internalversion/rolebinding.go deleted file mode 100644 index 00cd2e24e6df8..0000000000000 --- a/pkg/client/listers/rbac/internalversion/rolebinding.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - rbac "k8s.io/kubernetes/pkg/apis/rbac" -) - -// RoleBindingLister helps list RoleBindings. -type RoleBindingLister interface { - // List lists all RoleBindings in the indexer. - List(selector labels.Selector) (ret []*rbac.RoleBinding, err error) - // RoleBindings returns an object that can list and get RoleBindings. - RoleBindings(namespace string) RoleBindingNamespaceLister - RoleBindingListerExpansion -} - -// roleBindingLister implements the RoleBindingLister interface. -type roleBindingLister struct { - indexer cache.Indexer -} - -// NewRoleBindingLister returns a new RoleBindingLister. -func NewRoleBindingLister(indexer cache.Indexer) RoleBindingLister { - return &roleBindingLister{indexer: indexer} -} - -// List lists all RoleBindings in the indexer. -func (s *roleBindingLister) List(selector labels.Selector) (ret []*rbac.RoleBinding, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*rbac.RoleBinding)) - }) - return ret, err -} - -// RoleBindings returns an object that can list and get RoleBindings. -func (s *roleBindingLister) RoleBindings(namespace string) RoleBindingNamespaceLister { - return roleBindingNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// RoleBindingNamespaceLister helps list and get RoleBindings. -type RoleBindingNamespaceLister interface { - // List lists all RoleBindings in the indexer for a given namespace. - List(selector labels.Selector) (ret []*rbac.RoleBinding, err error) - // Get retrieves the RoleBinding from the indexer for a given namespace and name. - Get(name string) (*rbac.RoleBinding, error) - RoleBindingNamespaceListerExpansion -} - -// roleBindingNamespaceLister implements the RoleBindingNamespaceLister -// interface. -type roleBindingNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all RoleBindings in the indexer for a given namespace. -func (s roleBindingNamespaceLister) List(selector labels.Selector) (ret []*rbac.RoleBinding, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*rbac.RoleBinding)) - }) - return ret, err -} - -// Get retrieves the RoleBinding from the indexer for a given namespace and name. -func (s roleBindingNamespaceLister) Get(name string) (*rbac.RoleBinding, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(rbac.Resource("rolebinding"), name) - } - return obj.(*rbac.RoleBinding), nil -} diff --git a/pkg/client/listers/scheduling/internalversion/BUILD b/pkg/client/listers/scheduling/internalversion/BUILD deleted file mode 100644 index 6bdfb1eb22523..0000000000000 --- a/pkg/client/listers/scheduling/internalversion/BUILD +++ /dev/null @@ -1,34 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "priorityclass.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/scheduling/internalversion", - deps = [ - "//pkg/apis/scheduling:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/scheduling/internalversion/expansion_generated.go b/pkg/client/listers/scheduling/internalversion/expansion_generated.go deleted file mode 100644 index a0828e84bec5e..0000000000000 --- a/pkg/client/listers/scheduling/internalversion/expansion_generated.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// PriorityClassListerExpansion allows custom methods to be added to -// PriorityClassLister. -type PriorityClassListerExpansion interface{} diff --git a/pkg/client/listers/scheduling/internalversion/priorityclass.go b/pkg/client/listers/scheduling/internalversion/priorityclass.go deleted file mode 100644 index b7d30c7da6a5a..0000000000000 --- a/pkg/client/listers/scheduling/internalversion/priorityclass.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - scheduling "k8s.io/kubernetes/pkg/apis/scheduling" -) - -// PriorityClassLister helps list PriorityClasses. -type PriorityClassLister interface { - // List lists all PriorityClasses in the indexer. - List(selector labels.Selector) (ret []*scheduling.PriorityClass, err error) - // Get retrieves the PriorityClass from the index for a given name. - Get(name string) (*scheduling.PriorityClass, error) - PriorityClassListerExpansion -} - -// priorityClassLister implements the PriorityClassLister interface. -type priorityClassLister struct { - indexer cache.Indexer -} - -// NewPriorityClassLister returns a new PriorityClassLister. -func NewPriorityClassLister(indexer cache.Indexer) PriorityClassLister { - return &priorityClassLister{indexer: indexer} -} - -// List lists all PriorityClasses in the indexer. -func (s *priorityClassLister) List(selector labels.Selector) (ret []*scheduling.PriorityClass, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*scheduling.PriorityClass)) - }) - return ret, err -} - -// Get retrieves the PriorityClass from the index for a given name. -func (s *priorityClassLister) Get(name string) (*scheduling.PriorityClass, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(scheduling.Resource("priorityclass"), name) - } - return obj.(*scheduling.PriorityClass), nil -} diff --git a/pkg/client/listers/settings/internalversion/BUILD b/pkg/client/listers/settings/internalversion/BUILD deleted file mode 100644 index 5206f0941e6ea..0000000000000 --- a/pkg/client/listers/settings/internalversion/BUILD +++ /dev/null @@ -1,34 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "podpreset.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/settings/internalversion", - deps = [ - "//pkg/apis/settings:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/settings/internalversion/expansion_generated.go b/pkg/client/listers/settings/internalversion/expansion_generated.go deleted file mode 100644 index 3346f5213f2f7..0000000000000 --- a/pkg/client/listers/settings/internalversion/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// PodPresetListerExpansion allows custom methods to be added to -// PodPresetLister. -type PodPresetListerExpansion interface{} - -// PodPresetNamespaceListerExpansion allows custom methods to be added to -// PodPresetNamespaceLister. -type PodPresetNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/settings/internalversion/podpreset.go b/pkg/client/listers/settings/internalversion/podpreset.go deleted file mode 100644 index 4ca09ad194c6a..0000000000000 --- a/pkg/client/listers/settings/internalversion/podpreset.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - settings "k8s.io/kubernetes/pkg/apis/settings" -) - -// PodPresetLister helps list PodPresets. -type PodPresetLister interface { - // List lists all PodPresets in the indexer. - List(selector labels.Selector) (ret []*settings.PodPreset, err error) - // PodPresets returns an object that can list and get PodPresets. - PodPresets(namespace string) PodPresetNamespaceLister - PodPresetListerExpansion -} - -// podPresetLister implements the PodPresetLister interface. -type podPresetLister struct { - indexer cache.Indexer -} - -// NewPodPresetLister returns a new PodPresetLister. -func NewPodPresetLister(indexer cache.Indexer) PodPresetLister { - return &podPresetLister{indexer: indexer} -} - -// List lists all PodPresets in the indexer. -func (s *podPresetLister) List(selector labels.Selector) (ret []*settings.PodPreset, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*settings.PodPreset)) - }) - return ret, err -} - -// PodPresets returns an object that can list and get PodPresets. -func (s *podPresetLister) PodPresets(namespace string) PodPresetNamespaceLister { - return podPresetNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// PodPresetNamespaceLister helps list and get PodPresets. -type PodPresetNamespaceLister interface { - // List lists all PodPresets in the indexer for a given namespace. - List(selector labels.Selector) (ret []*settings.PodPreset, err error) - // Get retrieves the PodPreset from the indexer for a given namespace and name. - Get(name string) (*settings.PodPreset, error) - PodPresetNamespaceListerExpansion -} - -// podPresetNamespaceLister implements the PodPresetNamespaceLister -// interface. -type podPresetNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all PodPresets in the indexer for a given namespace. -func (s podPresetNamespaceLister) List(selector labels.Selector) (ret []*settings.PodPreset, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*settings.PodPreset)) - }) - return ret, err -} - -// Get retrieves the PodPreset from the indexer for a given namespace and name. -func (s podPresetNamespaceLister) Get(name string) (*settings.PodPreset, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(settings.Resource("podpreset"), name) - } - return obj.(*settings.PodPreset), nil -} diff --git a/pkg/client/listers/storage/internalversion/BUILD b/pkg/client/listers/storage/internalversion/BUILD deleted file mode 100644 index f9ca0821b7607..0000000000000 --- a/pkg/client/listers/storage/internalversion/BUILD +++ /dev/null @@ -1,35 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "expansion_generated.go", - "storageclass.go", - "volumeattachment.go", - ], - importpath = "k8s.io/kubernetes/pkg/client/listers/storage/internalversion", - deps = [ - "//pkg/apis/storage:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", - "//staging/src/k8s.io/client-go/tools/cache: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/pkg/client/listers/storage/internalversion/expansion_generated.go b/pkg/client/listers/storage/internalversion/expansion_generated.go deleted file mode 100644 index 4a38620de99c5..0000000000000 --- a/pkg/client/listers/storage/internalversion/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -// StorageClassListerExpansion allows custom methods to be added to -// StorageClassLister. -type StorageClassListerExpansion interface{} - -// VolumeAttachmentListerExpansion allows custom methods to be added to -// VolumeAttachmentLister. -type VolumeAttachmentListerExpansion interface{} diff --git a/pkg/client/listers/storage/internalversion/storageclass.go b/pkg/client/listers/storage/internalversion/storageclass.go deleted file mode 100644 index f60d04097d918..0000000000000 --- a/pkg/client/listers/storage/internalversion/storageclass.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - storage "k8s.io/kubernetes/pkg/apis/storage" -) - -// StorageClassLister helps list StorageClasses. -type StorageClassLister interface { - // List lists all StorageClasses in the indexer. - List(selector labels.Selector) (ret []*storage.StorageClass, err error) - // Get retrieves the StorageClass from the index for a given name. - Get(name string) (*storage.StorageClass, error) - StorageClassListerExpansion -} - -// storageClassLister implements the StorageClassLister interface. -type storageClassLister struct { - indexer cache.Indexer -} - -// NewStorageClassLister returns a new StorageClassLister. -func NewStorageClassLister(indexer cache.Indexer) StorageClassLister { - return &storageClassLister{indexer: indexer} -} - -// List lists all StorageClasses in the indexer. -func (s *storageClassLister) List(selector labels.Selector) (ret []*storage.StorageClass, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*storage.StorageClass)) - }) - return ret, err -} - -// Get retrieves the StorageClass from the index for a given name. -func (s *storageClassLister) Get(name string) (*storage.StorageClass, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(storage.Resource("storageclass"), name) - } - return obj.(*storage.StorageClass), nil -} diff --git a/pkg/client/listers/storage/internalversion/volumeattachment.go b/pkg/client/listers/storage/internalversion/volumeattachment.go deleted file mode 100644 index 1f1231f5d18e1..0000000000000 --- a/pkg/client/listers/storage/internalversion/volumeattachment.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package internalversion - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - storage "k8s.io/kubernetes/pkg/apis/storage" -) - -// VolumeAttachmentLister helps list VolumeAttachments. -type VolumeAttachmentLister interface { - // List lists all VolumeAttachments in the indexer. - List(selector labels.Selector) (ret []*storage.VolumeAttachment, err error) - // Get retrieves the VolumeAttachment from the index for a given name. - Get(name string) (*storage.VolumeAttachment, error) - VolumeAttachmentListerExpansion -} - -// volumeAttachmentLister implements the VolumeAttachmentLister interface. -type volumeAttachmentLister struct { - indexer cache.Indexer -} - -// NewVolumeAttachmentLister returns a new VolumeAttachmentLister. -func NewVolumeAttachmentLister(indexer cache.Indexer) VolumeAttachmentLister { - return &volumeAttachmentLister{indexer: indexer} -} - -// List lists all VolumeAttachments in the indexer. -func (s *volumeAttachmentLister) List(selector labels.Selector) (ret []*storage.VolumeAttachment, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*storage.VolumeAttachment)) - }) - return ret, err -} - -// Get retrieves the VolumeAttachment from the index for a given name. -func (s *volumeAttachmentLister) Get(name string) (*storage.VolumeAttachment, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(storage.Resource("volumeattachment"), name) - } - return obj.(*storage.VolumeAttachment), nil -} diff --git a/pkg/cloudprovider/providers/aws/aws.go b/pkg/cloudprovider/providers/aws/aws.go index dbad7cdd75099..b80dff30e51e5 100644 --- a/pkg/cloudprovider/providers/aws/aws.go +++ b/pkg/cloudprovider/providers/aws/aws.go @@ -22,13 +22,12 @@ import ( "fmt" "io" "net" + "path" "strconv" "strings" "sync" "time" - gcfg "gopkg.in/gcfg.v1" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" @@ -44,10 +43,7 @@ import ( "github.com/aws/aws-sdk-go/service/kms" "github.com/aws/aws-sdk-go/service/sts" "github.com/golang/glog" - clientset "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/record" - - "path" + gcfg "gopkg.in/gcfg.v1" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -55,8 +51,10 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" + clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" v1core "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/tools/record" cloudprovider "k8s.io/cloud-provider" "k8s.io/kubernetes/pkg/api/v1/service" "k8s.io/kubernetes/pkg/controller" @@ -1547,11 +1545,6 @@ func (c *Cloud) GetZoneByNodeName(ctx context.Context, nodeName types.NodeName) } -// Abstraction around AWS Instance Types -// There isn't an API to get information for a particular instance type (that I know of) -type awsInstanceType struct { -} - // Used to represent a mount device for attaching an EBS volume // This should be stored as a single letter (i.e. c, not sdc or /dev/sdc) type mountDevice string @@ -1597,13 +1590,6 @@ func newAWSInstance(ec2Service EC2, instance *ec2.Instance) *awsInstance { return self } -// Gets the awsInstanceType that models the instance type of this instance -func (i *awsInstance) getInstanceType() *awsInstanceType { - // TODO: Make this real - awsInstanceType := &awsInstanceType{} - return awsInstanceType -} - // Gets the full information about this instance from the EC2 API func (i *awsInstance) describeInstance() (*ec2.Instance, error) { return describeInstance(i.ec2, awsInstanceID(i.awsID)) @@ -1617,10 +1603,6 @@ func (c *Cloud) getMountDevice( info *ec2.Instance, volumeID EBSVolumeID, assign bool) (assigned mountDevice, alreadyAttached bool, err error) { - instanceType := i.getInstanceType() - if instanceType == nil { - return "", false, fmt.Errorf("could not get instance type for instance: %s", i.awsID) - } deviceMappings := map[mountDevice]EBSVolumeID{} for _, blockDevice := range info.BlockDeviceMappings { @@ -2193,7 +2175,6 @@ func (c *Cloud) CreateDisk(volumeOptions *VolumeOptions) (KubernetesVolumeID, er return "", fmt.Errorf("invalid AWS VolumeType %q", volumeOptions.VolumeType) } - // TODO: Should we tag this with the cluster id (so it gets deleted when the cluster does?) request := &ec2.CreateVolumeInput{} request.AvailabilityZone = aws.String(volumeOptions.AvailabilityZone) request.Size = aws.Int64(int64(volumeOptions.CapacityGB)) @@ -2206,6 +2187,21 @@ func (c *Cloud) CreateDisk(volumeOptions *VolumeOptions) (KubernetesVolumeID, er if iops > 0 { request.Iops = aws.Int64(iops) } + + tags := volumeOptions.Tags + tags = c.tagging.buildTags(ResourceLifecycleOwned, tags) + + var tagList []*ec2.Tag + for k, v := range tags { + tagList = append(tagList, &ec2.Tag{ + Key: aws.String(k), Value: aws.String(v), + }) + } + request.TagSpecifications = append(request.TagSpecifications, &ec2.TagSpecification{ + Tags: tagList, + ResourceType: aws.String(ec2.ResourceTypeVolume), + }) + response, err := c.ec2.CreateVolume(request) if err != nil { return "", err @@ -2217,17 +2213,6 @@ func (c *Cloud) CreateDisk(volumeOptions *VolumeOptions) (KubernetesVolumeID, er } volumeName := KubernetesVolumeID("aws://" + aws.StringValue(response.AvailabilityZone) + "/" + string(awsID)) - // apply tags - if err := c.tagging.createTags(c.ec2, string(awsID), ResourceLifecycleOwned, volumeOptions.Tags); err != nil { - // delete the volume and hope it succeeds - _, delerr := c.DeleteDisk(volumeName) - if delerr != nil { - // delete did not succeed, we have a stray volume! - return "", fmt.Errorf("error tagging volume %s, could not delete the volume: %q", volumeName, delerr) - } - return "", fmt.Errorf("error tagging volume %s: %q", volumeName, err) - } - // AWS has a bad habbit of reporting success when creating a volume with // encryption keys that either don't exists or have wrong permissions. // Such volume lives for couple of seconds and then it's silently deleted diff --git a/pkg/cloudprovider/providers/aws/aws_fakes.go b/pkg/cloudprovider/providers/aws/aws_fakes.go index bc35818d2e9c4..f398ab87cd8f7 100644 --- a/pkg/cloudprovider/providers/aws/aws_fakes.go +++ b/pkg/cloudprovider/providers/aws/aws_fakes.go @@ -25,7 +25,6 @@ import ( "github.com/aws/aws-sdk-go/service/elb" "github.com/aws/aws-sdk-go/service/elbv2" "github.com/aws/aws-sdk-go/service/kms" - "github.com/golang/glog" ) diff --git a/pkg/cloudprovider/providers/aws/aws_loadbalancer.go b/pkg/cloudprovider/providers/aws/aws_loadbalancer.go index 4cc69a439eb84..27d1443304cdd 100644 --- a/pkg/cloudprovider/providers/aws/aws_loadbalancer.go +++ b/pkg/cloudprovider/providers/aws/aws_loadbalancer.go @@ -29,6 +29,7 @@ import ( "github.com/aws/aws-sdk-go/service/elb" "github.com/aws/aws-sdk-go/service/elbv2" "github.com/golang/glog" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" diff --git a/pkg/cloudprovider/providers/aws/aws_loadbalancer_test.go b/pkg/cloudprovider/providers/aws/aws_loadbalancer_test.go index 6141de5ebbd57..9f81ea75cfa19 100644 --- a/pkg/cloudprovider/providers/aws/aws_loadbalancer_test.go +++ b/pkg/cloudprovider/providers/aws/aws_loadbalancer_test.go @@ -17,8 +17,9 @@ limitations under the License. package aws import ( - "github.com/aws/aws-sdk-go/aws" "testing" + + "github.com/aws/aws-sdk-go/aws" ) func TestElbProtocolsAreEqual(t *testing.T) { diff --git a/pkg/cloudprovider/providers/aws/aws_routes.go b/pkg/cloudprovider/providers/aws/aws_routes.go index e332c1513fea9..658f6e898573f 100644 --- a/pkg/cloudprovider/providers/aws/aws_routes.go +++ b/pkg/cloudprovider/providers/aws/aws_routes.go @@ -23,6 +23,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/golang/glog" + cloudprovider "k8s.io/cloud-provider" ) diff --git a/pkg/cloudprovider/providers/aws/aws_test.go b/pkg/cloudprovider/providers/aws/aws_test.go index 72a799357e643..50e303d43d3d5 100644 --- a/pkg/cloudprovider/providers/aws/aws_test.go +++ b/pkg/cloudprovider/providers/aws/aws_test.go @@ -27,14 +27,14 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/elb" - "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/sets" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" ) @@ -68,6 +68,11 @@ func (m *MockedFakeEC2) DescribeSecurityGroups(request *ec2.DescribeSecurityGrou return args.Get(0).([]*ec2.SecurityGroup), nil } +func (m *MockedFakeEC2) CreateVolume(request *ec2.CreateVolumeInput) (*ec2.Volume, error) { + args := m.Called(request) + return args.Get(0).(*ec2.Volume), nil +} + type MockedFakeELB struct { *FakeELB mock.Mock @@ -1393,6 +1398,38 @@ func TestFindSecurityGroupForInstanceMultipleTagged(t *testing.T) { assert.Contains(t, err.Error(), "sg123(another_group)") } +func TestCreateDisk(t *testing.T) { + awsServices := newMockedFakeAWSServices(TestClusterID) + c, _ := newAWSCloud(CloudConfig{}, awsServices) + + volumeOptions := &VolumeOptions{ + AvailabilityZone: "us-east-1a", + CapacityGB: 10, + } + request := &ec2.CreateVolumeInput{ + AvailabilityZone: aws.String("us-east-1a"), + Encrypted: aws.Bool(false), + VolumeType: aws.String(DefaultVolumeType), + Size: aws.Int64(10), + TagSpecifications: []*ec2.TagSpecification{ + {ResourceType: aws.String(ec2.ResourceTypeVolume), Tags: []*ec2.Tag{ + {Key: aws.String(TagNameKubernetesClusterLegacy), Value: aws.String(TestClusterID)}, + {Key: aws.String(fmt.Sprintf("%s%s", TagNameKubernetesClusterPrefix, TestClusterID)), Value: aws.String(ResourceLifecycleOwned)}, + }}, + }, + } + volume := &ec2.Volume{ + AvailabilityZone: aws.String("us-east-1a"), + VolumeId: aws.String("vol-volumeId0"), + } + awsServices.ec2.(*MockedFakeEC2).On("CreateVolume", request).Return(volume, nil) + + volumeID, err := c.CreateDisk(volumeOptions) + assert.Nil(t, err, "Error creating disk: %v", err) + assert.Equal(t, volumeID, KubernetesVolumeID("aws://us-east-1a/vol-volumeId0")) + awsServices.ec2.(*MockedFakeEC2).AssertExpectations(t) +} + func newMockedFakeAWSServices(id string) *FakeAWSServices { s := NewFakeAWSServices(id) s.ec2 = &MockedFakeEC2{FakeEC2Impl: s.ec2.(*FakeEC2Impl)} diff --git a/pkg/cloudprovider/providers/aws/aws_utils.go b/pkg/cloudprovider/providers/aws/aws_utils.go index b56699f854b70..bd373d64e5881 100644 --- a/pkg/cloudprovider/providers/aws/aws_utils.go +++ b/pkg/cloudprovider/providers/aws/aws_utils.go @@ -18,6 +18,7 @@ package aws import ( "github.com/aws/aws-sdk-go/aws" + "k8s.io/apimachinery/pkg/util/sets" ) diff --git a/pkg/cloudprovider/providers/aws/instances.go b/pkg/cloudprovider/providers/aws/instances.go index a42834415dd0f..c0b03a5922cf9 100644 --- a/pkg/cloudprovider/providers/aws/instances.go +++ b/pkg/cloudprovider/providers/aws/instances.go @@ -19,15 +19,16 @@ package aws import ( "fmt" "net/url" + "regexp" "strings" + "sync" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/golang/glog" + "k8s.io/api/core/v1" - "regexp" - "sync" - "time" ) // awsInstanceRegMatch represents Regex Match for AWS instance. diff --git a/pkg/cloudprovider/providers/aws/instances_test.go b/pkg/cloudprovider/providers/aws/instances_test.go index 37b407d74c350..4e6e260d1efd7 100644 --- a/pkg/cloudprovider/providers/aws/instances_test.go +++ b/pkg/cloudprovider/providers/aws/instances_test.go @@ -17,12 +17,14 @@ limitations under the License. package aws import ( + "testing" + "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/stretchr/testify/assert" + "k8s.io/api/core/v1" - "testing" - "time" ) func TestMapToAWSInstanceIDs(t *testing.T) { diff --git a/pkg/cloudprovider/providers/aws/regions.go b/pkg/cloudprovider/providers/aws/regions.go index e97f88fc90f8d..74d64c68de0c4 100644 --- a/pkg/cloudprovider/providers/aws/regions.go +++ b/pkg/cloudprovider/providers/aws/regions.go @@ -17,10 +17,12 @@ limitations under the License. package aws import ( + "sync" + "github.com/golang/glog" + "k8s.io/apimachinery/pkg/util/sets" awscredentialprovider "k8s.io/kubernetes/pkg/credentialprovider/aws" - "sync" ) // wellKnownRegions is the complete list of regions known to the AWS cloudprovider @@ -29,6 +31,7 @@ var wellKnownRegions = [...]string{ // from `aws ec2 describe-regions --region us-east-1 --query Regions[].RegionName | sort` "ap-northeast-1", "ap-northeast-2", + "ap-northeast-3", "ap-south-1", "ap-southeast-1", "ap-southeast-2", @@ -36,6 +39,7 @@ var wellKnownRegions = [...]string{ "eu-central-1", "eu-west-1", "eu-west-2", + "eu-west-3", "sa-east-1", "us-east-1", "us-east-2", @@ -44,6 +48,7 @@ var wellKnownRegions = [...]string{ // these are not registered in many / most accounts "cn-north-1", + "cn-northwest-1", "us-gov-west-1", } diff --git a/pkg/cloudprovider/providers/aws/tags.go b/pkg/cloudprovider/providers/aws/tags.go index 8e44cbb5bd156..5773983c7a304 100644 --- a/pkg/cloudprovider/providers/aws/tags.go +++ b/pkg/cloudprovider/providers/aws/tags.go @@ -18,12 +18,12 @@ package aws import ( "fmt" - "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/golang/glog" + "k8s.io/apimachinery/pkg/util/wait" ) diff --git a/pkg/cloudprovider/providers/aws/tags_test.go b/pkg/cloudprovider/providers/aws/tags_test.go index 1de98a24a4e2b..125f4b2b3fb75 100644 --- a/pkg/cloudprovider/providers/aws/tags_test.go +++ b/pkg/cloudprovider/providers/aws/tags_test.go @@ -17,9 +17,10 @@ limitations under the License. package aws import ( + "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "testing" ) func TestFilterTags(t *testing.T) { diff --git a/pkg/cloudprovider/providers/aws/volumes.go b/pkg/cloudprovider/providers/aws/volumes.go index 4a082528f9d40..d7c046c5cd05e 100644 --- a/pkg/cloudprovider/providers/aws/volumes.go +++ b/pkg/cloudprovider/providers/aws/volumes.go @@ -25,6 +25,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/golang/glog" + "k8s.io/apimachinery/pkg/types" ) diff --git a/pkg/cloudprovider/providers/azure/BUILD b/pkg/cloudprovider/providers/azure/BUILD index 6517b058d4bd0..1ead263abda61 100644 --- a/pkg/cloudprovider/providers/azure/BUILD +++ b/pkg/cloudprovider/providers/azure/BUILD @@ -58,7 +58,7 @@ go_library( "//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library", "//staging/src/k8s.io/cloud-provider:go_default_library", - "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute:go_default_library", + "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute:go_default_library", "//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network:go_default_library", "//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage:go_default_library", "//vendor/github.com/Azure/azure-sdk-for-go/storage:go_default_library", @@ -101,7 +101,7 @@ go_test( "//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/cloud-provider:go_default_library", - "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute:go_default_library", + "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute:go_default_library", "//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network:go_default_library", "//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage:go_default_library", "//vendor/github.com/Azure/go-autorest/autorest:go_default_library", diff --git a/pkg/cloudprovider/providers/azure/azure.go b/pkg/cloudprovider/providers/azure/azure.go index c80859926e0ce..01e07593797ca 100644 --- a/pkg/cloudprovider/providers/azure/azure.go +++ b/pkg/cloudprovider/providers/azure/azure.go @@ -159,7 +159,7 @@ type Cloud struct { DisksClient DisksClient FileClient FileClient resourceRequestBackoff wait.Backoff - metadata *InstanceMetadata + metadata *InstanceMetadataService vmSet VMSet // Lock for access to node caches, includes nodeZones, nodeResourceGroups, and unmanagedNodes. @@ -328,7 +328,10 @@ func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) { az.CloudProviderBackoffJitter) } - az.metadata = NewInstanceMetadata() + az.metadata, err = NewInstanceMetadataService(metadataURL) + if err != nil { + return nil, err + } if az.MaximumLoadBalancerRuleCount == 0 { az.MaximumLoadBalancerRuleCount = maximumLoadBalancerRuleCount diff --git a/pkg/cloudprovider/providers/azure/azure_backoff.go b/pkg/cloudprovider/providers/azure/azure_backoff.go index cbdfee6d87e01..ab268d311ea72 100644 --- a/pkg/cloudprovider/providers/azure/azure_backoff.go +++ b/pkg/cloudprovider/providers/azure/azure_backoff.go @@ -21,7 +21,7 @@ import ( "fmt" "net/http" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/golang/glog" diff --git a/pkg/cloudprovider/providers/azure/azure_client.go b/pkg/cloudprovider/providers/azure/azure_client.go index f8abb8fa5d79f..1f1de845b5c40 100644 --- a/pkg/cloudprovider/providers/azure/azure_client.go +++ b/pkg/cloudprovider/providers/azure/azure_client.go @@ -22,7 +22,7 @@ import ( "net/http" "time" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage" "github.com/Azure/go-autorest/autorest" diff --git a/pkg/cloudprovider/providers/azure/azure_controller_common.go b/pkg/cloudprovider/providers/azure/azure_controller_common.go index ef628c24fa4fc..9be915cfc37c4 100644 --- a/pkg/cloudprovider/providers/azure/azure_controller_common.go +++ b/pkg/cloudprovider/providers/azure/azure_controller_common.go @@ -20,7 +20,7 @@ import ( "fmt" "time" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/golang/glog" "k8s.io/apimachinery/pkg/types" diff --git a/pkg/cloudprovider/providers/azure/azure_controller_standard.go b/pkg/cloudprovider/providers/azure/azure_controller_standard.go index 5ac04bbf43728..9c62e2877dfab 100644 --- a/pkg/cloudprovider/providers/azure/azure_controller_standard.go +++ b/pkg/cloudprovider/providers/azure/azure_controller_standard.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/golang/glog" "k8s.io/apimachinery/pkg/types" @@ -73,28 +73,19 @@ func (as *availabilitySet) AttachDisk(isManagedDisk bool, diskName, diskURI stri }, }, } - glog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk", nodeResourceGroup, vmName) + glog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk(%s)", nodeResourceGroup, vmName, diskName) ctx, cancel := getContextWithCancel() defer cancel() - resp, err := as.VirtualMachinesClient.CreateOrUpdate(ctx, nodeResourceGroup, vmName, newVM) - if as.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) { - glog.V(2).Infof("azureDisk - update(%s) backing off: vm(%s)", nodeResourceGroup, vmName) - retryErr := as.CreateOrUpdateVMWithRetry(nodeResourceGroup, vmName, newVM) - if retryErr != nil { - err = retryErr - glog.V(2).Infof("azureDisk - update(%s) abort backoff: vm(%s)", nodeResourceGroup, vmName) - } - } - if err != nil { - glog.Errorf("azureDisk - azure attach failed, err: %v", err) + if _, err := as.VirtualMachinesClient.CreateOrUpdate(ctx, nodeResourceGroup, vmName, newVM); err != nil { + glog.Errorf("azureDisk - attach disk(%s) failed, err: %v", diskName, err) detail := err.Error() if strings.Contains(detail, errLeaseFailed) || strings.Contains(detail, errDiskBlobNotFound) { // if lease cannot be acquired or disk not found, immediately detach the disk and return the original error - glog.Infof("azureDisk - err %s, try detach", detail) + glog.V(2).Infof("azureDisk - err %v, try detach disk(%s)", err, diskName) as.DetachDiskByName(diskName, diskURI, nodeName) } } else { - glog.V(4).Info("azureDisk - azure attach succeeded") + glog.V(2).Infof("azureDisk - attach disk(%s) succeeded", diskName) // Invalidate the cache right after updating as.cloud.vmCache.Delete(vmName) } @@ -124,7 +115,7 @@ func (as *availabilitySet) DetachDiskByName(diskName, diskURI string, nodeName t (disk.Vhd != nil && disk.Vhd.URI != nil && diskURI != "" && *disk.Vhd.URI == diskURI) || (disk.ManagedDisk != nil && diskURI != "" && *disk.ManagedDisk.ID == diskURI) { // found the disk - glog.V(4).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI) + glog.V(2).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI) disks = append(disks[:i], disks[i+1:]...) bFoundDisk = true break @@ -143,22 +134,13 @@ func (as *availabilitySet) DetachDiskByName(diskName, diskURI string, nodeName t }, }, } - glog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk", nodeResourceGroup, vmName) + glog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk(%s)", nodeResourceGroup, vmName, diskName) ctx, cancel := getContextWithCancel() defer cancel() - resp, err := as.VirtualMachinesClient.CreateOrUpdate(ctx, nodeResourceGroup, vmName, newVM) - if as.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) { - glog.V(2).Infof("azureDisk - update(%s) backing off: vm(%s)", nodeResourceGroup, vmName) - retryErr := as.CreateOrUpdateVMWithRetry(nodeResourceGroup, vmName, newVM) - if retryErr != nil { - err = retryErr - glog.V(2).Infof("azureDisk - update(%s) abort backoff: vm(%s)", nodeResourceGroup, vmName) - } - } - if err != nil { - glog.Errorf("azureDisk - azure disk detach failed, err: %v", err) + if _, err := as.VirtualMachinesClient.CreateOrUpdate(ctx, nodeResourceGroup, vmName, newVM); err != nil { + glog.Errorf("azureDisk - detach disk(%s) failed, err: %v", diskName, err) } else { - glog.V(4).Info("azureDisk - azure disk detach succeeded") + glog.V(2).Infof("azureDisk - detach disk(%s) succeeded", diskName) // Invalidate the cache right after updating as.cloud.vmCache.Delete(vmName) } diff --git a/pkg/cloudprovider/providers/azure/azure_controller_vmss.go b/pkg/cloudprovider/providers/azure/azure_controller_vmss.go index b5db5e37ae977..d65b1be47295d 100644 --- a/pkg/cloudprovider/providers/azure/azure_controller_vmss.go +++ b/pkg/cloudprovider/providers/azure/azure_controller_vmss.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/golang/glog" "k8s.io/apimachinery/pkg/types" @@ -71,25 +71,16 @@ func (ss *scaleSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nod ctx, cancel := getContextWithCancel() defer cancel() - glog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk", nodeResourceGroup, nodeName) - resp, err := ss.VirtualMachineScaleSetVMsClient.Update(ctx, nodeResourceGroup, ssName, instanceID, vm) - if ss.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) { - glog.V(2).Infof("azureDisk - update(%s) backing off: vm(%s)", nodeResourceGroup, nodeName) - retryErr := ss.UpdateVmssVMWithRetry(ctx, nodeResourceGroup, ssName, instanceID, vm) - if retryErr != nil { - err = retryErr - glog.V(2).Infof("azureDisk - update(%s) abort backoff: vm(%s)", nodeResourceGroup, nodeName) - } - } - if err != nil { + glog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk(%s)", nodeResourceGroup, nodeName, diskName) + if _, err := ss.VirtualMachineScaleSetVMsClient.Update(ctx, nodeResourceGroup, ssName, instanceID, vm); err != nil { detail := err.Error() if strings.Contains(detail, errLeaseFailed) || strings.Contains(detail, errDiskBlobNotFound) { // if lease cannot be acquired or disk not found, immediately detach the disk and return the original error - glog.Infof("azureDisk - err %s, try detach", detail) + glog.Infof("azureDisk - err %s, try detach disk(%s)", detail, diskName) ss.DetachDiskByName(diskName, diskURI, nodeName) } } else { - glog.V(4).Info("azureDisk - azure attach succeeded") + glog.V(2).Infof("azureDisk - attach disk(%s) succeeded", diskName) // Invalidate the cache right after updating key := buildVmssCacheKey(nodeResourceGroup, ss.makeVmssVMName(ssName, instanceID)) ss.vmssVMCache.Delete(key) @@ -121,7 +112,7 @@ func (ss *scaleSet) DetachDiskByName(diskName, diskURI string, nodeName types.No (disk.Vhd != nil && disk.Vhd.URI != nil && diskURI != "" && *disk.Vhd.URI == diskURI) || (disk.ManagedDisk != nil && diskURI != "" && *disk.ManagedDisk.ID == diskURI) { // found the disk - glog.V(4).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI) + glog.V(2).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI) disks = append(disks[:i], disks[i+1:]...) bFoundDisk = true break @@ -135,20 +126,11 @@ func (ss *scaleSet) DetachDiskByName(diskName, diskURI string, nodeName types.No vm.StorageProfile.DataDisks = &disks ctx, cancel := getContextWithCancel() defer cancel() - glog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk", nodeResourceGroup, nodeName) - resp, err := ss.VirtualMachineScaleSetVMsClient.Update(ctx, nodeResourceGroup, ssName, instanceID, vm) - if ss.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) { - glog.V(2).Infof("azureDisk - update(%s) backing off: vm(%s)", nodeResourceGroup, nodeName) - retryErr := ss.UpdateVmssVMWithRetry(ctx, nodeResourceGroup, ssName, instanceID, vm) - if retryErr != nil { - err = retryErr - glog.V(2).Infof("azureDisk - update(%s) abort backoff: vm(%s)", nodeResourceGroup, nodeName) - } - } - if err != nil { - glog.Errorf("azureDisk - azure disk detach %q from %s failed, err: %v", diskName, nodeName, err) + glog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk(%s)", nodeResourceGroup, nodeName, diskName) + if _, err := ss.VirtualMachineScaleSetVMsClient.Update(ctx, nodeResourceGroup, ssName, instanceID, vm); err != nil { + glog.Errorf("azureDisk - detach disk(%s) from %s failed, err: %v", diskName, nodeName, err) } else { - glog.V(4).Info("azureDisk - azure detach succeeded") + glog.V(2).Infof("azureDisk - detach disk(%s) succeeded", diskName) // Invalidate the cache right after updating key := buildVmssCacheKey(nodeResourceGroup, ss.makeVmssVMName(ssName, instanceID)) ss.vmssVMCache.Delete(key) diff --git a/pkg/cloudprovider/providers/azure/azure_fakes.go b/pkg/cloudprovider/providers/azure/azure_fakes.go index 4cb6a545dc34b..77cc02cb64a5c 100644 --- a/pkg/cloudprovider/providers/azure/azure_fakes.go +++ b/pkg/cloudprovider/providers/azure/azure_fakes.go @@ -29,7 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" cloudprovider "k8s.io/cloud-provider" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage" "github.com/Azure/go-autorest/autorest" diff --git a/pkg/cloudprovider/providers/azure/azure_instance_metadata.go b/pkg/cloudprovider/providers/azure/azure_instance_metadata.go index c9cf6ce1c07ea..5f803b90a3047 100644 --- a/pkg/cloudprovider/providers/azure/azure_instance_metadata.go +++ b/pkg/cloudprovider/providers/azure/azure_instance_metadata.go @@ -18,11 +18,17 @@ package azure import ( "encoding/json" + "fmt" "io/ioutil" "net/http" + "time" ) -const metadataURL = "http://169.254.169.254/metadata/" +const ( + metadataCacheTTL = time.Minute + metadataCacheKey = "InstanceMetadata" + metadataURL = "http://169.254.169.254/metadata/instance" +) // NetworkMetadata contains metadata about an instance's network type NetworkMetadata struct { @@ -54,67 +60,100 @@ type Subnet struct { Prefix string `json:"prefix"` } -// InstanceMetadata knows how to query the Azure instance metadata server. -type InstanceMetadata struct { - baseURL string -} - // ComputeMetadata represents compute information type ComputeMetadata struct { - Name string `json:"name,omitempty"` - Zone string `json:"zone,omitempty"` - VMSize string `json:"vmSize,omitempty"` + SKU string `json:"sku,omitempty"` + Name string `json:"name,omitempty"` + Zone string `json:"zone,omitempty"` + VMSize string `json:"vmSize,omitempty"` + OSType string `json:"osType,omitempty"` + Location string `json:"location,omitempty"` + FaultDomain string `json:"platformFaultDomain,omitempty"` + UpdateDomain string `json:"platformUpdateDomain,omitempty"` + ResourceGroup string `json:"resourceGroupName,omitempty"` + VMScaleSetName string `json:"vmScaleSetName,omitempty"` } -// NewInstanceMetadata creates an instance of the InstanceMetadata accessor object. -func NewInstanceMetadata() *InstanceMetadata { - return &InstanceMetadata{ - baseURL: metadataURL, - } +// InstanceMetadata represents instance information. +type InstanceMetadata struct { + Compute *ComputeMetadata `json:"compute,omitempty"` + Network *NetworkMetadata `json:"network,omitempty"` } -// makeMetadataURL makes a complete metadata URL from the given path. -func (i *InstanceMetadata) makeMetadataURL(path string) string { - return i.baseURL + path +// InstanceMetadataService knows how to query the Azure instance metadata server. +type InstanceMetadataService struct { + metadataURL string + imsCache *timedCache } -// Object queries the metadata server and populates the passed in object -func (i *InstanceMetadata) Object(path string, obj interface{}) error { - data, err := i.queryMetadataBytes(path, "json") - if err != nil { - return err +// NewInstanceMetadataService creates an instance of the InstanceMetadataService accessor object. +func NewInstanceMetadataService(metadataURL string) (*InstanceMetadataService, error) { + ims := &InstanceMetadataService{ + metadataURL: metadataURL, } - return json.Unmarshal(data, obj) -} -// Text queries the metadata server and returns the corresponding text -func (i *InstanceMetadata) Text(path string) (string, error) { - data, err := i.queryMetadataBytes(path, "text") + imsCache, err := newTimedcache(metadataCacheTTL, ims.getInstanceMetadata) if err != nil { - return "", err + return nil, err } - return string(data), err -} -func (i *InstanceMetadata) queryMetadataBytes(path, format string) ([]byte, error) { - client := &http.Client{} + ims.imsCache = imsCache + return ims, nil +} - req, err := http.NewRequest("GET", i.makeMetadataURL(path), nil) +func (ims *InstanceMetadataService) getInstanceMetadata(key string) (interface{}, error) { + req, err := http.NewRequest("GET", ims.metadataURL, nil) if err != nil { return nil, err } req.Header.Add("Metadata", "True") + req.Header.Add("User-Agent", "golang/kubernetes-cloud-provider") q := req.URL.Query() - q.Add("format", format) + q.Add("format", "json") q.Add("api-version", "2017-12-01") req.URL.RawQuery = q.Encode() + client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() - return ioutil.ReadAll(resp.Body) + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failure of getting instance metadata with response %q", resp.Status) + } + + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + obj := InstanceMetadata{} + err = json.Unmarshal(data, &obj) + if err != nil { + return nil, err + } + + return &obj, nil +} + +// GetMetadata gets instance metadata from cache. +func (ims *InstanceMetadataService) GetMetadata() (*InstanceMetadata, error) { + cache, err := ims.imsCache.Get(metadataCacheKey) + if err != nil { + return nil, err + } + + // Cache shouldn't be nil, but added a check incase something wrong. + if cache == nil { + return nil, fmt.Errorf("failure of getting instance metadata") + } + + if metadata, ok := cache.(*InstanceMetadata); ok { + return metadata, nil + } + + return nil, fmt.Errorf("failure of getting instance metadata") } diff --git a/pkg/cloudprovider/providers/azure/azure_instances.go b/pkg/cloudprovider/providers/azure/azure_instances.go index 8a2e589575038..d966b21b3ebfe 100644 --- a/pkg/cloudprovider/providers/azure/azure_instances.go +++ b/pkg/cloudprovider/providers/azure/azure_instances.go @@ -18,6 +18,7 @@ package azure import ( "context" + "fmt" "os" "strings" @@ -67,12 +68,16 @@ func (az *Cloud) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.N } if az.UseInstanceMetadata { - computeMetadata, err := az.getComputeMetadata() + metadata, err := az.metadata.GetMetadata() if err != nil { return nil, err } - isLocalInstance, err := az.isCurrentInstance(name, computeMetadata.Name) + if metadata.Compute == nil || metadata.Network == nil { + return nil, fmt.Errorf("failure of getting instance metadata") + } + + isLocalInstance, err := az.isCurrentInstance(name, metadata.Compute.Name) if err != nil { return nil, err } @@ -82,30 +87,38 @@ func (az *Cloud) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.N return addressGetter(name) } - ipAddress := IPAddress{} - err = az.metadata.Object("instance/network/interface/0/ipv4/ipAddress/0", &ipAddress) - if err != nil { - return nil, err - } - - // Fall back to ARM API if the address is empty string. - // TODO: this is a workaround because IMDS is not stable enough. - // It should be removed after IMDS fixing the issue. - if strings.TrimSpace(ipAddress.PrivateIP) == "" { - return addressGetter(name) + if len(metadata.Network.Interface) == 0 { + return nil, fmt.Errorf("no interface is found for the instance") } // Use ip address got from instance metadata. + ipAddress := metadata.Network.Interface[0] addresses := []v1.NodeAddress{ - {Type: v1.NodeInternalIP, Address: ipAddress.PrivateIP}, {Type: v1.NodeHostName, Address: string(name)}, } - if len(ipAddress.PublicIP) > 0 { - addr := v1.NodeAddress{ - Type: v1.NodeExternalIP, - Address: ipAddress.PublicIP, + for _, address := range ipAddress.IPV4.IPAddress { + addresses = append(addresses, v1.NodeAddress{ + Type: v1.NodeInternalIP, + Address: address.PrivateIP, + }) + if len(address.PublicIP) > 0 { + addresses = append(addresses, v1.NodeAddress{ + Type: v1.NodeExternalIP, + Address: address.PublicIP, + }) + } + } + for _, address := range ipAddress.IPV6.IPAddress { + addresses = append(addresses, v1.NodeAddress{ + Type: v1.NodeInternalIP, + Address: address.PrivateIP, + }) + if len(address.PublicIP) > 0 { + addresses = append(addresses, v1.NodeAddress{ + Type: v1.NodeExternalIP, + Address: address.PublicIP, + }) } - addresses = append(addresses, addr) } return addresses, nil } @@ -172,17 +185,6 @@ func (az *Cloud) InstanceShutdownByProviderID(ctx context.Context, providerID st return strings.ToLower(powerStatus) == vmPowerStateStopped || strings.ToLower(powerStatus) == vmPowerStateDeallocated, nil } -// getComputeMetadata gets compute information from instance metadata. -func (az *Cloud) getComputeMetadata() (*ComputeMetadata, error) { - computeInfo := ComputeMetadata{} - err := az.metadata.Object(computeMetadataURI, &computeInfo) - if err != nil { - return nil, err - } - - return &computeInfo, nil -} - func (az *Cloud) isCurrentInstance(name types.NodeName, metadataVMName string) (bool, error) { var err error nodeName := mapNodeNameToVMName(name) @@ -213,12 +215,16 @@ func (az *Cloud) InstanceID(ctx context.Context, name types.NodeName) (string, e } if az.UseInstanceMetadata { - computeMetadata, err := az.getComputeMetadata() + metadata, err := az.metadata.GetMetadata() if err != nil { return "", err } - isLocalInstance, err := az.isCurrentInstance(name, computeMetadata.Name) + if metadata.Compute == nil { + return "", fmt.Errorf("failure of getting instance metadata") + } + + isLocalInstance, err := az.isCurrentInstance(name, metadata.Compute.Name) if err != nil { return "", err } @@ -229,10 +235,7 @@ func (az *Cloud) InstanceID(ctx context.Context, name types.NodeName) (string, e } // Get resource group name. - resourceGroup, err := az.metadata.Text("instance/compute/resourceGroupName") - if err != nil { - return "", err - } + resourceGroup := metadata.Compute.ResourceGroup // Compose instanceID based on nodeName for standard instance. if az.VMType == vmTypeStandard { @@ -240,7 +243,7 @@ func (az *Cloud) InstanceID(ctx context.Context, name types.NodeName) (string, e } // Get scale set name and instanceID from vmName for vmss. - ssName, instanceID, err := extractVmssVMName(computeMetadata.Name) + ssName, instanceID, err := extractVmssVMName(metadata.Compute.Name) if err != nil { if err == ErrorNotVmssInstance { // Compose machineID for standard Node. @@ -289,18 +292,22 @@ func (az *Cloud) InstanceType(ctx context.Context, name types.NodeName) (string, } if az.UseInstanceMetadata { - computeMetadata, err := az.getComputeMetadata() + metadata, err := az.metadata.GetMetadata() if err != nil { return "", err } - isLocalInstance, err := az.isCurrentInstance(name, computeMetadata.Name) + if metadata.Compute == nil { + return "", fmt.Errorf("failure of getting instance metadata") + } + + isLocalInstance, err := az.isCurrentInstance(name, metadata.Compute.Name) if err != nil { return "", err } if isLocalInstance { - if computeMetadata.VMSize != "" { - return computeMetadata.VMSize, nil + if metadata.Compute.VMSize != "" { + return metadata.Compute.VMSize, nil } } } diff --git a/pkg/cloudprovider/providers/azure/azure_instances_test.go b/pkg/cloudprovider/providers/azure/azure_instances_test.go index 20680b5150ca6..3ae39917c72e9 100644 --- a/pkg/cloudprovider/providers/azure/azure_instances_test.go +++ b/pkg/cloudprovider/providers/azure/azure_instances_test.go @@ -23,7 +23,7 @@ import ( "net/http" "testing" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/go-autorest/autorest/to" "k8s.io/apimachinery/pkg/types" ) @@ -66,7 +66,6 @@ func setTestVirtualMachines(c *Cloud, vmList map[string]string) { func TestInstanceID(t *testing.T) { cloud := getTestCloud() - cloud.metadata = &InstanceMetadata{} testcases := []struct { name string @@ -105,15 +104,18 @@ func TestInstanceID(t *testing.T) { } mux := http.NewServeMux() - mux.Handle("/instance/compute", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, fmt.Sprintf("{\"name\":\"%s\"}", test.metadataName)) + mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, fmt.Sprintf(`{"compute":{"name":"%s"}}`, test.metadataName)) })) go func() { http.Serve(listener, mux) }() defer listener.Close() - cloud.metadata.baseURL = "http://" + listener.Addr().String() + "/" + cloud.metadata, err = NewInstanceMetadataService("http://" + listener.Addr().String() + "/") + if err != nil { + t.Errorf("Test [%s] unexpected error: %v", test.name, err) + } vmListWithPowerState := make(map[string]string) for _, vm := range test.vmList { vmListWithPowerState[vm] = "" diff --git a/pkg/cloudprovider/providers/azure/azure_loadbalancer.go b/pkg/cloudprovider/providers/azure/azure_loadbalancer.go index bc53a496668b9..506a64dd2f73d 100644 --- a/pkg/cloudprovider/providers/azure/azure_loadbalancer.go +++ b/pkg/cloudprovider/providers/azure/azure_loadbalancer.go @@ -147,7 +147,7 @@ func (az *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, ser return nil, err } - if _, err := az.reconcilePublicIP(clusterName, updateService, true /* wantLb */); err != nil { + if _, err := az.reconcilePublicIP(clusterName, updateService, lb, true /* wantLb */); err != nil { return nil, err } @@ -185,7 +185,7 @@ func (az *Cloud) EnsureLoadBalancerDeleted(ctx context.Context, clusterName stri return err } - if _, err := az.reconcilePublicIP(clusterName, service, false /* wantLb */); err != nil { + if _, err := az.reconcilePublicIP(clusterName, service, nil, false /* wantLb */); err != nil { return err } @@ -1301,7 +1301,7 @@ func deduplicate(collection *[]string) *[]string { } // This reconciles the PublicIP resources similar to how the LB is reconciled. -func (az *Cloud) reconcilePublicIP(clusterName string, service *v1.Service, wantLb bool) (*network.PublicIPAddress, error) { +func (az *Cloud) reconcilePublicIP(clusterName string, service *v1.Service, lb *network.LoadBalancer, wantLb bool) (*network.PublicIPAddress, error) { isInternal := requiresInternalLoadBalancer(service) serviceName := getServiceName(service) var desiredPipName string @@ -1320,7 +1320,8 @@ func (az *Cloud) reconcilePublicIP(clusterName string, service *v1.Service, want return nil, err } - for _, pip := range pips { + for i := range pips { + pip := pips[i] if pip.Tags != nil && (pip.Tags)["service"] != nil && *(pip.Tags)["service"] == serviceName { @@ -1331,17 +1332,9 @@ func (az *Cloud) reconcilePublicIP(clusterName string, service *v1.Service, want // Public ip resource with match service tag } else { glog.V(2).Infof("reconcilePublicIP for service(%s): pip(%s) - deleting", serviceName, pipName) - glog.V(10).Infof("DeletePublicIPWithRetry(%s, %q): start", pipResourceGroup, pipName) - err = az.DeletePublicIPWithRetry(service, pipResourceGroup, pipName) - if err != nil { - glog.V(2).Infof("ensure(%s) abort backoff: pip(%s) - deleting", serviceName, pipName) - // We let err to pass through - // It may be ignorable - } - glog.V(10).Infof("DeletePublicIPWithRetry(%s, %q): end", pipResourceGroup, pipName) // response not read yet... - - err = ignoreStatusNotFoundFromError(err) + err := az.safeDeletePublicIP(service, pipResourceGroup, &pip, lb) if err != nil { + glog.Errorf("safeDeletePublicIP(%s) failed with error: %v", pipName, err) return nil, err } glog.V(2).Infof("reconcilePublicIP for service(%s): pip(%s) - finished", serviceName, pipName) @@ -1362,6 +1355,86 @@ func (az *Cloud) reconcilePublicIP(clusterName string, service *v1.Service, want return nil, nil } +// safeDeletePublicIP deletes public IP by removing its reference first. +func (az *Cloud) safeDeletePublicIP(service *v1.Service, pipResourceGroup string, pip *network.PublicIPAddress, lb *network.LoadBalancer) error { + // Remove references if pip.IPConfiguration is not nil. + if pip.PublicIPAddressPropertiesFormat != nil && + pip.PublicIPAddressPropertiesFormat.IPConfiguration != nil && + lb != nil && lb.LoadBalancerPropertiesFormat != nil && + lb.LoadBalancerPropertiesFormat.FrontendIPConfigurations != nil { + referencedLBRules := []network.SubResource{} + frontendIPConfigUpdated := false + loadBalancerRuleUpdated := false + + // Check whether there are still frontend IP configurations referring to it. + ipConfigurationID := to.String(pip.PublicIPAddressPropertiesFormat.IPConfiguration.ID) + if ipConfigurationID != "" { + lbFrontendIPConfigs := *lb.LoadBalancerPropertiesFormat.FrontendIPConfigurations + for i := len(lbFrontendIPConfigs) - 1; i >= 0; i-- { + config := lbFrontendIPConfigs[i] + if strings.EqualFold(ipConfigurationID, to.String(config.ID)) { + if config.FrontendIPConfigurationPropertiesFormat != nil && + config.FrontendIPConfigurationPropertiesFormat.LoadBalancingRules != nil { + referencedLBRules = *config.FrontendIPConfigurationPropertiesFormat.LoadBalancingRules + } + + frontendIPConfigUpdated = true + lbFrontendIPConfigs = append(lbFrontendIPConfigs[:i], lbFrontendIPConfigs[i+1:]...) + break + } + } + + if frontendIPConfigUpdated { + lb.LoadBalancerPropertiesFormat.FrontendIPConfigurations = &lbFrontendIPConfigs + } + } + + // Check whether there are still load balancer rules referring to it. + if len(referencedLBRules) > 0 { + referencedLBRuleIDs := sets.NewString() + for _, refer := range referencedLBRules { + referencedLBRuleIDs.Insert(to.String(refer.ID)) + } + + if lb.LoadBalancerPropertiesFormat.LoadBalancingRules != nil { + lbRules := *lb.LoadBalancerPropertiesFormat.LoadBalancingRules + for i := len(lbRules) - 1; i >= 0; i-- { + ruleID := to.String(lbRules[i].ID) + if ruleID != "" && referencedLBRuleIDs.Has(ruleID) { + loadBalancerRuleUpdated = true + lbRules = append(lbRules[:i], lbRules[i+1:]...) + } + } + + if loadBalancerRuleUpdated { + lb.LoadBalancerPropertiesFormat.LoadBalancingRules = &lbRules + } + } + } + + // Update load balancer when frontendIPConfigUpdated or loadBalancerRuleUpdated. + if frontendIPConfigUpdated || loadBalancerRuleUpdated { + err := az.CreateOrUpdateLBWithRetry(service, *lb) + if err != nil { + glog.Errorf("safeDeletePublicIP for service(%s) failed with error: %v", getServiceName(service), err) + return err + } + } + } + + pipName := to.String(pip.Name) + glog.V(10).Infof("DeletePublicIPWithRetry(%s, %q): start", pipResourceGroup, pipName) + err := az.DeletePublicIPWithRetry(service, pipResourceGroup, pipName) + if err != nil { + if err = ignoreStatusNotFoundFromError(err); err != nil { + return err + } + } + glog.V(10).Infof("DeletePublicIPWithRetry(%s, %q): end", pipResourceGroup, pipName) + + return nil +} + func findProbe(probes []network.Probe, probe network.Probe) bool { for _, existingProbe := range probes { if strings.EqualFold(to.String(existingProbe.Name), to.String(probe.Name)) && to.Int32(existingProbe.Port) == to.Int32(probe.Port) { diff --git a/pkg/cloudprovider/providers/azure/azure_managedDiskController.go b/pkg/cloudprovider/providers/azure/azure_managedDiskController.go index e72608175bc77..1bbd65ac19ada 100644 --- a/pkg/cloudprovider/providers/azure/azure_managedDiskController.go +++ b/pkg/cloudprovider/providers/azure/azure_managedDiskController.go @@ -23,8 +23,8 @@ import ( "strconv" "strings" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" - "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" + "github.com/Azure/go-autorest/autorest/to" "github.com/golang/glog" "k8s.io/api/core/v1" @@ -35,6 +35,12 @@ import ( "k8s.io/kubernetes/pkg/volume/util" ) +const ( + // default IOPS Caps & Throughput Cap (MBps) per https://docs.microsoft.com/en-us/azure/virtual-machines/linux/disks-ultra-ssd + defaultDiskIOPSReadWrite = 500 + defaultDiskMBpsReadWrite = 100 +) + //ManagedDiskController : managed disk controller struct type ManagedDiskController struct { common *controllerCommon @@ -55,7 +61,11 @@ type ManagedDiskOptions struct { // The tags of the disk. Tags map[string]string // The SKU of storage account. - StorageAccountType storage.SkuName + StorageAccountType compute.DiskStorageAccountTypes + // IOPS Caps for UltraSSD disk + DiskIOPSReadWrite string + // Throughput Cap (MBps) for UltraSSD disk + DiskMBpsReadWrite string } func newManagedDiskController(common *controllerCommon) (*ManagedDiskController, error) { @@ -87,17 +97,49 @@ func (c *ManagedDiskController) CreateManagedDisk(options *ManagedDiskOptions) ( } diskSizeGB := int32(options.SizeGB) + diskSku := compute.DiskStorageAccountTypes(options.StorageAccountType) + diskProperties := compute.DiskProperties{ + DiskSizeGB: &diskSizeGB, + CreationData: &compute.CreationData{CreateOption: compute.Empty}, + } + + if diskSku == compute.UltraSSDLRS { + diskIOPSReadWrite := int64(defaultDiskIOPSReadWrite) + if options.DiskIOPSReadWrite != "" { + v, err := strconv.Atoi(options.DiskIOPSReadWrite) + if err != nil { + return "", fmt.Errorf("AzureDisk - failed to parse DiskIOPSReadWrite: %v", err) + } + diskIOPSReadWrite = int64(v) + } + diskProperties.DiskIOPSReadWrite = to.Int64Ptr(diskIOPSReadWrite) + + diskMBpsReadWrite := int32(defaultDiskMBpsReadWrite) + if options.DiskMBpsReadWrite != "" { + v, err := strconv.Atoi(options.DiskMBpsReadWrite) + if err != nil { + return "", fmt.Errorf("AzureDisk - failed to parse DiskMBpsReadWrite: %v", err) + } + diskMBpsReadWrite = int32(v) + } + diskProperties.DiskMBpsReadWrite = to.Int32Ptr(diskMBpsReadWrite) + } else { + if options.DiskIOPSReadWrite != "" { + return "", fmt.Errorf("AzureDisk - DiskIOPSReadWrite parameter is only applicable in UltraSSD_LRS disk type") + } + if options.DiskMBpsReadWrite != "" { + return "", fmt.Errorf("AzureDisk - DiskMBpsReadWrite parameter is only applicable in UltraSSD_LRS disk type") + } + } + model := compute.Disk{ Location: &c.common.location, Tags: newTags, Zones: createZones, Sku: &compute.DiskSku{ - Name: compute.StorageAccountTypes(options.StorageAccountType), - }, - DiskProperties: &compute.DiskProperties{ - DiskSizeGB: &diskSizeGB, - CreationData: &compute.CreationData{CreateOption: compute.Empty}, + Name: diskSku, }, + DiskProperties: &diskProperties, } if options.ResourceGroup == "" { diff --git a/pkg/cloudprovider/providers/azure/azure_standard.go b/pkg/cloudprovider/providers/azure/azure_standard.go index 8315b49d5038d..dc565276b1b11 100644 --- a/pkg/cloudprovider/providers/azure/azure_standard.go +++ b/pkg/cloudprovider/providers/azure/azure_standard.go @@ -29,7 +29,7 @@ import ( "k8s.io/api/core/v1" cloudprovider "k8s.io/cloud-provider" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/Azure/go-autorest/autorest/to" "github.com/golang/glog" diff --git a/pkg/cloudprovider/providers/azure/azure_test.go b/pkg/cloudprovider/providers/azure/azure_test.go index b708976a61828..0369d59a53cd9 100644 --- a/pkg/cloudprovider/providers/azure/azure_test.go +++ b/pkg/cloudprovider/providers/azure/azure_test.go @@ -19,13 +19,10 @@ package azure import ( "bytes" "context" - "encoding/json" "fmt" "math" "net" "net/http" - "net/http/httptest" - "reflect" "strings" "testing" @@ -37,7 +34,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/azure/auth" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/Azure/go-autorest/autorest/to" "github.com/stretchr/testify/assert" @@ -861,13 +858,13 @@ func TestReconcilePublicIPWithNewService(t *testing.T) { az := getTestCloud() svc := getTestService("servicea", v1.ProtocolTCP, 80, 443) - pip, err := az.reconcilePublicIP(testClusterName, &svc, true /* wantLb*/) + pip, err := az.reconcilePublicIP(testClusterName, &svc, nil, true /* wantLb*/) if err != nil { t.Errorf("Unexpected error: %q", err) } validatePublicIP(t, pip, &svc, true) - pip2, err := az.reconcilePublicIP(testClusterName, &svc, true /* wantLb */) + pip2, err := az.reconcilePublicIP(testClusterName, &svc, nil, true /* wantLb */) if err != nil { t.Errorf("Unexpected error: %q", err) } @@ -882,7 +879,7 @@ func TestReconcilePublicIPRemoveService(t *testing.T) { az := getTestCloud() svc := getTestService("servicea", v1.ProtocolTCP, 80, 443) - pip, err := az.reconcilePublicIP(testClusterName, &svc, true /* wantLb*/) + pip, err := az.reconcilePublicIP(testClusterName, &svc, nil, true /* wantLb*/) if err != nil { t.Errorf("Unexpected error: %q", err) } @@ -890,7 +887,7 @@ func TestReconcilePublicIPRemoveService(t *testing.T) { validatePublicIP(t, pip, &svc, true) // Remove the service - pip, err = az.reconcilePublicIP(testClusterName, &svc, false /* wantLb */) + pip, err = az.reconcilePublicIP(testClusterName, &svc, nil, false /* wantLb */) if err != nil { t.Errorf("Unexpected error: %q", err) } @@ -902,7 +899,7 @@ func TestReconcilePublicIPWithInternalService(t *testing.T) { az := getTestCloud() svc := getInternalTestService("servicea", 80, 443) - pip, err := az.reconcilePublicIP(testClusterName, &svc, true /* wantLb*/) + pip, err := az.reconcilePublicIP(testClusterName, &svc, nil, true /* wantLb*/) if err != nil { t.Errorf("Unexpected error: %q", err) } @@ -914,7 +911,7 @@ func TestReconcilePublicIPWithExternalAndInternalSwitch(t *testing.T) { az := getTestCloud() svc := getInternalTestService("servicea", 80, 443) - pip, err := az.reconcilePublicIP(testClusterName, &svc, true /* wantLb*/) + pip, err := az.reconcilePublicIP(testClusterName, &svc, nil, true /* wantLb*/) if err != nil { t.Errorf("Unexpected error: %q", err) } @@ -922,14 +919,14 @@ func TestReconcilePublicIPWithExternalAndInternalSwitch(t *testing.T) { // Update to external service svcUpdated := getTestService("servicea", v1.ProtocolTCP, 80) - pip, err = az.reconcilePublicIP(testClusterName, &svcUpdated, true /* wantLb*/) + pip, err = az.reconcilePublicIP(testClusterName, &svcUpdated, nil, true /* wantLb*/) if err != nil { t.Errorf("Unexpected error: %q", err) } validatePublicIP(t, pip, &svcUpdated, true) // Update to internal service again - pip, err = az.reconcilePublicIP(testClusterName, &svc, true /* wantLb*/) + pip, err = az.reconcilePublicIP(testClusterName, &svc, nil, true /* wantLb*/) if err != nil { t.Errorf("Unexpected error: %q", err) } @@ -1682,7 +1679,6 @@ func TestGetZone(t *testing.T) { Config: Config{ Location: "eastus", }, - metadata: &InstanceMetadata{}, } testcases := []struct { name string @@ -1715,18 +1711,19 @@ func TestGetZone(t *testing.T) { } mux := http.NewServeMux() - mux.Handle("/v1/InstanceInfo/FD", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, test.faultDomain) - })) - mux.Handle("/instance/compute", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, fmt.Sprintf("{\"zone\":\"%s\"}", test.zone)) + mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, fmt.Sprintf(`{"compute":{"zone":"%s", "platformFaultDomain":"%s"}}`, test.zone, test.faultDomain)) })) go func() { http.Serve(listener, mux) }() defer listener.Close() - cloud.metadata.baseURL = "http://" + listener.Addr().String() + "/" + cloud.metadata, err = NewInstanceMetadataService("http://" + listener.Addr().String() + "/") + if err != nil { + t.Errorf("Test [%s] unexpected error: %v", test.name, err) + } + zone, err := cloud.GetZone(context.Background()) if err != nil { t.Errorf("Test [%s] unexpected error: %v", test.name, err) @@ -1740,29 +1737,6 @@ func TestGetZone(t *testing.T) { } } -func TestFetchFaultDomain(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, "99") - })) - defer ts.Close() - - cloud := &Cloud{} - cloud.metadata = &InstanceMetadata{ - baseURL: ts.URL + "/", - } - - faultDomain, err := cloud.fetchFaultDomain() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if faultDomain == nil { - t.Errorf("Unexpected nil fault domain") - } - if *faultDomain != "99" { - t.Errorf("Expected '99', saw '%s'", *faultDomain) - } -} - func TestGetNodeNameByProviderID(t *testing.T) { az := getTestCloud() providers := []struct { @@ -1815,73 +1789,6 @@ func TestGetNodeNameByProviderID(t *testing.T) { } } -func TestMetadataURLGeneration(t *testing.T) { - metadata := NewInstanceMetadata() - fullPath := metadata.makeMetadataURL("some/path") - if fullPath != "http://169.254.169.254/metadata/some/path" { - t.Errorf("Expected http://169.254.169.254/metadata/some/path saw %s", fullPath) - } -} - -func TestMetadataParsing(t *testing.T) { - data := ` -{ - "interface": [ - { - "ipv4": { - "ipAddress": [ - { - "privateIpAddress": "10.0.1.4", - "publicIpAddress": "X.X.X.X" - } - ], - "subnet": [ - { - "address": "10.0.1.0", - "prefix": "24" - } - ] - }, - "ipv6": { - "ipAddress": [ - - ] - }, - "macAddress": "002248020E1E" - } - ] -} -` - - network := NetworkMetadata{} - if err := json.Unmarshal([]byte(data), &network); err != nil { - t.Errorf("Unexpected error: %v", err) - } - - ip := network.Interface[0].IPV4.IPAddress[0].PrivateIP - if ip != "10.0.1.4" { - t.Errorf("Unexpected value: %s, expected 10.0.1.4", ip) - } - - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, data) - })) - defer server.Close() - - metadata := &InstanceMetadata{ - baseURL: server.URL, - } - - networkJSON := NetworkMetadata{} - if err := metadata.Object("/some/path", &networkJSON); err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if !reflect.DeepEqual(network, networkJSON) { - t.Errorf("Unexpected inequality:\n%#v\nvs\n%#v", network, networkJSON) - } -} - func addTestSubnet(t *testing.T, az *Cloud, svc *v1.Service) { if svc.Annotations[ServiceAnnotationLoadBalancerInternal] != "true" { t.Error("Subnet added to non-internal service") diff --git a/pkg/cloudprovider/providers/azure/azure_vmsets.go b/pkg/cloudprovider/providers/azure/azure_vmsets.go index 8fcd8e585b1a0..0d37a91c07083 100644 --- a/pkg/cloudprovider/providers/azure/azure_vmsets.go +++ b/pkg/cloudprovider/providers/azure/azure_vmsets.go @@ -17,7 +17,7 @@ limitations under the License. package azure import ( - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "k8s.io/api/core/v1" diff --git a/pkg/cloudprovider/providers/azure/azure_vmss.go b/pkg/cloudprovider/providers/azure/azure_vmss.go index d14090c14e559..ca09f46e88d64 100644 --- a/pkg/cloudprovider/providers/azure/azure_vmss.go +++ b/pkg/cloudprovider/providers/azure/azure_vmss.go @@ -24,7 +24,7 @@ import ( "strconv" "strings" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/Azure/go-autorest/autorest/to" "github.com/golang/glog" @@ -159,7 +159,7 @@ func (ss *scaleSet) getVmssVMByInstanceID(resourceGroup, scaleSetName, instanceI } if cachedVM == nil { - glog.Errorf("cound't find vmss virtual machine by scaleSetName (%q) and instanceID (%q)", scaleSetName, instanceID) + glog.Errorf("couldn't find vmss virtual machine by scaleSetName (%s) and instanceID (%s)", scaleSetName, instanceID) return vm, cloudprovider.InstanceNotFound } diff --git a/pkg/cloudprovider/providers/azure/azure_vmss_test.go b/pkg/cloudprovider/providers/azure/azure_vmss_test.go index f7d431992d669..54ebff15fad14 100644 --- a/pkg/cloudprovider/providers/azure/azure_vmss_test.go +++ b/pkg/cloudprovider/providers/azure/azure_vmss_test.go @@ -20,7 +20,7 @@ import ( "fmt" "testing" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/Azure/go-autorest/autorest/to" "github.com/stretchr/testify/assert" diff --git a/pkg/cloudprovider/providers/azure/azure_wrap.go b/pkg/cloudprovider/providers/azure/azure_wrap.go index 0f393a6074223..e2fa8f83d1378 100644 --- a/pkg/cloudprovider/providers/azure/azure_wrap.go +++ b/pkg/cloudprovider/providers/azure/azure_wrap.go @@ -23,7 +23,7 @@ import ( "strings" "time" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/Azure/go-autorest/autorest" "github.com/golang/glog" diff --git a/pkg/cloudprovider/providers/azure/azure_zones.go b/pkg/cloudprovider/providers/azure/azure_zones.go index 8cd41f75d7313..ca8b0b517633c 100644 --- a/pkg/cloudprovider/providers/azure/azure_zones.go +++ b/pkg/cloudprovider/providers/azure/azure_zones.go @@ -21,21 +21,12 @@ import ( "fmt" "strconv" "strings" - "sync" "github.com/golang/glog" "k8s.io/apimachinery/pkg/types" cloudprovider "k8s.io/cloud-provider" ) -const ( - faultDomainURI = "v1/InstanceInfo/FD" - computeMetadataURI = "instance/compute" -) - -var faultMutex = &sync.Mutex{} -var faultDomain *string - // makeZone returns the zone value in format of -. func (az *Cloud) makeZone(zoneID int) string { return fmt.Sprintf("%s-%d", strings.ToLower(az.Location), zoneID) @@ -58,47 +49,33 @@ func (az *Cloud) GetZoneID(zoneLabel string) string { // GetZone returns the Zone containing the current availability zone and locality region that the program is running in. // If the node is not running with availability zones, then it will fall back to fault domain. func (az *Cloud) GetZone(ctx context.Context) (cloudprovider.Zone, error) { - computeInfo := ComputeMetadata{} - err := az.metadata.Object(computeMetadataURI, &computeInfo) + metadata, err := az.metadata.GetMetadata() if err != nil { return cloudprovider.Zone{}, err } - if computeInfo.Zone == "" { - glog.V(3).Infof("Availability zone is not enabled for the node, falling back to fault domain") - return az.getZoneFromFaultDomain() + if metadata.Compute == nil { + return cloudprovider.Zone{}, fmt.Errorf("failure of getting compute information from instance metadata") } - zoneID, err := strconv.Atoi(computeInfo.Zone) - if err != nil { - return cloudprovider.Zone{}, fmt.Errorf("failed to parse zone ID %q: %v", computeInfo.Zone, err) + zone := "" + if metadata.Compute.Zone != "" { + zoneID, err := strconv.Atoi(metadata.Compute.Zone) + if err != nil { + return cloudprovider.Zone{}, fmt.Errorf("failed to parse zone ID %q: %v", metadata.Compute.Zone, err) + } + zone = az.makeZone(zoneID) + } else { + glog.V(3).Infof("Availability zone is not enabled for the node, falling back to fault domain") + zone = metadata.Compute.FaultDomain } return cloudprovider.Zone{ - FailureDomain: az.makeZone(zoneID), + FailureDomain: zone, Region: az.Location, }, nil } -// getZoneFromFaultDomain gets fault domain for the instance. -// Fault domain is the fallback when availability zone is not enabled for the node. -func (az *Cloud) getZoneFromFaultDomain() (cloudprovider.Zone, error) { - faultMutex.Lock() - defer faultMutex.Unlock() - if faultDomain == nil { - var err error - faultDomain, err = az.fetchFaultDomain() - if err != nil { - return cloudprovider.Zone{}, err - } - } - zone := cloudprovider.Zone{ - FailureDomain: *faultDomain, - Region: az.Location, - } - return zone, nil -} - // GetZoneByProviderID implements Zones.GetZoneByProviderID // This is particularly useful in external cloud providers where the kubelet // does not initialize node data. @@ -133,12 +110,3 @@ func (az *Cloud) GetZoneByNodeName(ctx context.Context, nodeName types.NodeName) return az.vmSet.GetZoneByNodeName(string(nodeName)) } - -func (az *Cloud) fetchFaultDomain() (*string, error) { - faultDomain, err := az.metadata.Text(faultDomainURI) - if err != nil { - return nil, err - } - - return &faultDomain, nil -} diff --git a/pkg/cloudprovider/providers/gce/gce.go b/pkg/cloudprovider/providers/gce/gce.go index 794bf85efd336..adba37d59b64a 100644 --- a/pkg/cloudprovider/providers/gce/gce.go +++ b/pkg/cloudprovider/providers/gce/gce.go @@ -57,6 +57,7 @@ import ( ) const ( + // ProviderName is the official const representation of the Google Cloud Provider ProviderName = "gce" k8sNodeRouteTag = "k8s-node-route" @@ -80,13 +81,13 @@ const ( maxTargetPoolCreateInstances = 200 // HTTP Load Balancer parameters - // Configure 2 second period for external health checks. - gceHcCheckIntervalSeconds = int64(2) + // Configure 8 second period for external health checks. + gceHcCheckIntervalSeconds = int64(8) gceHcTimeoutSeconds = int64(1) // Start sending requests as soon as a pod is found on the node. gceHcHealthyThreshold = int64(1) - // Defaults to 5 * 2 = 10 seconds before the LB will steer traffic away - gceHcUnhealthyThreshold = int64(5) + // Defaults to 3 * 8 = 24 seconds before the LB will steer traffic away. + gceHcUnhealthyThreshold = int64(3) gceComputeAPIEndpoint = "https://www.googleapis.com/compute/v1/" gceComputeAPIEndpointBeta = "https://www.googleapis.com/compute/beta/" @@ -97,9 +98,9 @@ type gceObject interface { MarshalJSON() ([]byte, error) } -// GCECloud is an implementation of Interface, LoadBalancer and Instances for Google Compute Engine. -type GCECloud struct { - // ClusterID contains functionality for getting (and initializing) the ingress-uid. Call GCECloud.Initialize() +// Cloud is an implementation of Interface, LoadBalancer and Instances for Google Compute Engine. +type Cloud struct { + // ClusterID contains functionality for getting (and initializing) the ingress-uid. Call Cloud.Initialize() // for the cloudprovider to start watching the configmap. ClusterID ClusterID @@ -145,7 +146,7 @@ type GCECloud struct { // lock to prevent shared resources from being prematurely deleted while the operation is // in progress. sharedResourceLock sync.Mutex - // AlphaFeatureGate gates gce alpha features in GCECloud instance. + // AlphaFeatureGate gates gce alpha features in Cloud instance. // Related wrapper functions that interacts with gce alpha api should examine whether // the corresponding api is enabled. // If not enabled, it should return error. @@ -158,6 +159,7 @@ type GCECloud struct { s *cloud.Service } +// ConfigGlobal is the in memory representation of the gce.conf config data // TODO: replace gcfg with json type ConfigGlobal struct { TokenURL string `gcfg:"token-url"` @@ -177,12 +179,12 @@ type ConfigGlobal struct { NodeInstancePrefix string `gcfg:"node-instance-prefix"` Regional bool `gcfg:"regional"` Multizone bool `gcfg:"multizone"` - // ApiEndpoint is the GCE compute API endpoint to use. If this is blank, + // APIEndpoint is the GCE compute API endpoint to use. If this is blank, // then the default endpoint is used. - ApiEndpoint string `gcfg:"api-endpoint"` - // ContainerApiEndpoint is the GCE container API endpoint to use. If this is blank, + APIEndpoint string `gcfg:"api-endpoint"` + // ContainerAPIEndpoint is the GCE container API endpoint to use. If this is blank, // then the default endpoint is used. - ContainerApiEndpoint string `gcfg:"container-api-endpoint"` + ContainerAPIEndpoint string `gcfg:"container-api-endpoint"` // LocalZone specifies the GCE zone that gce cloud client instance is // located in (i.e. where the controller will be running). If this is // blank, then the local zone will be discovered via the metadata server. @@ -197,10 +199,10 @@ type ConfigFile struct { Global ConfigGlobal `gcfg:"global"` } -// CloudConfig includes all the necessary configuration for creating GCECloud +// CloudConfig includes all the necessary configuration for creating Cloud type CloudConfig struct { - ApiEndpoint string - ContainerApiEndpoint string + APIEndpoint string + ContainerAPIEndpoint string ProjectID string NetworkProjectID string Region string @@ -236,22 +238,22 @@ type Services struct { } // ComputeServices returns access to the internal compute services. -func (g *GCECloud) ComputeServices() *Services { +func (g *Cloud) ComputeServices() *Services { return &Services{g.service, g.serviceAlpha, g.serviceBeta} } // Compute returns the generated stubs for the compute API. -func (g *GCECloud) Compute() cloud.Cloud { +func (g *Cloud) Compute() cloud.Cloud { return g.c } // ContainerService returns the container service. -func (g *GCECloud) ContainerService() *container.Service { +func (g *Cloud) ContainerService() *container.Service { return g.containerService } -// newGCECloud creates a new instance of GCECloud. -func newGCECloud(config io.Reader) (gceCloud *GCECloud, err error) { +// newGCECloud creates a new instance of Cloud. +func newGCECloud(config io.Reader) (gceCloud *Cloud, err error) { var cloudConfig *CloudConfig var configFile *ConfigFile @@ -286,12 +288,12 @@ func generateCloudConfig(configFile *ConfigFile) (cloudConfig *CloudConfig, err cloudConfig.UseMetadataServer = true cloudConfig.AlphaFeatureGate = NewAlphaFeatureGate([]string{}) if configFile != nil { - if configFile.Global.ApiEndpoint != "" { - cloudConfig.ApiEndpoint = configFile.Global.ApiEndpoint + if configFile.Global.APIEndpoint != "" { + cloudConfig.APIEndpoint = configFile.Global.APIEndpoint } - if configFile.Global.ContainerApiEndpoint != "" { - cloudConfig.ContainerApiEndpoint = configFile.Global.ContainerApiEndpoint + if configFile.Global.ContainerAPIEndpoint != "" { + cloudConfig.ContainerAPIEndpoint = configFile.Global.ContainerAPIEndpoint } if configFile.Global.TokenURL != "" { @@ -377,11 +379,11 @@ func generateCloudConfig(configFile *ConfigFile) (cloudConfig *CloudConfig, err return cloudConfig, err } -// CreateGCECloud creates a GCECloud object using the specified parameters. +// CreateGCECloud creates a Cloud object using the specified parameters. // If no networkUrl is specified, loads networkName via rest call. // If no tokenSource is specified, uses oauth2.DefaultTokenSource. // If managedZones is nil / empty all zones in the region will be managed. -func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { +func CreateGCECloud(config *CloudConfig) (*Cloud, error) { // Remove any pre-release version and build metadata from the semver, // leaving only the MAJOR.MINOR.PATCH portion. See http://semver.org/. version := strings.TrimLeft(strings.Split(strings.Split(version.Get().GitVersion, "-")[0], "+")[0], "v") @@ -429,10 +431,10 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { // Generate alpha and beta api endpoints based on override v1 api endpoint. // For example, // staging API endpoint: https://www.googleapis.com/compute/staging_v1/ - if config.ApiEndpoint != "" { - service.BasePath = fmt.Sprintf("%sprojects/", config.ApiEndpoint) - serviceBeta.BasePath = fmt.Sprintf("%sprojects/", strings.Replace(config.ApiEndpoint, "v1", "beta", -1)) - serviceAlpha.BasePath = fmt.Sprintf("%sprojects/", strings.Replace(config.ApiEndpoint, "v1", "alpha", -1)) + if config.APIEndpoint != "" { + service.BasePath = fmt.Sprintf("%sprojects/", config.APIEndpoint) + serviceBeta.BasePath = fmt.Sprintf("%sprojects/", strings.Replace(config.APIEndpoint, "v1", "beta", -1)) + serviceAlpha.BasePath = fmt.Sprintf("%sprojects/", strings.Replace(config.APIEndpoint, "v1", "alpha", -1)) } containerService, err := container.New(client) @@ -440,8 +442,8 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { return nil, err } containerService.UserAgent = userAgent - if config.ContainerApiEndpoint != "" { - containerService.BasePath = config.ContainerApiEndpoint + if config.ContainerAPIEndpoint != "" { + containerService.BasePath = config.ContainerAPIEndpoint } tpuService, err := newTPUService(client) @@ -460,7 +462,7 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { if config.NetworkURL != "" { networkURL = config.NetworkURL } else if config.NetworkName != "" { - networkURL = gceNetworkURL(config.ApiEndpoint, netProjID, config.NetworkName) + networkURL = gceNetworkURL(config.APIEndpoint, netProjID, config.NetworkName) } else { // Other consumers may use the cloudprovider without utilizing the wrapped GCE API functions // or functions requiring network/subnetwork URLs (e.g. Kubelet). @@ -470,7 +472,7 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { if config.SubnetworkURL != "" { subnetURL = config.SubnetworkURL } else if config.SubnetworkName != "" { - subnetURL = gceSubnetworkURL(config.ApiEndpoint, netProjID, config.Region, config.SubnetworkName) + subnetURL = gceSubnetworkURL(config.APIEndpoint, netProjID, config.Region, config.SubnetworkName) } else { // Determine the type of network and attempt to discover the correct subnet for AUTO mode. // Gracefully fail because kubelet calls CreateGCECloud without any config, and minions @@ -510,7 +512,7 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { operationPollRateLimiter := flowcontrol.NewTokenBucketRateLimiter(5, 5) // 5 qps, 5 burst. - gce := &GCECloud{ + gce := &Cloud{ service: service, serviceAlpha: serviceAlpha, serviceBeta: serviceBeta, @@ -550,8 +552,8 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { // SetRateLimiter adds a custom cloud.RateLimiter implementation. // WARNING: Calling this could have unexpected behavior if you have in-flight -// requests. It is best to use this immediately after creating a GCECloud. -func (g *GCECloud) SetRateLimiter(rl cloud.RateLimiter) { +// requests. It is best to use this immediately after creating a Cloud. +func (g *Cloud) SetRateLimiter(rl cloud.RateLimiter) { if rl != nil { g.s.RateLimiter = rl } @@ -610,89 +612,92 @@ func tryConvertToProjectNames(configProject, configNetworkProject string, servic // Initialize takes in a clientBuilder and spawns a goroutine for watching the clusterid configmap. // This must be called before utilizing the funcs of gce.ClusterID -func (gce *GCECloud) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stop <-chan struct{}) { - gce.clientBuilder = clientBuilder - gce.client = clientBuilder.ClientOrDie("cloud-provider") +func (g *Cloud) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stop <-chan struct{}) { + g.clientBuilder = clientBuilder + g.client = clientBuilder.ClientOrDie("cloud-provider") - if gce.OnXPN() { - gce.eventBroadcaster = record.NewBroadcaster() - gce.eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: gce.client.CoreV1().Events("")}) - gce.eventRecorder = gce.eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "gce-cloudprovider"}) + if g.OnXPN() { + g.eventBroadcaster = record.NewBroadcaster() + g.eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: g.client.CoreV1().Events("")}) + g.eventRecorder = g.eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "g-cloudprovider"}) } - go gce.watchClusterID(stop) + go g.watchClusterID(stop) } // LoadBalancer returns an implementation of LoadBalancer for Google Compute Engine. -func (gce *GCECloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) { - return gce, true +func (g *Cloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) { + return g, true } // Instances returns an implementation of Instances for Google Compute Engine. -func (gce *GCECloud) Instances() (cloudprovider.Instances, bool) { - return gce, true +func (g *Cloud) Instances() (cloudprovider.Instances, bool) { + return g, true } // Zones returns an implementation of Zones for Google Compute Engine. -func (gce *GCECloud) Zones() (cloudprovider.Zones, bool) { - return gce, true +func (g *Cloud) Zones() (cloudprovider.Zones, bool) { + return g, true } -func (gce *GCECloud) Clusters() (cloudprovider.Clusters, bool) { - return gce, true +// Clusters returns an implementation of Clusters for Google Compute Engine. +func (g *Cloud) Clusters() (cloudprovider.Clusters, bool) { + return g, true } // Routes returns an implementation of Routes for Google Compute Engine. -func (gce *GCECloud) Routes() (cloudprovider.Routes, bool) { - return gce, true +func (g *Cloud) Routes() (cloudprovider.Routes, bool) { + return g, true } // ProviderName returns the cloud provider ID. -func (gce *GCECloud) ProviderName() string { +func (g *Cloud) ProviderName() string { return ProviderName } // ProjectID returns the ProjectID corresponding to the project this cloud is in. -func (g *GCECloud) ProjectID() string { +func (g *Cloud) ProjectID() string { return g.projectID } // NetworkProjectID returns the ProjectID corresponding to the project this cluster's network is in. -func (g *GCECloud) NetworkProjectID() string { +func (g *Cloud) NetworkProjectID() string { return g.networkProjectID } // Region returns the region -func (gce *GCECloud) Region() string { - return gce.region +func (g *Cloud) Region() string { + return g.region } // OnXPN returns true if the cluster is running on a cross project network (XPN) -func (gce *GCECloud) OnXPN() bool { - return gce.onXPN +func (g *Cloud) OnXPN() bool { + return g.onXPN } // NetworkURL returns the network url -func (gce *GCECloud) NetworkURL() string { - return gce.networkURL +func (g *Cloud) NetworkURL() string { + return g.networkURL } // SubnetworkURL returns the subnetwork url -func (gce *GCECloud) SubnetworkURL() string { - return gce.subnetworkURL +func (g *Cloud) SubnetworkURL() string { + return g.subnetworkURL } -func (gce *GCECloud) IsLegacyNetwork() bool { - return gce.isLegacyNetwork +// IsLegacyNetwork returns true if the cluster is still running a legacy network configuration. +func (g *Cloud) IsLegacyNetwork() bool { + return g.isLegacyNetwork } -func (gce *GCECloud) SetInformers(informerFactory informers.SharedInformerFactory) { - glog.Infof("Setting up informers for GCECloud") +// SetInformers sets up the zone handlers we need watching for node changes. +func (g *Cloud) SetInformers(informerFactory informers.SharedInformerFactory) { + glog.Infof("Setting up informers for Cloud") nodeInformer := informerFactory.Core().V1().Nodes().Informer() nodeInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { node := obj.(*v1.Node) - gce.updateNodeZones(nil, node) + g.updateNodeZones(nil, node) }, UpdateFunc: func(prev, obj interface{}) { prevNode := prev.(*v1.Node) @@ -701,7 +706,7 @@ func (gce *GCECloud) SetInformers(informerFactory informers.SharedInformerFactor prevNode.Labels[kubeletapis.LabelZoneFailureDomain] { return } - gce.updateNodeZones(prevNode, newNode) + g.updateNodeZones(prevNode, newNode) }, DeleteFunc: func(obj interface{}) { node, isNode := obj.(*v1.Node) @@ -719,37 +724,37 @@ func (gce *GCECloud) SetInformers(informerFactory informers.SharedInformerFactor return } } - gce.updateNodeZones(node, nil) + g.updateNodeZones(node, nil) }, }) - gce.nodeInformerSynced = nodeInformer.HasSynced + g.nodeInformerSynced = nodeInformer.HasSynced } -func (gce *GCECloud) updateNodeZones(prevNode, newNode *v1.Node) { - gce.nodeZonesLock.Lock() - defer gce.nodeZonesLock.Unlock() +func (g *Cloud) updateNodeZones(prevNode, newNode *v1.Node) { + g.nodeZonesLock.Lock() + defer g.nodeZonesLock.Unlock() if prevNode != nil { prevZone, ok := prevNode.ObjectMeta.Labels[kubeletapis.LabelZoneFailureDomain] if ok { - gce.nodeZones[prevZone].Delete(prevNode.ObjectMeta.Name) - if gce.nodeZones[prevZone].Len() == 0 { - gce.nodeZones[prevZone] = nil + g.nodeZones[prevZone].Delete(prevNode.ObjectMeta.Name) + if g.nodeZones[prevZone].Len() == 0 { + g.nodeZones[prevZone] = nil } } } if newNode != nil { newZone, ok := newNode.ObjectMeta.Labels[kubeletapis.LabelZoneFailureDomain] if ok { - if gce.nodeZones[newZone] == nil { - gce.nodeZones[newZone] = sets.NewString() + if g.nodeZones[newZone] == nil { + g.nodeZones[newZone] = sets.NewString() } - gce.nodeZones[newZone].Insert(newNode.ObjectMeta.Name) + g.nodeZones[newZone].Insert(newNode.ObjectMeta.Name) } } } // HasClusterID returns true if the cluster has a clusterID -func (gce *GCECloud) HasClusterID() bool { +func (g *Cloud) HasClusterID() bool { return true } @@ -760,8 +765,8 @@ func isProjectNumber(idOrNumber string) bool { return err == nil } -// GCECloud implements cloudprovider.Interface. -var _ cloudprovider.Interface = (*GCECloud)(nil) +// Cloud implements cloudprovider.Interface. +var _ cloudprovider.Interface = (*Cloud)(nil) func gceNetworkURL(apiEndpoint, project, network string) string { if apiEndpoint == "" { @@ -894,19 +899,19 @@ func newOauthClient(tokenSource oauth2.TokenSource) (*http.Client, error) { } func (manager *gceServiceManager) getProjectsAPIEndpoint() string { - projectsApiEndpoint := gceComputeAPIEndpoint + "projects/" + projectsAPIEndpoint := gceComputeAPIEndpoint + "projects/" if manager.gce.service != nil { - projectsApiEndpoint = manager.gce.service.BasePath + projectsAPIEndpoint = manager.gce.service.BasePath } - return projectsApiEndpoint + return projectsAPIEndpoint } func (manager *gceServiceManager) getProjectsAPIEndpointBeta() string { - projectsApiEndpoint := gceComputeAPIEndpointBeta + "projects/" + projectsAPIEndpoint := gceComputeAPIEndpointBeta + "projects/" if manager.gce.service != nil { - projectsApiEndpoint = manager.gce.serviceBeta.BasePath + projectsAPIEndpoint = manager.gce.serviceBeta.BasePath } - return projectsApiEndpoint + return projectsAPIEndpoint } diff --git a/pkg/cloudprovider/providers/gce/gce_addresses.go b/pkg/cloudprovider/providers/gce/gce_addresses.go index 2bf3e20b051b8..b595ae6282538 100644 --- a/pkg/cloudprovider/providers/gce/gce_addresses.go +++ b/pkg/cloudprovider/providers/gce/gce_addresses.go @@ -42,106 +42,106 @@ func newAddressMetricContextWithVersion(request, region, version string) *metric // Caller is allocated a random IP if they do not specify an ipAddress. If an // ipAddress is specified, it must belong to the current project, eg: an // ephemeral IP associated with a global forwarding rule. -func (gce *GCECloud) ReserveGlobalAddress(addr *compute.Address) error { +func (g *Cloud) ReserveGlobalAddress(addr *compute.Address) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("reserve", "") - return mc.Observe(gce.c.GlobalAddresses().Insert(ctx, meta.GlobalKey(addr.Name), addr)) + return mc.Observe(g.c.GlobalAddresses().Insert(ctx, meta.GlobalKey(addr.Name), addr)) } // DeleteGlobalAddress deletes a global address by name. -func (gce *GCECloud) DeleteGlobalAddress(name string) error { +func (g *Cloud) DeleteGlobalAddress(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("delete", "") - return mc.Observe(gce.c.GlobalAddresses().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.GlobalAddresses().Delete(ctx, meta.GlobalKey(name))) } // GetGlobalAddress returns the global address by name. -func (gce *GCECloud) GetGlobalAddress(name string) (*compute.Address, error) { +func (g *Cloud) GetGlobalAddress(name string) (*compute.Address, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("get", "") - v, err := gce.c.GlobalAddresses().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.GlobalAddresses().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // ReserveRegionAddress creates a region address -func (gce *GCECloud) ReserveRegionAddress(addr *compute.Address, region string) error { +func (g *Cloud) ReserveRegionAddress(addr *compute.Address, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("reserve", region) - return mc.Observe(gce.c.Addresses().Insert(ctx, meta.RegionalKey(addr.Name, region), addr)) + return mc.Observe(g.c.Addresses().Insert(ctx, meta.RegionalKey(addr.Name, region), addr)) } // ReserveAlphaRegionAddress creates an Alpha, regional address. -func (gce *GCECloud) ReserveAlphaRegionAddress(addr *computealpha.Address, region string) error { +func (g *Cloud) ReserveAlphaRegionAddress(addr *computealpha.Address, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("reserve", region) - return mc.Observe(gce.c.AlphaAddresses().Insert(ctx, meta.RegionalKey(addr.Name, region), addr)) + return mc.Observe(g.c.AlphaAddresses().Insert(ctx, meta.RegionalKey(addr.Name, region), addr)) } // ReserveBetaRegionAddress creates a beta region address -func (gce *GCECloud) ReserveBetaRegionAddress(addr *computebeta.Address, region string) error { +func (g *Cloud) ReserveBetaRegionAddress(addr *computebeta.Address, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("reserve", region) - return mc.Observe(gce.c.BetaAddresses().Insert(ctx, meta.RegionalKey(addr.Name, region), addr)) + return mc.Observe(g.c.BetaAddresses().Insert(ctx, meta.RegionalKey(addr.Name, region), addr)) } // DeleteRegionAddress deletes a region address by name. -func (gce *GCECloud) DeleteRegionAddress(name, region string) error { +func (g *Cloud) DeleteRegionAddress(name, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("delete", region) - return mc.Observe(gce.c.Addresses().Delete(ctx, meta.RegionalKey(name, region))) + return mc.Observe(g.c.Addresses().Delete(ctx, meta.RegionalKey(name, region))) } // GetRegionAddress returns the region address by name -func (gce *GCECloud) GetRegionAddress(name, region string) (*compute.Address, error) { +func (g *Cloud) GetRegionAddress(name, region string) (*compute.Address, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("get", region) - v, err := gce.c.Addresses().Get(ctx, meta.RegionalKey(name, region)) + v, err := g.c.Addresses().Get(ctx, meta.RegionalKey(name, region)) return v, mc.Observe(err) } // GetAlphaRegionAddress returns the Alpha, regional address by name. -func (gce *GCECloud) GetAlphaRegionAddress(name, region string) (*computealpha.Address, error) { +func (g *Cloud) GetAlphaRegionAddress(name, region string) (*computealpha.Address, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("get", region) - v, err := gce.c.AlphaAddresses().Get(ctx, meta.RegionalKey(name, region)) + v, err := g.c.AlphaAddresses().Get(ctx, meta.RegionalKey(name, region)) return v, mc.Observe(err) } // GetBetaRegionAddress returns the beta region address by name -func (gce *GCECloud) GetBetaRegionAddress(name, region string) (*computebeta.Address, error) { +func (g *Cloud) GetBetaRegionAddress(name, region string) (*computebeta.Address, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("get", region) - v, err := gce.c.BetaAddresses().Get(ctx, meta.RegionalKey(name, region)) + v, err := g.c.BetaAddresses().Get(ctx, meta.RegionalKey(name, region)) return v, mc.Observe(err) } // GetRegionAddressByIP returns the regional address matching the given IP address. -func (gce *GCECloud) GetRegionAddressByIP(region, ipAddress string) (*compute.Address, error) { +func (g *Cloud) GetRegionAddressByIP(region, ipAddress string) (*compute.Address, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("list", region) - addrs, err := gce.c.Addresses().List(ctx, region, filter.Regexp("address", ipAddress)) + addrs, err := g.c.Addresses().List(ctx, region, filter.Regexp("address", ipAddress)) mc.Observe(err) if err != nil { @@ -160,12 +160,12 @@ func (gce *GCECloud) GetRegionAddressByIP(region, ipAddress string) (*compute.Ad } // GetBetaRegionAddressByIP returns the beta regional address matching the given IP address. -func (gce *GCECloud) GetBetaRegionAddressByIP(region, ipAddress string) (*computebeta.Address, error) { +func (g *Cloud) GetBetaRegionAddressByIP(region, ipAddress string) (*computebeta.Address, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newAddressMetricContext("list", region) - addrs, err := gce.c.BetaAddresses().List(ctx, region, filter.Regexp("address", ipAddress)) + addrs, err := g.c.BetaAddresses().List(ctx, region, filter.Regexp("address", ipAddress)) mc.Observe(err) if err != nil { @@ -184,11 +184,11 @@ func (gce *GCECloud) GetBetaRegionAddressByIP(region, ipAddress string) (*comput } // TODO(#51665): retire this function once Network Tiers becomes Beta in GCP. -func (gce *GCECloud) getNetworkTierFromAddress(name, region string) (string, error) { - if !gce.AlphaFeatureGate.Enabled(AlphaFeatureNetworkTiers) { +func (g *Cloud) getNetworkTierFromAddress(name, region string) (string, error) { + if !g.AlphaFeatureGate.Enabled(AlphaFeatureNetworkTiers) { return cloud.NetworkTierDefault.ToGCEValue(), nil } - addr, err := gce.GetAlphaRegionAddress(name, region) + addr, err := g.GetAlphaRegionAddress(name, region) if err != nil { return handleAlphaNetworkTierGetError(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_alpha.go b/pkg/cloudprovider/providers/gce/gce_alpha.go index 0ce698aa98e9b..598f1e336d3f3 100644 --- a/pkg/cloudprovider/providers/gce/gce_alpha.go +++ b/pkg/cloudprovider/providers/gce/gce_alpha.go @@ -21,21 +21,24 @@ import ( ) const ( - // alpha: v1.8 (for Services) + // AlphaFeatureNetworkTiers allows Services backed by a GCP load balancer to choose + // what network tier to use. Currently supports "Standard" and "Premium" (default). // - // Allows Services backed by a GCP load balancer to choose what network - // tier to use. Currently supports "Standard" and "Premium" (default). + // alpha: v1.8 (for Services) AlphaFeatureNetworkTiers = "NetworkTiers" ) +// AlphaFeatureGate contains a mapping of alpha features to whether they are enabled type AlphaFeatureGate struct { features map[string]bool } +// Enabled returns true if the provided alpha feature is enabled func (af *AlphaFeatureGate) Enabled(key string) bool { return af.features[key] } +// NewAlphaFeatureGate marks the provided alpha features as enabled func NewAlphaFeatureGate(features []string) *AlphaFeatureGate { featureMap := make(map[string]bool) for _, name := range features { @@ -44,9 +47,9 @@ func NewAlphaFeatureGate(features []string) *AlphaFeatureGate { return &AlphaFeatureGate{featureMap} } -func (gce *GCECloud) alphaFeatureEnabled(feature string) error { - if !gce.AlphaFeatureGate.Enabled(feature) { - return fmt.Errorf("alpha feature %q is not enabled.", feature) +func (g *Cloud) alphaFeatureEnabled(feature string) error { + if !g.AlphaFeatureGate.Enabled(feature) { + return fmt.Errorf("alpha feature %q is not enabled", feature) } return nil } diff --git a/pkg/cloudprovider/providers/gce/gce_annotations.go b/pkg/cloudprovider/providers/gce/gce_annotations.go index ccc0f44411813..4f3281c3e4763 100644 --- a/pkg/cloudprovider/providers/gce/gce_annotations.go +++ b/pkg/cloudprovider/providers/gce/gce_annotations.go @@ -25,6 +25,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud" ) +// LoadBalancerType defines a specific type for holding load balancer types (eg. Internal) type LoadBalancerType string const ( @@ -33,23 +34,30 @@ const ( // Currently, only "internal" is supported. ServiceAnnotationLoadBalancerType = "cloud.google.com/load-balancer-type" + // LBTypeInternal is the constant for the official internal type. LBTypeInternal LoadBalancerType = "Internal" + // Deprecating the lowercase spelling of Internal. deprecatedTypeInternalLowerCase LoadBalancerType = "internal" - // ServiceAnnotationInternalBackendShare is annotated on a service with "true" when users + // ServiceAnnotationILBBackendShare is annotated on a service with "true" when users // want to share GCP Backend Services for a set of internal load balancers. // ALPHA feature - this may be removed in a future release. ServiceAnnotationILBBackendShare = "alpha.cloud.google.com/load-balancer-backend-share" + // This annotation did not correctly specify "alpha", so both annotations will be checked. deprecatedServiceAnnotationILBBackendShare = "cloud.google.com/load-balancer-backend-share" // NetworkTierAnnotationKey is annotated on a Service object to indicate which // network tier a GCP LB should use. The valid values are "Standard" and // "Premium" (default). - NetworkTierAnnotationKey = "cloud.google.com/network-tier" + NetworkTierAnnotationKey = "cloud.google.com/network-tier" + + // NetworkTierAnnotationStandard is an annotation to indicate the Service is on the Standard network tier NetworkTierAnnotationStandard = cloud.NetworkTierStandard - NetworkTierAnnotationPremium = cloud.NetworkTierPremium + + // NetworkTierAnnotationPremium is an annotation to indicate the Service is on the Premium network tier + NetworkTierAnnotationPremium = cloud.NetworkTierPremium ) // GetLoadBalancerAnnotationType returns the type of GCP load balancer which should be assembled. diff --git a/pkg/cloudprovider/providers/gce/gce_backendservice.go b/pkg/cloudprovider/providers/gce/gce_backendservice.go index 23dc3bf1cb3c5..6560c91260681 100644 --- a/pkg/cloudprovider/providers/gce/gce_backendservice.go +++ b/pkg/cloudprovider/providers/gce/gce_backendservice.go @@ -35,201 +35,201 @@ func newBackendServiceMetricContextWithVersion(request, region, version string) } // GetGlobalBackendService retrieves a backend by name. -func (gce *GCECloud) GetGlobalBackendService(name string) (*compute.BackendService, error) { +func (g *Cloud) GetGlobalBackendService(name string) (*compute.BackendService, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("get", "") - v, err := gce.c.BackendServices().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.BackendServices().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // GetBetaGlobalBackendService retrieves beta backend by name. -func (gce *GCECloud) GetBetaGlobalBackendService(name string) (*computebeta.BackendService, error) { +func (g *Cloud) GetBetaGlobalBackendService(name string) (*computebeta.BackendService, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContextWithVersion("get", "", computeBetaVersion) - v, err := gce.c.BetaBackendServices().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.BetaBackendServices().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // GetAlphaGlobalBackendService retrieves alpha backend by name. -func (gce *GCECloud) GetAlphaGlobalBackendService(name string) (*computealpha.BackendService, error) { +func (g *Cloud) GetAlphaGlobalBackendService(name string) (*computealpha.BackendService, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContextWithVersion("get", "", computeAlphaVersion) - v, err := gce.c.AlphaBackendServices().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.AlphaBackendServices().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // UpdateGlobalBackendService applies the given BackendService as an update to // an existing service. -func (gce *GCECloud) UpdateGlobalBackendService(bg *compute.BackendService) error { +func (g *Cloud) UpdateGlobalBackendService(bg *compute.BackendService) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("update", "") - return mc.Observe(gce.c.BackendServices().Update(ctx, meta.GlobalKey(bg.Name), bg)) + return mc.Observe(g.c.BackendServices().Update(ctx, meta.GlobalKey(bg.Name), bg)) } // UpdateBetaGlobalBackendService applies the given beta BackendService as an // update to an existing service. -func (gce *GCECloud) UpdateBetaGlobalBackendService(bg *computebeta.BackendService) error { +func (g *Cloud) UpdateBetaGlobalBackendService(bg *computebeta.BackendService) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContextWithVersion("update", "", computeBetaVersion) - return mc.Observe(gce.c.BetaBackendServices().Update(ctx, meta.GlobalKey(bg.Name), bg)) + return mc.Observe(g.c.BetaBackendServices().Update(ctx, meta.GlobalKey(bg.Name), bg)) } // UpdateAlphaGlobalBackendService applies the given alpha BackendService as an // update to an existing service. -func (gce *GCECloud) UpdateAlphaGlobalBackendService(bg *computealpha.BackendService) error { +func (g *Cloud) UpdateAlphaGlobalBackendService(bg *computealpha.BackendService) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContextWithVersion("update", "", computeAlphaVersion) - return mc.Observe(gce.c.AlphaBackendServices().Update(ctx, meta.GlobalKey(bg.Name), bg)) + return mc.Observe(g.c.AlphaBackendServices().Update(ctx, meta.GlobalKey(bg.Name), bg)) } // DeleteGlobalBackendService deletes the given BackendService by name. -func (gce *GCECloud) DeleteGlobalBackendService(name string) error { +func (g *Cloud) DeleteGlobalBackendService(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("delete", "") - return mc.Observe(gce.c.BackendServices().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.BackendServices().Delete(ctx, meta.GlobalKey(name))) } // CreateGlobalBackendService creates the given BackendService. -func (gce *GCECloud) CreateGlobalBackendService(bg *compute.BackendService) error { +func (g *Cloud) CreateGlobalBackendService(bg *compute.BackendService) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("create", "") - return mc.Observe(gce.c.BackendServices().Insert(ctx, meta.GlobalKey(bg.Name), bg)) + return mc.Observe(g.c.BackendServices().Insert(ctx, meta.GlobalKey(bg.Name), bg)) } // CreateBetaGlobalBackendService creates the given beta BackendService. -func (gce *GCECloud) CreateBetaGlobalBackendService(bg *computebeta.BackendService) error { +func (g *Cloud) CreateBetaGlobalBackendService(bg *computebeta.BackendService) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContextWithVersion("create", "", computeBetaVersion) - return mc.Observe(gce.c.BetaBackendServices().Insert(ctx, meta.GlobalKey(bg.Name), bg)) + return mc.Observe(g.c.BetaBackendServices().Insert(ctx, meta.GlobalKey(bg.Name), bg)) } // CreateAlphaGlobalBackendService creates the given alpha BackendService. -func (gce *GCECloud) CreateAlphaGlobalBackendService(bg *computealpha.BackendService) error { +func (g *Cloud) CreateAlphaGlobalBackendService(bg *computealpha.BackendService) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContextWithVersion("create", "", computeAlphaVersion) - return mc.Observe(gce.c.AlphaBackendServices().Insert(ctx, meta.GlobalKey(bg.Name), bg)) + return mc.Observe(g.c.AlphaBackendServices().Insert(ctx, meta.GlobalKey(bg.Name), bg)) } // ListGlobalBackendServices lists all backend services in the project. -func (gce *GCECloud) ListGlobalBackendServices() ([]*compute.BackendService, error) { +func (g *Cloud) ListGlobalBackendServices() ([]*compute.BackendService, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("list", "") - v, err := gce.c.BackendServices().List(ctx, filter.None) + v, err := g.c.BackendServices().List(ctx, filter.None) return v, mc.Observe(err) } // GetGlobalBackendServiceHealth returns the health of the BackendService // identified by the given name, in the given instanceGroup. The // instanceGroupLink is the fully qualified self link of an instance group. -func (gce *GCECloud) GetGlobalBackendServiceHealth(name string, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) { +func (g *Cloud) GetGlobalBackendServiceHealth(name string, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("get_health", "") groupRef := &compute.ResourceGroupReference{Group: instanceGroupLink} - v, err := gce.c.BackendServices().GetHealth(ctx, meta.GlobalKey(name), groupRef) + v, err := g.c.BackendServices().GetHealth(ctx, meta.GlobalKey(name), groupRef) return v, mc.Observe(err) } // GetRegionBackendService retrieves a backend by name. -func (gce *GCECloud) GetRegionBackendService(name, region string) (*compute.BackendService, error) { +func (g *Cloud) GetRegionBackendService(name, region string) (*compute.BackendService, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("get", region) - v, err := gce.c.RegionBackendServices().Get(ctx, meta.RegionalKey(name, region)) + v, err := g.c.RegionBackendServices().Get(ctx, meta.RegionalKey(name, region)) return v, mc.Observe(err) } // UpdateRegionBackendService applies the given BackendService as an update to // an existing service. -func (gce *GCECloud) UpdateRegionBackendService(bg *compute.BackendService, region string) error { +func (g *Cloud) UpdateRegionBackendService(bg *compute.BackendService, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("update", region) - return mc.Observe(gce.c.RegionBackendServices().Update(ctx, meta.RegionalKey(bg.Name, region), bg)) + return mc.Observe(g.c.RegionBackendServices().Update(ctx, meta.RegionalKey(bg.Name, region), bg)) } // DeleteRegionBackendService deletes the given BackendService by name. -func (gce *GCECloud) DeleteRegionBackendService(name, region string) error { +func (g *Cloud) DeleteRegionBackendService(name, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("delete", region) - return mc.Observe(gce.c.RegionBackendServices().Delete(ctx, meta.RegionalKey(name, region))) + return mc.Observe(g.c.RegionBackendServices().Delete(ctx, meta.RegionalKey(name, region))) } // CreateRegionBackendService creates the given BackendService. -func (gce *GCECloud) CreateRegionBackendService(bg *compute.BackendService, region string) error { +func (g *Cloud) CreateRegionBackendService(bg *compute.BackendService, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("create", region) - return mc.Observe(gce.c.RegionBackendServices().Insert(ctx, meta.RegionalKey(bg.Name, region), bg)) + return mc.Observe(g.c.RegionBackendServices().Insert(ctx, meta.RegionalKey(bg.Name, region), bg)) } // ListRegionBackendServices lists all backend services in the project. -func (gce *GCECloud) ListRegionBackendServices(region string) ([]*compute.BackendService, error) { +func (g *Cloud) ListRegionBackendServices(region string) ([]*compute.BackendService, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("list", region) - v, err := gce.c.RegionBackendServices().List(ctx, region, filter.None) + v, err := g.c.RegionBackendServices().List(ctx, region, filter.None) return v, mc.Observe(err) } // GetRegionalBackendServiceHealth returns the health of the BackendService // identified by the given name, in the given instanceGroup. The // instanceGroupLink is the fully qualified self link of an instance group. -func (gce *GCECloud) GetRegionalBackendServiceHealth(name, region string, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) { +func (g *Cloud) GetRegionalBackendServiceHealth(name, region string, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContext("get_health", region) ref := &compute.ResourceGroupReference{Group: instanceGroupLink} - v, err := gce.c.RegionBackendServices().GetHealth(ctx, meta.RegionalKey(name, region), ref) + v, err := g.c.RegionBackendServices().GetHealth(ctx, meta.RegionalKey(name, region), ref) return v, mc.Observe(err) } // SetSecurityPolicyForBetaGlobalBackendService sets the given // SecurityPolicyReference for the BackendService identified by the given name. -func (gce *GCECloud) SetSecurityPolicyForBetaGlobalBackendService(backendServiceName string, securityPolicyReference *computebeta.SecurityPolicyReference) error { +func (g *Cloud) SetSecurityPolicyForBetaGlobalBackendService(backendServiceName string, securityPolicyReference *computebeta.SecurityPolicyReference) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContextWithVersion("set_security_policy", "", computeBetaVersion) - return mc.Observe(gce.c.BetaBackendServices().SetSecurityPolicy(ctx, meta.GlobalKey(backendServiceName), securityPolicyReference)) + return mc.Observe(g.c.BetaBackendServices().SetSecurityPolicy(ctx, meta.GlobalKey(backendServiceName), securityPolicyReference)) } // SetSecurityPolicyForAlphaGlobalBackendService sets the given // SecurityPolicyReference for the BackendService identified by the given name. -func (gce *GCECloud) SetSecurityPolicyForAlphaGlobalBackendService(backendServiceName string, securityPolicyReference *computealpha.SecurityPolicyReference) error { +func (g *Cloud) SetSecurityPolicyForAlphaGlobalBackendService(backendServiceName string, securityPolicyReference *computealpha.SecurityPolicyReference) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newBackendServiceMetricContextWithVersion("set_security_policy", "", computeAlphaVersion) - return mc.Observe(gce.c.AlphaBackendServices().SetSecurityPolicy(ctx, meta.GlobalKey(backendServiceName), securityPolicyReference)) + return mc.Observe(g.c.AlphaBackendServices().SetSecurityPolicy(ctx, meta.GlobalKey(backendServiceName), securityPolicyReference)) } diff --git a/pkg/cloudprovider/providers/gce/gce_cert.go b/pkg/cloudprovider/providers/gce/gce_cert.go index 3b6614f816f30..5153f067e8a19 100644 --- a/pkg/cloudprovider/providers/gce/gce_cert.go +++ b/pkg/cloudprovider/providers/gce/gce_cert.go @@ -29,43 +29,43 @@ func newCertMetricContext(request string) *metricContext { } // GetSslCertificate returns the SslCertificate by name. -func (gce *GCECloud) GetSslCertificate(name string) (*compute.SslCertificate, error) { +func (g *Cloud) GetSslCertificate(name string) (*compute.SslCertificate, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newCertMetricContext("get") - v, err := gce.c.SslCertificates().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.SslCertificates().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // CreateSslCertificate creates and returns a SslCertificate. -func (gce *GCECloud) CreateSslCertificate(sslCerts *compute.SslCertificate) (*compute.SslCertificate, error) { +func (g *Cloud) CreateSslCertificate(sslCerts *compute.SslCertificate) (*compute.SslCertificate, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newCertMetricContext("create") - err := gce.c.SslCertificates().Insert(ctx, meta.GlobalKey(sslCerts.Name), sslCerts) + err := g.c.SslCertificates().Insert(ctx, meta.GlobalKey(sslCerts.Name), sslCerts) if err != nil { return nil, mc.Observe(err) } - return gce.GetSslCertificate(sslCerts.Name) + return g.GetSslCertificate(sslCerts.Name) } // DeleteSslCertificate deletes the SslCertificate by name. -func (gce *GCECloud) DeleteSslCertificate(name string) error { +func (g *Cloud) DeleteSslCertificate(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newCertMetricContext("delete") - return mc.Observe(gce.c.SslCertificates().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.SslCertificates().Delete(ctx, meta.GlobalKey(name))) } // ListSslCertificates lists all SslCertificates in the project. -func (gce *GCECloud) ListSslCertificates() ([]*compute.SslCertificate, error) { +func (g *Cloud) ListSslCertificates() ([]*compute.SslCertificate, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newCertMetricContext("list") - v, err := gce.c.SslCertificates().List(ctx, filter.None) + v, err := g.c.SslCertificates().List(ctx, filter.None) return v, mc.Observe(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_clusterid.go b/pkg/cloudprovider/providers/gce/gce_clusterid.go index 80e54bd172321..23dd6cf5e214c 100644 --- a/pkg/cloudprovider/providers/gce/gce_clusterid.go +++ b/pkg/cloudprovider/providers/gce/gce_clusterid.go @@ -36,19 +36,27 @@ import ( ) const ( - // Key used to persist UIDs to configmaps. + // UIDConfigMapName is the Key used to persist UIDs to configmaps. UIDConfigMapName = "ingress-uid" - // Namespace which contains the above config map + + // UIDNamespace is the namespace which contains the above config map UIDNamespace = metav1.NamespaceSystem - // Data keys for the specific ids - UIDCluster = "uid" - UIDProvider = "provider-uid" + + // UIDCluster is the data keys for looking up the clusters UID + UIDCluster = "uid" + + // UIDProvider is the data keys for looking up the providers UID + UIDProvider = "provider-uid" + + // UIDLengthBytes is the length of a UID UIDLengthBytes = 8 + // Frequency of the updateFunc event handler being called // This does not actually query the apiserver for current state - the local cache value is used. updateFuncFrequency = 10 * time.Minute ) +// ClusterID is the struct for maintaining information about this cluster's ID type ClusterID struct { idLock sync.RWMutex client clientset.Interface @@ -59,10 +67,10 @@ type ClusterID struct { } // Continually watches for changes to the cluster id config map -func (gce *GCECloud) watchClusterID(stop <-chan struct{}) { - gce.ClusterID = ClusterID{ +func (g *Cloud) watchClusterID(stop <-chan struct{}) { + g.ClusterID = ClusterID{ cfgMapKey: fmt.Sprintf("%v/%v", UIDNamespace, UIDConfigMapName), - client: gce.client, + client: g.client, } mapEventHandler := cache.ResourceEventHandlerFuncs{ @@ -78,7 +86,7 @@ func (gce *GCECloud) watchClusterID(stop <-chan struct{}) { } glog.V(4).Infof("Observed new configmap for clusteriD: %v, %v; setting local values", m.Name, m.Data) - gce.ClusterID.update(m) + g.ClusterID.update(m) }, UpdateFunc: func(old, cur interface{}) { m, ok := cur.(*v1.ConfigMap) @@ -97,13 +105,13 @@ func (gce *GCECloud) watchClusterID(stop <-chan struct{}) { } glog.V(4).Infof("Observed updated configmap for clusteriD %v, %v; setting local values", m.Name, m.Data) - gce.ClusterID.update(m) + g.ClusterID.update(m) }, } - listerWatcher := cache.NewListWatchFromClient(gce.ClusterID.client.CoreV1().RESTClient(), "configmaps", UIDNamespace, fields.Everything()) + listerWatcher := cache.NewListWatchFromClient(g.ClusterID.client.CoreV1().RESTClient(), "configmaps", UIDNamespace, fields.Everything()) var controller cache.Controller - gce.ClusterID.store, controller = cache.NewInformer(newSingleObjectListerWatcher(listerWatcher, UIDConfigMapName), &v1.ConfigMap{}, updateFuncFrequency, mapEventHandler) + g.ClusterID.store, controller = cache.NewInformer(newSingleObjectListerWatcher(listerWatcher, UIDConfigMapName), &v1.ConfigMap{}, updateFuncFrequency, mapEventHandler) controller.Run(stop) } @@ -131,9 +139,9 @@ func (ci *ClusterID) GetID() (string, error) { return *ci.clusterID, nil } -// GetFederationId returns the id which could represent the entire Federation +// GetFederationID returns the id which could represent the entire Federation // or just the cluster if not federated. -func (ci *ClusterID) GetFederationId() (string, bool, error) { +func (ci *ClusterID) GetFederationID() (string, bool, error) { if err := ci.getOrInitialize(); err != nil { return "", false, err } @@ -141,7 +149,7 @@ func (ci *ClusterID) GetFederationId() (string, bool, error) { ci.idLock.RLock() defer ci.idLock.RUnlock() if ci.clusterID == nil { - return "", false, errors.New("Could not retrieve cluster id") + return "", false, errors.New("could not retrieve cluster id") } // If provider ID is not set, return false @@ -157,7 +165,7 @@ func (ci *ClusterID) GetFederationId() (string, bool, error) { // before the watch has begun. func (ci *ClusterID) getOrInitialize() error { if ci.store == nil { - return errors.New("GCECloud.ClusterID is not ready. Call Initialize() before using.") + return errors.New("Cloud.ClusterID is not ready. Call Initialize() before using") } if ci.clusterID != nil { @@ -172,12 +180,12 @@ func (ci *ClusterID) getOrInitialize() error { } // The configmap does not exist - let's try creating one. - newId, err := makeUID() + newID, err := makeUID() if err != nil { return err } - glog.V(4).Infof("Creating clusteriD: %v", newId) + glog.V(4).Infof("Creating clusteriD: %v", newID) cfg := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: UIDConfigMapName, @@ -185,8 +193,8 @@ func (ci *ClusterID) getOrInitialize() error { }, } cfg.Data = map[string]string{ - UIDCluster: newId, - UIDProvider: newId, + UIDCluster: newID, + UIDProvider: newID, } if _, err := ci.client.CoreV1().ConfigMaps(UIDNamespace).Create(cfg); err != nil { @@ -194,7 +202,7 @@ func (ci *ClusterID) getOrInitialize() error { return err } - glog.V(2).Infof("Created a config map containing clusteriD: %v", newId) + glog.V(2).Infof("Created a config map containing clusteriD: %v", newID) ci.update(cfg) return nil } @@ -224,8 +232,8 @@ func (ci *ClusterID) update(m *v1.ConfigMap) { if clusterID, exists := m.Data[UIDCluster]; exists { ci.clusterID = &clusterID } - if provId, exists := m.Data[UIDProvider]; exists { - ci.providerID = &provId + if provID, exists := m.Data[UIDProvider]; exists { + ci.providerID = &provID } } diff --git a/pkg/cloudprovider/providers/gce/gce_clusters.go b/pkg/cloudprovider/providers/gce/gce_clusters.go index 63b4bbeb69d4c..53295000c669e 100644 --- a/pkg/cloudprovider/providers/gce/gce_clusters.go +++ b/pkg/cloudprovider/providers/gce/gce_clusters.go @@ -18,22 +18,22 @@ package gce import ( "context" - "errors" "fmt" "github.com/golang/glog" - container "google.golang.org/api/container/v1" + "google.golang.org/api/container/v1" ) func newClustersMetricContext(request, zone string) *metricContext { return newGenericMetricContext("clusters", request, unusedMetricLabel, zone, computeV1Version) } -func (gce *GCECloud) ListClusters(ctx context.Context) ([]string, error) { +// ListClusters will return a list of cluster names for the associated project +func (g *Cloud) ListClusters(ctx context.Context) ([]string, error) { allClusters := []string{} - for _, zone := range gce.managedZones { - clusters, err := gce.listClustersInZone(zone) + for _, zone := range g.managedZones { + clusters, err := g.listClustersInZone(zone) if err != nil { return nil, err } @@ -44,36 +44,38 @@ func (gce *GCECloud) ListClusters(ctx context.Context) ([]string, error) { return allClusters, nil } -func (gce *GCECloud) GetManagedClusters(ctx context.Context) ([]*container.Cluster, error) { +// GetManagedClusters will return the cluster objects associated to this project +func (g *Cloud) GetManagedClusters(ctx context.Context) ([]*container.Cluster, error) { managedClusters := []*container.Cluster{} - if gce.regional { + if g.regional { var err error - managedClusters, err = gce.getClustersInLocation(gce.region) + managedClusters, err = g.getClustersInLocation(g.region) if err != nil { return nil, err } - } else if len(gce.managedZones) >= 1 { - for _, zone := range gce.managedZones { - clusters, err := gce.getClustersInLocation(zone) + } else if len(g.managedZones) >= 1 { + for _, zone := range g.managedZones { + clusters, err := g.getClustersInLocation(zone) if err != nil { return nil, err } managedClusters = append(managedClusters, clusters...) } } else { - return nil, errors.New(fmt.Sprintf("no zones associated with this cluster(%s)", gce.ProjectID())) + return nil, fmt.Errorf("no zones associated with this cluster(%s)", g.ProjectID()) } return managedClusters, nil } -func (gce *GCECloud) Master(ctx context.Context, clusterName string) (string, error) { +// Master returned the dns address of the master +func (g *Cloud) Master(ctx context.Context, clusterName string) (string, error) { return "k8s-" + clusterName + "-master.internal", nil } -func (gce *GCECloud) listClustersInZone(zone string) ([]string, error) { - clusters, err := gce.getClustersInLocation(zone) +func (g *Cloud) listClustersInZone(zone string) ([]string, error) { + clusters, err := g.getClustersInLocation(zone) if err != nil { return nil, err } @@ -85,12 +87,12 @@ func (gce *GCECloud) listClustersInZone(zone string) ([]string, error) { return result, nil } -func (gce *GCECloud) getClustersInLocation(zoneOrRegion string) ([]*container.Cluster, error) { +func (g *Cloud) getClustersInLocation(zoneOrRegion string) ([]*container.Cluster, error) { // TODO: Issue/68913 migrate metric to list_location instead of list_zone. mc := newClustersMetricContext("list_zone", zoneOrRegion) // TODO: use PageToken to list all not just the first 500 - location := getLocationName(gce.projectID, zoneOrRegion) - list, err := gce.containerService.Projects.Locations.Clusters.List(location).Do() + location := getLocationName(g.projectID, zoneOrRegion) + list, err := g.containerService.Projects.Locations.Clusters.List(location).Do() if err != nil { return nil, mc.Observe(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_disks.go b/pkg/cloudprovider/providers/gce/gce_disks.go index d7c31603ee42b..8f8c47c7434e7 100644 --- a/pkg/cloudprovider/providers/gce/gce_disks.go +++ b/pkg/cloudprovider/providers/gce/gce_disks.go @@ -43,10 +43,14 @@ import ( "k8s.io/kubernetes/pkg/features" ) +// DiskType defines a specific type for holding disk types (eg. pd-ssd) type DiskType string const ( - DiskTypeSSD = "pd-ssd" + // DiskTypeSSD the type for persistent SSD storage + DiskTypeSSD = "pd-ssd" + + // DiskTypeStandard the type for standard persistent storage DiskTypeStandard = "pd-standard" diskTypeDefault = DiskTypeStandard @@ -85,7 +89,7 @@ type diskServiceManager interface { // Attach a persistent disk on GCE with the given disk spec to the specified instance. AttachDiskOnCloudProvider( - disk *GCEDisk, + disk *Disk, readWrite string, instanceZone string, instanceName string) error @@ -96,18 +100,18 @@ type diskServiceManager interface { instanceName string, devicePath string) error - ResizeDiskOnCloudProvider(disk *GCEDisk, sizeGb int64, zone string) error - RegionalResizeDiskOnCloudProvider(disk *GCEDisk, sizeGb int64) error + ResizeDiskOnCloudProvider(disk *Disk, sizeGb int64, zone string) error + RegionalResizeDiskOnCloudProvider(disk *Disk, sizeGb int64) error // Gets the persistent disk from GCE with the given diskName. - GetDiskFromCloudProvider(zone string, diskName string) (*GCEDisk, error) + GetDiskFromCloudProvider(zone string, diskName string) (*Disk, error) // Gets the regional persistent disk from GCE with the given diskName. - GetRegionalDiskFromCloudProvider(diskName string) (*GCEDisk, error) + GetRegionalDiskFromCloudProvider(diskName string) (*Disk, error) } type gceServiceManager struct { - gce *GCECloud + gce *Cloud } var _ diskServiceManager = &gceServiceManager{} @@ -172,7 +176,7 @@ func (manager *gceServiceManager) CreateRegionalDiskOnCloudProvider( } func (manager *gceServiceManager) AttachDiskOnCloudProvider( - disk *GCEDisk, + disk *Disk, readWrite string, instanceZone string, instanceName string) error { @@ -205,13 +209,13 @@ func (manager *gceServiceManager) DetachDiskOnCloudProvider( func (manager *gceServiceManager) GetDiskFromCloudProvider( zone string, - diskName string) (*GCEDisk, error) { + diskName string) (*Disk, error) { if zone == "" { - return nil, fmt.Errorf("Can not fetch disk %q. Zone is empty.", diskName) + return nil, fmt.Errorf("can not fetch disk %q, zone is empty", diskName) } if diskName == "" { - return nil, fmt.Errorf("Can not fetch disk. Zone is specified (%q). But disk name is empty.", zone) + return nil, fmt.Errorf("can not fetch disk, zone is specified (%q), but disk name is empty", zone) } ctx, cancel := cloud.ContextWithCallTimeout() @@ -231,7 +235,7 @@ func (manager *gceServiceManager) GetDiskFromCloudProvider( return nil, fmt.Errorf("failed to extract region from zone for %q/%q err=%v", zone, diskName, err) } - return &GCEDisk{ + return &Disk{ ZoneInfo: zoneInfo, Region: region, Name: diskStable.Name, @@ -242,7 +246,7 @@ func (manager *gceServiceManager) GetDiskFromCloudProvider( } func (manager *gceServiceManager) GetRegionalDiskFromCloudProvider( - diskName string) (*GCEDisk, error) { + diskName string) (*Disk, error) { if !utilfeature.DefaultFeatureGate.Enabled(features.GCERegionalPersistentDisk) { return nil, fmt.Errorf("the regional PD feature is only available with the %s Kubernetes feature gate enabled", features.GCERegionalPersistentDisk) @@ -260,7 +264,7 @@ func (manager *gceServiceManager) GetRegionalDiskFromCloudProvider( zones.Insert(lastComponent(zoneURI)) } - return &GCEDisk{ + return &Disk{ ZoneInfo: multiZone{zones}, Region: lastComponent(diskBeta.Region), Name: diskBeta.Name, @@ -290,7 +294,7 @@ func (manager *gceServiceManager) DeleteRegionalDiskOnCloudProvider( return manager.gce.c.BetaRegionDisks().Delete(ctx, meta.RegionalKey(diskName, manager.gce.region)) } -func (manager *gceServiceManager) getDiskSourceURI(disk *GCEDisk) (string, error) { +func (manager *gceServiceManager) getDiskSourceURI(disk *Disk) (string, error) { getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint() switch zoneInfo := disk.ZoneInfo.(type) { @@ -409,7 +413,7 @@ func (manager *gceServiceManager) getRegionFromZone(zoneInfo zoneType) (string, return region, nil } -func (manager *gceServiceManager) ResizeDiskOnCloudProvider(disk *GCEDisk, sizeGb int64, zone string) error { +func (manager *gceServiceManager) ResizeDiskOnCloudProvider(disk *Disk, sizeGb int64, zone string) error { resizeServiceRequest := &compute.DisksResizeRequest{ SizeGb: sizeGb, } @@ -419,7 +423,7 @@ func (manager *gceServiceManager) ResizeDiskOnCloudProvider(disk *GCEDisk, sizeG return manager.gce.c.Disks().Resize(ctx, meta.ZonalKey(disk.Name, zone), resizeServiceRequest) } -func (manager *gceServiceManager) RegionalResizeDiskOnCloudProvider(disk *GCEDisk, sizeGb int64) error { +func (manager *gceServiceManager) RegionalResizeDiskOnCloudProvider(disk *Disk, sizeGb int64) error { if !utilfeature.DefaultFeatureGate.Enabled(features.GCERegionalPersistentDisk) { return fmt.Errorf("the regional PD feature is only available with the %s Kubernetes feature gate enabled", features.GCERegionalPersistentDisk) } @@ -472,13 +476,14 @@ type Disks interface { GetAutoLabelsForPD(name string, zone string) (map[string]string, error) } -// GCECloud implements Disks. -var _ Disks = (*GCECloud)(nil) +// Cloud implements Disks. +var _ Disks = (*Cloud)(nil) -// GCECloud implements PVLabeler. -var _ cloudprovider.PVLabeler = (*GCECloud)(nil) +// Cloud implements PVLabeler. +var _ cloudprovider.PVLabeler = (*Cloud)(nil) -type GCEDisk struct { +// Disk holds all relevant data about an instance of GCE storage +type Disk struct { ZoneInfo zoneType Region string Name string @@ -510,7 +515,8 @@ func newDiskMetricContextRegional(request, region string) *metricContext { return newGenericMetricContext("disk", request, region, unusedMetricLabel, computeV1Version) } -func (gce *GCECloud) GetLabelsForVolume(ctx context.Context, pv *v1.PersistentVolume) (map[string]string, error) { +// GetLabelsForVolume retrieved the label info for the provided volume +func (g *Cloud) GetLabelsForVolume(ctx context.Context, pv *v1.PersistentVolume) (map[string]string, error) { // Ignore any volumes that are being provisioned if pv.Spec.GCEPersistentDisk.PDName == volume.ProvisionedVolumeName { return nil, nil @@ -519,7 +525,7 @@ func (gce *GCECloud) GetLabelsForVolume(ctx context.Context, pv *v1.PersistentVo // If the zone is already labeled, honor the hint zone := pv.Labels[kubeletapis.LabelZoneFailureDomain] - labels, err := gce.GetAutoLabelsForPD(pv.Spec.GCEPersistentDisk.PDName, zone) + labels, err := g.GetAutoLabelsForPD(pv.Spec.GCEPersistentDisk.PDName, zone) if err != nil { return nil, err } @@ -527,28 +533,30 @@ func (gce *GCECloud) GetLabelsForVolume(ctx context.Context, pv *v1.PersistentVo return labels, nil } -func (gce *GCECloud) AttachDisk(diskName string, nodeName types.NodeName, readOnly bool, regional bool) error { +// AttachDisk attaches given disk to the node with the specified NodeName. +// Current instance is used when instanceID is empty string. +func (g *Cloud) AttachDisk(diskName string, nodeName types.NodeName, readOnly bool, regional bool) error { instanceName := mapNodeNameToInstanceName(nodeName) - instance, err := gce.getInstanceByName(instanceName) + instance, err := g.getInstanceByName(instanceName) if err != nil { return fmt.Errorf("error getting instance %q", instanceName) } // Try fetching as regional PD - var disk *GCEDisk + var disk *Disk var mc *metricContext if regional && utilfeature.DefaultFeatureGate.Enabled(features.GCERegionalPersistentDisk) { - disk, err = gce.getRegionalDiskByName(diskName) + disk, err = g.getRegionalDiskByName(diskName) if err != nil { return err } - mc = newDiskMetricContextRegional("attach", gce.region) + mc = newDiskMetricContextRegional("attach", g.region) } else { - disk, err = gce.getDiskByName(diskName, instance.Zone) + disk, err = g.getDiskByName(diskName, instance.Zone) if err != nil { return err } - mc = newDiskMetricContextZonal("attach", gce.region, instance.Zone) + mc = newDiskMetricContextZonal("attach", g.region, instance.Zone) } readWrite := "READ_WRITE" @@ -556,12 +564,14 @@ func (gce *GCECloud) AttachDisk(diskName string, nodeName types.NodeName, readOn readWrite = "READ_ONLY" } - return mc.Observe(gce.manager.AttachDiskOnCloudProvider(disk, readWrite, instance.Zone, instance.Name)) + return mc.Observe(g.manager.AttachDiskOnCloudProvider(disk, readWrite, instance.Zone, instance.Name)) } -func (gce *GCECloud) DetachDisk(devicePath string, nodeName types.NodeName) error { +// DetachDisk detaches given disk to the node with the specified NodeName. +// Current instance is used when nodeName is empty string. +func (g *Cloud) DetachDisk(devicePath string, nodeName types.NodeName) error { instanceName := mapNodeNameToInstanceName(nodeName) - inst, err := gce.getInstanceByName(instanceName) + inst, err := g.getInstanceByName(instanceName) if err != nil { if err == cloudprovider.InstanceNotFound { // If instance no longer exists, safe to assume volume is not attached. @@ -575,13 +585,14 @@ func (gce *GCECloud) DetachDisk(devicePath string, nodeName types.NodeName) erro return fmt.Errorf("error getting instance %q", instanceName) } - mc := newDiskMetricContextZonal("detach", gce.region, inst.Zone) - return mc.Observe(gce.manager.DetachDiskOnCloudProvider(inst.Zone, inst.Name, devicePath)) + mc := newDiskMetricContextZonal("detach", g.region, inst.Zone) + return mc.Observe(g.manager.DetachDiskOnCloudProvider(inst.Zone, inst.Name, devicePath)) } -func (gce *GCECloud) DiskIsAttached(diskName string, nodeName types.NodeName) (bool, error) { +// DiskIsAttached checks if a disk is attached to the node with the specified NodeName. +func (g *Cloud) DiskIsAttached(diskName string, nodeName types.NodeName) (bool, error) { instanceName := mapNodeNameToInstanceName(nodeName) - instance, err := gce.getInstanceByName(instanceName) + instance, err := g.getInstanceByName(instanceName) if err != nil { if err == cloudprovider.InstanceNotFound { // If instance no longer exists, safe to assume volume is not attached. @@ -605,13 +616,15 @@ func (gce *GCECloud) DiskIsAttached(diskName string, nodeName types.NodeName) (b return false, nil } -func (gce *GCECloud) DisksAreAttached(diskNames []string, nodeName types.NodeName) (map[string]bool, error) { +// DisksAreAttached is a batch function to check if a list of disks are attached +// to the node with the specified NodeName. +func (g *Cloud) DisksAreAttached(diskNames []string, nodeName types.NodeName) (map[string]bool, error) { attached := make(map[string]bool) for _, diskName := range diskNames { attached[diskName] = false } instanceName := mapNodeNameToInstanceName(nodeName) - instance, err := gce.getInstanceByName(instanceName) + instance, err := g.getInstanceByName(instanceName) if err != nil { if err == cloudprovider.InstanceNotFound { // If instance no longer exists, safe to assume volume is not attached. @@ -640,11 +653,11 @@ func (gce *GCECloud) DisksAreAttached(diskNames []string, nodeName types.NodeNam // CreateDisk creates a new Persistent Disk, with the specified name & // size, in the specified zone. It stores specified tags encoded in // JSON in Description field. -func (gce *GCECloud) CreateDisk( +func (g *Cloud) CreateDisk( name string, diskType string, zone string, sizeGb int64, tags map[string]string) error { // Do not allow creation of PDs in zones that are do not have nodes. Such PDs // are not currently usable. - curZones, err := gce.GetAllCurrentZones() + curZones, err := g.GetAllCurrentZones() if err != nil { return err } @@ -652,7 +665,7 @@ func (gce *GCECloud) CreateDisk( return fmt.Errorf("kubernetes does not have a node in zone %q", zone) } - tagsStr, err := gce.encodeDiskTags(tags) + tagsStr, err := g.encodeDiskTags(tags) if err != nil { return err } @@ -662,9 +675,9 @@ func (gce *GCECloud) CreateDisk( return err } - mc := newDiskMetricContextZonal("create", gce.region, zone) + mc := newDiskMetricContextZonal("create", g.region, zone) - err = gce.manager.CreateDiskOnCloudProvider( + err = g.manager.CreateDiskOnCloudProvider( name, sizeGb, tagsStr, diskType, zone) mc.Observe(err) @@ -678,14 +691,14 @@ func (gce *GCECloud) CreateDisk( // CreateRegionalDisk creates a new Regional Persistent Disk, with the specified // name & size, replicated to the specified zones. It stores specified tags // encoded in JSON in Description field. -func (gce *GCECloud) CreateRegionalDisk( +func (g *Cloud) CreateRegionalDisk( name string, diskType string, replicaZones sets.String, sizeGb int64, tags map[string]string) error { // Do not allow creation of PDs in zones that are do not have nodes. Such PDs // are not currently usable. This functionality should be reverted to checking // against managed zones if we want users to be able to create RegionalDisks // in zones where there are no nodes - curZones, err := gce.GetAllCurrentZones() + curZones, err := g.GetAllCurrentZones() if err != nil { return err } @@ -693,7 +706,7 @@ func (gce *GCECloud) CreateRegionalDisk( return fmt.Errorf("kubernetes does not have nodes in specified zones: %q. Zones that contain nodes: %q", replicaZones.Difference(curZones), curZones) } - tagsStr, err := gce.encodeDiskTags(tags) + tagsStr, err := g.encodeDiskTags(tags) if err != nil { return err } @@ -703,9 +716,9 @@ func (gce *GCECloud) CreateRegionalDisk( return err } - mc := newDiskMetricContextRegional("create", gce.region) + mc := newDiskMetricContextRegional("create", g.region) - err = gce.manager.CreateRegionalDiskOnCloudProvider( + err = g.manager.CreateRegionalDiskOnCloudProvider( name, sizeGb, tagsStr, diskType, replicaZones) mc.Observe(err) @@ -727,8 +740,9 @@ func getDiskType(diskType string) (string, error) { } } -func (gce *GCECloud) DeleteDisk(diskToDelete string) error { - err := gce.doDeleteDisk(diskToDelete) +// DeleteDisk deletes rgw referenced persistent disk. +func (g *Cloud) DeleteDisk(diskToDelete string) error { + err := g.doDeleteDisk(diskToDelete) if isGCEError(err, "resourceInUseByAnotherResource") { return volume.NewDeletedVolumeInUseError(err.Error()) } @@ -740,8 +754,8 @@ func (gce *GCECloud) DeleteDisk(diskToDelete string) error { } // ResizeDisk expands given disk and returns new disk size -func (gce *GCECloud) ResizeDisk(diskToResize string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) { - disk, err := gce.GetDiskByNameUnknownZone(diskToResize) +func (g *Cloud) ResizeDisk(diskToResize string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) { + disk, err := g.GetDiskByNameUnknownZone(diskToResize) if err != nil { return oldSize, err } @@ -760,26 +774,24 @@ func (gce *GCECloud) ResizeDisk(diskToResize string, oldSize resource.Quantity, switch zoneInfo := disk.ZoneInfo.(type) { case singleZone: mc = newDiskMetricContextZonal("resize", disk.Region, zoneInfo.zone) - err := gce.manager.ResizeDiskOnCloudProvider(disk, requestGIB, zoneInfo.zone) + err := g.manager.ResizeDiskOnCloudProvider(disk, requestGIB, zoneInfo.zone) if err != nil { return oldSize, mc.Observe(err) - } else { - return newSizeQuant, mc.Observe(err) } + return newSizeQuant, mc.Observe(err) case multiZone: if !utilfeature.DefaultFeatureGate.Enabled(features.GCERegionalPersistentDisk) { return oldSize, fmt.Errorf("disk.ZoneInfo has unexpected type %T", zoneInfo) } mc = newDiskMetricContextRegional("resize", disk.Region) - err := gce.manager.RegionalResizeDiskOnCloudProvider(disk, requestGIB) + err := g.manager.RegionalResizeDiskOnCloudProvider(disk, requestGIB) if err != nil { return oldSize, mc.Observe(err) - } else { - return newSizeQuant, mc.Observe(err) } + return newSizeQuant, mc.Observe(err) case nil: return oldSize, fmt.Errorf("PD has nil ZoneInfo: %v", disk) default: @@ -787,13 +799,13 @@ func (gce *GCECloud) ResizeDisk(diskToResize string, oldSize resource.Quantity, } } -// Builds the labels that should be automatically added to a PersistentVolume backed by a GCE PD +// GetAutoLabelsForPD builds the labels that should be automatically added to a PersistentVolume backed by a GCE PD // Specifically, this builds FailureDomain (zone) and Region labels. // The PersistentVolumeLabel admission controller calls this and adds the labels when a PV is created. // If zone is specified, the volume will only be found in the specified zone, // otherwise all managed zones will be searched. -func (gce *GCECloud) GetAutoLabelsForPD(name string, zone string) (map[string]string, error) { - var disk *GCEDisk +func (g *Cloud) GetAutoLabelsForPD(name string, zone string) (map[string]string, error) { + var disk *Disk var err error if zone == "" { // For regional PDs this is fine, but for zonal PDs we would like as far @@ -804,7 +816,7 @@ func (gce *GCECloud) GetAutoLabelsForPD(name string, zone string) (map[string]st // However, wherever possible the zone should be passed (and it is // passed for most cases that we can control, e.g. dynamic volume // provisioning). - disk, err = gce.GetDiskByNameUnknownZone(name) + disk, err = g.GetDiskByNameUnknownZone(name) if err != nil { return nil, err } @@ -820,19 +832,19 @@ func (gce *GCECloud) GetAutoLabelsForPD(name string, zone string) (map[string]st if len(zoneSet) > 1 { // Regional PD - disk, err = gce.getRegionalDiskByName(name) + disk, err = g.getRegionalDiskByName(name) if err != nil { return nil, err } } else { // Zonal PD - disk, err = gce.getDiskByName(name, zone) + disk, err = g.getDiskByName(name, zone) if err != nil { return nil, err } } } else { - disk, err = gce.getDiskByName(name, zone) + disk, err = g.getDiskByName(name, zone) if err != nil { return nil, err } @@ -867,11 +879,11 @@ func (gce *GCECloud) GetAutoLabelsForPD(name string, zone string) (map[string]st return labels, nil } -// Returns a GCEDisk for the disk, if it is found in the specified zone. +// Returns a Disk for the disk, if it is found in the specified zone. // If not found, returns (nil, nil) -func (gce *GCECloud) findDiskByName(diskName string, zone string) (*GCEDisk, error) { - mc := newDiskMetricContextZonal("get", gce.region, zone) - disk, err := gce.manager.GetDiskFromCloudProvider(zone, diskName) +func (g *Cloud) findDiskByName(diskName string, zone string) (*Disk, error) { + mc := newDiskMetricContextZonal("get", g.region, zone) + disk, err := g.manager.GetDiskFromCloudProvider(zone, diskName) if err == nil { return disk, mc.Observe(nil) } @@ -882,19 +894,19 @@ func (gce *GCECloud) findDiskByName(diskName string, zone string) (*GCEDisk, err } // Like findDiskByName, but returns an error if the disk is not found -func (gce *GCECloud) getDiskByName(diskName string, zone string) (*GCEDisk, error) { - disk, err := gce.findDiskByName(diskName, zone) +func (g *Cloud) getDiskByName(diskName string, zone string) (*Disk, error) { + disk, err := g.findDiskByName(diskName, zone) if disk == nil && err == nil { return nil, fmt.Errorf("GCE persistent disk not found: diskName=%q zone=%q", diskName, zone) } return disk, err } -// Returns a GCEDisk for the regional disk, if it is found. +// Returns a Disk for the regional disk, if it is found. // If not found, returns (nil, nil) -func (gce *GCECloud) findRegionalDiskByName(diskName string) (*GCEDisk, error) { - mc := newDiskMetricContextRegional("get", gce.region) - disk, err := gce.manager.GetRegionalDiskFromCloudProvider(diskName) +func (g *Cloud) findRegionalDiskByName(diskName string) (*Disk, error) { + mc := newDiskMetricContextRegional("get", g.region) + disk, err := g.manager.GetRegionalDiskFromCloudProvider(diskName) if err == nil { return disk, mc.Observe(nil) } @@ -905,20 +917,20 @@ func (gce *GCECloud) findRegionalDiskByName(diskName string) (*GCEDisk, error) { } // Like findRegionalDiskByName, but returns an error if the disk is not found -func (gce *GCECloud) getRegionalDiskByName(diskName string) (*GCEDisk, error) { - disk, err := gce.findRegionalDiskByName(diskName) +func (g *Cloud) getRegionalDiskByName(diskName string) (*Disk, error) { + disk, err := g.findRegionalDiskByName(diskName) if disk == nil && err == nil { return nil, fmt.Errorf("GCE regional persistent disk not found: diskName=%q", diskName) } return disk, err } -// Scans all managed zones to return the GCE PD +// GetDiskByNameUnknownZone scans all managed zones to return the GCE PD // Prefer getDiskByName, if the zone can be established // Return cloudprovider.DiskNotFound if the given disk cannot be found in any zone -func (gce *GCECloud) GetDiskByNameUnknownZone(diskName string) (*GCEDisk, error) { +func (g *Cloud) GetDiskByNameUnknownZone(diskName string) (*Disk, error) { if utilfeature.DefaultFeatureGate.Enabled(features.GCERegionalPersistentDisk) { - regionalDisk, err := gce.getRegionalDiskByName(diskName) + regionalDisk, err := g.getRegionalDiskByName(diskName) if err == nil { return regionalDisk, err } @@ -934,9 +946,9 @@ func (gce *GCECloud) GetDiskByNameUnknownZone(diskName string) (*GCEDisk, error) // admission control, but that might be a little weird (values changing // on create) - var found *GCEDisk - for _, zone := range gce.managedZones { - disk, err := gce.findDiskByName(diskName, zone) + var found *Disk + for _, zone := range g.managedZones { + disk, err := g.findDiskByName(diskName, zone) if err != nil { return nil, err } @@ -964,14 +976,14 @@ func (gce *GCECloud) GetDiskByNameUnknownZone(diskName string) (*GCEDisk, error) return found, nil } glog.Warningf("GCE persistent disk %q not found in managed zones (%s)", - diskName, strings.Join(gce.managedZones, ",")) + diskName, strings.Join(g.managedZones, ",")) return nil, cloudprovider.DiskNotFound } // encodeDiskTags encodes requested volume tags into JSON string, as GCE does // not support tags on GCE PDs and we use Description field as fallback. -func (gce *GCECloud) encodeDiskTags(tags map[string]string) (string, error) { +func (g *Cloud) encodeDiskTags(tags map[string]string) (string, error) { if len(tags) == 0 { // No tags -> empty JSON return "", nil @@ -984,8 +996,8 @@ func (gce *GCECloud) encodeDiskTags(tags map[string]string) (string, error) { return string(enc), nil } -func (gce *GCECloud) doDeleteDisk(diskToDelete string) error { - disk, err := gce.GetDiskByNameUnknownZone(diskToDelete) +func (g *Cloud) doDeleteDisk(diskToDelete string) error { + disk, err := g.GetDiskByNameUnknownZone(diskToDelete) if err != nil { return err } @@ -995,14 +1007,14 @@ func (gce *GCECloud) doDeleteDisk(diskToDelete string) error { switch zoneInfo := disk.ZoneInfo.(type) { case singleZone: mc = newDiskMetricContextZonal("delete", disk.Region, zoneInfo.zone) - return mc.Observe(gce.manager.DeleteDiskOnCloudProvider(zoneInfo.zone, disk.Name)) + return mc.Observe(g.manager.DeleteDiskOnCloudProvider(zoneInfo.zone, disk.Name)) case multiZone: if !utilfeature.DefaultFeatureGate.Enabled(features.GCERegionalPersistentDisk) { return fmt.Errorf("disk.ZoneInfo has unexpected type %T", zoneInfo) } mc = newDiskMetricContextRegional("delete", disk.Region) - return mc.Observe(gce.manager.DeleteRegionalDiskOnCloudProvider(disk.Name)) + return mc.Observe(g.manager.DeleteRegionalDiskOnCloudProvider(disk.Name)) case nil: return fmt.Errorf("PD has nil ZoneInfo: %v", disk) default: diff --git a/pkg/cloudprovider/providers/gce/gce_disks_test.go b/pkg/cloudprovider/providers/gce/gce_disks_test.go index 4db0401e70723..98a95b64ea24f 100644 --- a/pkg/cloudprovider/providers/gce/gce_disks_test.go +++ b/pkg/cloudprovider/providers/gce/gce_disks_test.go @@ -35,15 +35,15 @@ import ( func TestCreateDisk_Basic(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: []string{"zone1"}, - projectID: gceProjectId, + projectID: gceProjectID, AlphaFeatureGate: alphaFeatureGate, nodeZones: createNodeZones(zonesWithNodes), nodeInformerSynced: func() bool { return true }, @@ -57,7 +57,7 @@ func TestCreateDisk_Basic(t *testing.T) { tags["test-tag"] = "test-value" expectedDiskTypeURI := gceComputeAPIEndpoint + "projects/" + fmt.Sprintf( - diskTypeURITemplateSingleZone, gceProjectId, zone, diskType) + diskTypeURITemplateSingleZone, gceProjectID, zone, diskType) expectedDescription := "{\"test-tag\":\"test-value\"}" /* Act */ @@ -90,15 +90,15 @@ func TestCreateDisk_Basic(t *testing.T) { func TestCreateRegionalDisk_Basic(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1", "zone3", "zone2"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, - projectID: gceProjectId, + projectID: gceProjectID, nodeZones: createNodeZones(zonesWithNodes), nodeInformerSynced: func() bool { return true }, } @@ -111,7 +111,7 @@ func TestCreateRegionalDisk_Basic(t *testing.T) { tags["test-tag"] = "test-value" expectedDiskTypeURI := gceComputeAPIEndpointBeta + "projects/" + fmt.Sprintf( - diskTypeURITemplateRegional, gceProjectId, gceRegion, diskType) + diskTypeURITemplateRegional, gceProjectID, gceRegion, diskType) expectedDescription := "{\"test-tag\":\"test-value\"}" /* Act */ @@ -144,12 +144,12 @@ func TestCreateRegionalDisk_Basic(t *testing.T) { func TestCreateDisk_DiskAlreadyExists(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -175,11 +175,11 @@ func TestCreateDisk_DiskAlreadyExists(t *testing.T) { func TestCreateDisk_WrongZone(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1"} - fakeManager := newFakeManager(gceProjectId, gceRegion) - gce := GCECloud{ + fakeManager := newFakeManager(gceProjectID, gceRegion) + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, nodeZones: createNodeZones(zonesWithNodes), @@ -200,11 +200,11 @@ func TestCreateDisk_WrongZone(t *testing.T) { func TestCreateDisk_NoManagedZone(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{} - fakeManager := newFakeManager(gceProjectId, gceRegion) - gce := GCECloud{ + fakeManager := newFakeManager(gceProjectID, gceRegion) + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, nodeZones: createNodeZones(zonesWithNodes), @@ -225,11 +225,11 @@ func TestCreateDisk_NoManagedZone(t *testing.T) { func TestCreateDisk_BadDiskType(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1"} - fakeManager := newFakeManager(gceProjectId, gceRegion) - gce := GCECloud{manager: fakeManager, + fakeManager := newFakeManager(gceProjectID, gceRegion) + gce := Cloud{manager: fakeManager, managedZones: zonesWithNodes, nodeZones: createNodeZones(zonesWithNodes), nodeInformerSynced: func() bool { return true }} @@ -250,12 +250,12 @@ func TestCreateDisk_BadDiskType(t *testing.T) { func TestCreateDisk_MultiZone(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1", "zone2", "zone3"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -279,12 +279,12 @@ func TestCreateDisk_MultiZone(t *testing.T) { func TestDeleteDisk_Basic(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -313,12 +313,12 @@ func TestDeleteDisk_Basic(t *testing.T) { func TestDeleteDisk_NotFound(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -338,12 +338,12 @@ func TestDeleteDisk_NotFound(t *testing.T) { func TestDeleteDisk_ResourceBeingUsed(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -369,12 +369,12 @@ func TestDeleteDisk_ResourceBeingUsed(t *testing.T) { func TestDeleteDisk_SameDiskMultiZone(t *testing.T) { /* Assert */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1", "zone2", "zone3"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -403,12 +403,12 @@ func TestDeleteDisk_SameDiskMultiZone(t *testing.T) { func TestDeleteDisk_DiffDiskMultiZone(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"zone1"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -437,16 +437,16 @@ func TestDeleteDisk_DiffDiskMultiZone(t *testing.T) { func TestGetAutoLabelsForPD_Basic(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "us-central1" zone := "us-central1-c" zonesWithNodes := []string{zone} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) diskName := "disk" diskType := DiskTypeSSD const sizeGb int64 = 128 alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -474,16 +474,16 @@ func TestGetAutoLabelsForPD_Basic(t *testing.T) { func TestGetAutoLabelsForPD_NoZone(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "europe-west1" zone := "europe-west1-d" zonesWithNodes := []string{zone} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) diskName := "disk" diskType := DiskTypeStandard const sizeGb int64 = 128 alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -510,13 +510,13 @@ func TestGetAutoLabelsForPD_NoZone(t *testing.T) { func TestGetAutoLabelsForPD_DiskNotFound(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zone := "asia-northeast1-a" zonesWithNodes := []string{zone} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) diskName := "disk" - gce := GCECloud{manager: fakeManager, + gce := Cloud{manager: fakeManager, managedZones: zonesWithNodes, nodeZones: createNodeZones(zonesWithNodes), nodeInformerSynced: func() bool { return true }} @@ -532,13 +532,13 @@ func TestGetAutoLabelsForPD_DiskNotFound(t *testing.T) { func TestGetAutoLabelsForPD_DiskNotFoundAndNoZone(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) diskName := "disk" alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -557,17 +557,17 @@ func TestGetAutoLabelsForPD_DiskNotFoundAndNoZone(t *testing.T) { func TestGetAutoLabelsForPD_DupDisk(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "us-west1" zonesWithNodes := []string{"us-west1-b", "asia-southeast1-a"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) diskName := "disk" diskType := DiskTypeStandard zone := "us-west1-b" const sizeGb int64 = 128 alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -596,16 +596,16 @@ func TestGetAutoLabelsForPD_DupDisk(t *testing.T) { func TestGetAutoLabelsForPD_DupDiskNoZone(t *testing.T) { /* Arrange */ - gceProjectId := "test-project" + gceProjectID := "test-project" gceRegion := "fake-region" zonesWithNodes := []string{"us-west1-b", "asia-southeast1-a"} - fakeManager := newFakeManager(gceProjectId, gceRegion) + fakeManager := newFakeManager(gceProjectID, gceRegion) diskName := "disk" diskType := DiskTypeStandard const sizeGb int64 = 128 alphaFeatureGate := NewAlphaFeatureGate([]string{}) - gce := GCECloud{ + gce := Cloud{ manager: fakeManager, managedZones: zonesWithNodes, AlphaFeatureGate: alphaFeatureGate, @@ -738,16 +738,16 @@ func (manager *FakeServiceManager) CreateRegionalDiskOnCloudProvider( manager.regionalDisks[diskToCreateV1.Name] = zones return nil case targetBeta: - return fmt.Errorf("RegionalDisk CreateDisk op not supported in beta.") + return fmt.Errorf("regionalDisk CreateDisk op not supported in beta") case targetAlpha: - return fmt.Errorf("RegionalDisk CreateDisk op not supported in alpha.") + return fmt.Errorf("regionalDisk CreateDisk op not supported in alpha") default: return fmt.Errorf("unexpected type: %T", t) } } func (manager *FakeServiceManager) AttachDiskOnCloudProvider( - disk *GCEDisk, + disk *Disk, readWrite string, instanceZone string, instanceName string) error { @@ -784,7 +784,7 @@ func (manager *FakeServiceManager) DetachDiskOnCloudProvider( * Gets disk info stored in the FakeServiceManager. */ func (manager *FakeServiceManager) GetDiskFromCloudProvider( - zone string, diskName string) (*GCEDisk, error) { + zone string, diskName string) (*Disk, error) { if manager.zonalDisks[zone] == "" { return nil, cloudprovider.DiskNotFound @@ -796,7 +796,7 @@ func (manager *FakeServiceManager) GetDiskFromCloudProvider( return nil, err } - return &GCEDisk{ + return &Disk{ Region: manager.gceRegion, ZoneInfo: singleZone{lastComponent(zone)}, Name: diskName, @@ -809,7 +809,7 @@ func (manager *FakeServiceManager) GetDiskFromCloudProvider( * Gets disk info stored in the FakeServiceManager. */ func (manager *FakeServiceManager) GetRegionalDiskFromCloudProvider( - diskName string) (*GCEDisk, error) { + diskName string) (*Disk, error) { if _, ok := manager.regionalDisks[diskName]; !ok { return nil, cloudprovider.DiskNotFound @@ -821,7 +821,7 @@ func (manager *FakeServiceManager) GetRegionalDiskFromCloudProvider( return nil, err } - return &GCEDisk{ + return &Disk{ Region: manager.gceRegion, ZoneInfo: multiZone{manager.regionalDisks[diskName]}, Name: diskName, @@ -831,14 +831,14 @@ func (manager *FakeServiceManager) GetRegionalDiskFromCloudProvider( } func (manager *FakeServiceManager) ResizeDiskOnCloudProvider( - disk *GCEDisk, + disk *Disk, size int64, zone string) error { panic("Not implmented") } func (manager *FakeServiceManager) RegionalResizeDiskOnCloudProvider( - disk *GCEDisk, + disk *Disk, size int64) error { panic("Not implemented") } diff --git a/pkg/cloudprovider/providers/gce/gce_fake.go b/pkg/cloudprovider/providers/gce/gce_fake.go index f51bc20719fef..73a724d74ae01 100644 --- a/pkg/cloudprovider/providers/gce/gce_fake.go +++ b/pkg/cloudprovider/providers/gce/gce_fake.go @@ -25,6 +25,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud" ) +// TestClusterValues holds the config values for the fake/test gce cloud object. type TestClusterValues struct { ProjectID string Region string @@ -34,6 +35,8 @@ type TestClusterValues struct { ClusterName string } +// DefaultTestClusterValues Creates a reasonable set of default cluster values +// for generating a new test fake GCE cloud instance. func DefaultTestClusterValues() TestClusterValues { return TestClusterValues{ ProjectID: "test-project", @@ -45,10 +48,6 @@ func DefaultTestClusterValues() TestClusterValues { } } -func FakeGCECloud(vals TestClusterValues) *GCECloud { - return simpleFakeGCECloud(vals) -} - type fakeRoundTripper struct{} func (*fakeRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { @@ -66,10 +65,11 @@ func fakeClusterID(clusterID string) ClusterID { } } -func simpleFakeGCECloud(vals TestClusterValues) *GCECloud { +// NewFakeGCECloud constructs a fake GCE Cloud from the cluster values. +func NewFakeGCECloud(vals TestClusterValues) *Cloud { client := &http.Client{Transport: &fakeRoundTripper{}} service, _ := compute.New(client) - gce := &GCECloud{ + gce := &Cloud{ region: vals.Region, service: service, managedZones: []string{vals.ZoneName}, diff --git a/pkg/cloudprovider/providers/gce/gce_firewall.go b/pkg/cloudprovider/providers/gce/gce_firewall.go index e138df87471b8..4aea497095622 100644 --- a/pkg/cloudprovider/providers/gce/gce_firewall.go +++ b/pkg/cloudprovider/providers/gce/gce_firewall.go @@ -28,38 +28,38 @@ func newFirewallMetricContext(request string) *metricContext { } // GetFirewall returns the Firewall by name. -func (gce *GCECloud) GetFirewall(name string) (*compute.Firewall, error) { +func (g *Cloud) GetFirewall(name string) (*compute.Firewall, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newFirewallMetricContext("get") - v, err := gce.c.Firewalls().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.Firewalls().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // CreateFirewall creates the passed firewall -func (gce *GCECloud) CreateFirewall(f *compute.Firewall) error { +func (g *Cloud) CreateFirewall(f *compute.Firewall) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newFirewallMetricContext("create") - return mc.Observe(gce.c.Firewalls().Insert(ctx, meta.GlobalKey(f.Name), f)) + return mc.Observe(g.c.Firewalls().Insert(ctx, meta.GlobalKey(f.Name), f)) } // DeleteFirewall deletes the given firewall rule. -func (gce *GCECloud) DeleteFirewall(name string) error { +func (g *Cloud) DeleteFirewall(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newFirewallMetricContext("delete") - return mc.Observe(gce.c.Firewalls().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.Firewalls().Delete(ctx, meta.GlobalKey(name))) } // UpdateFirewall applies the given firewall as an update to an existing service. -func (gce *GCECloud) UpdateFirewall(f *compute.Firewall) error { +func (g *Cloud) UpdateFirewall(f *compute.Firewall) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newFirewallMetricContext("update") - return mc.Observe(gce.c.Firewalls().Update(ctx, meta.GlobalKey(f.Name), f)) + return mc.Observe(g.c.Firewalls().Update(ctx, meta.GlobalKey(f.Name), f)) } diff --git a/pkg/cloudprovider/providers/gce/gce_forwardingrule.go b/pkg/cloudprovider/providers/gce/gce_forwardingrule.go index b40652c98e32b..5689cfd32eaa1 100644 --- a/pkg/cloudprovider/providers/gce/gce_forwardingrule.go +++ b/pkg/cloudprovider/providers/gce/gce_forwardingrule.go @@ -32,129 +32,129 @@ func newForwardingRuleMetricContextWithVersion(request, region, version string) } // CreateGlobalForwardingRule creates the passed GlobalForwardingRule -func (gce *GCECloud) CreateGlobalForwardingRule(rule *compute.ForwardingRule) error { +func (g *Cloud) CreateGlobalForwardingRule(rule *compute.ForwardingRule) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("create", "") - return mc.Observe(gce.c.GlobalForwardingRules().Insert(ctx, meta.GlobalKey(rule.Name), rule)) + return mc.Observe(g.c.GlobalForwardingRules().Insert(ctx, meta.GlobalKey(rule.Name), rule)) } // SetProxyForGlobalForwardingRule links the given TargetHttp(s)Proxy with the given GlobalForwardingRule. // targetProxyLink is the SelfLink of a TargetHttp(s)Proxy. -func (gce *GCECloud) SetProxyForGlobalForwardingRule(forwardingRuleName, targetProxyLink string) error { +func (g *Cloud) SetProxyForGlobalForwardingRule(forwardingRuleName, targetProxyLink string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("set_proxy", "") target := &compute.TargetReference{Target: targetProxyLink} - return mc.Observe(gce.c.GlobalForwardingRules().SetTarget(ctx, meta.GlobalKey(forwardingRuleName), target)) + return mc.Observe(g.c.GlobalForwardingRules().SetTarget(ctx, meta.GlobalKey(forwardingRuleName), target)) } // DeleteGlobalForwardingRule deletes the GlobalForwardingRule by name. -func (gce *GCECloud) DeleteGlobalForwardingRule(name string) error { +func (g *Cloud) DeleteGlobalForwardingRule(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("delete", "") - return mc.Observe(gce.c.GlobalForwardingRules().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.GlobalForwardingRules().Delete(ctx, meta.GlobalKey(name))) } // GetGlobalForwardingRule returns the GlobalForwardingRule by name. -func (gce *GCECloud) GetGlobalForwardingRule(name string) (*compute.ForwardingRule, error) { +func (g *Cloud) GetGlobalForwardingRule(name string) (*compute.ForwardingRule, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("get", "") - v, err := gce.c.GlobalForwardingRules().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.GlobalForwardingRules().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // ListGlobalForwardingRules lists all GlobalForwardingRules in the project. -func (gce *GCECloud) ListGlobalForwardingRules() ([]*compute.ForwardingRule, error) { +func (g *Cloud) ListGlobalForwardingRules() ([]*compute.ForwardingRule, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("list", "") - v, err := gce.c.GlobalForwardingRules().List(ctx, filter.None) + v, err := g.c.GlobalForwardingRules().List(ctx, filter.None) return v, mc.Observe(err) } // GetRegionForwardingRule returns the RegionalForwardingRule by name & region. -func (gce *GCECloud) GetRegionForwardingRule(name, region string) (*compute.ForwardingRule, error) { +func (g *Cloud) GetRegionForwardingRule(name, region string) (*compute.ForwardingRule, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("get", region) - v, err := gce.c.ForwardingRules().Get(ctx, meta.RegionalKey(name, region)) + v, err := g.c.ForwardingRules().Get(ctx, meta.RegionalKey(name, region)) return v, mc.Observe(err) } // GetAlphaRegionForwardingRule returns the Alpha forwarding rule by name & region. -func (gce *GCECloud) GetAlphaRegionForwardingRule(name, region string) (*computealpha.ForwardingRule, error) { +func (g *Cloud) GetAlphaRegionForwardingRule(name, region string) (*computealpha.ForwardingRule, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContextWithVersion("get", region, computeAlphaVersion) - v, err := gce.c.AlphaForwardingRules().Get(ctx, meta.RegionalKey(name, region)) + v, err := g.c.AlphaForwardingRules().Get(ctx, meta.RegionalKey(name, region)) return v, mc.Observe(err) } // ListRegionForwardingRules lists all RegionalForwardingRules in the project & region. -func (gce *GCECloud) ListRegionForwardingRules(region string) ([]*compute.ForwardingRule, error) { +func (g *Cloud) ListRegionForwardingRules(region string) ([]*compute.ForwardingRule, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("list", region) - v, err := gce.c.ForwardingRules().List(ctx, region, filter.None) + v, err := g.c.ForwardingRules().List(ctx, region, filter.None) return v, mc.Observe(err) } // ListAlphaRegionForwardingRules lists all RegionalForwardingRules in the project & region. -func (gce *GCECloud) ListAlphaRegionForwardingRules(region string) ([]*computealpha.ForwardingRule, error) { +func (g *Cloud) ListAlphaRegionForwardingRules(region string) ([]*computealpha.ForwardingRule, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContextWithVersion("list", region, computeAlphaVersion) - v, err := gce.c.AlphaForwardingRules().List(ctx, region, filter.None) + v, err := g.c.AlphaForwardingRules().List(ctx, region, filter.None) return v, mc.Observe(err) } // CreateRegionForwardingRule creates and returns a // RegionalForwardingRule that points to the given BackendService -func (gce *GCECloud) CreateRegionForwardingRule(rule *compute.ForwardingRule, region string) error { +func (g *Cloud) CreateRegionForwardingRule(rule *compute.ForwardingRule, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("create", region) - return mc.Observe(gce.c.ForwardingRules().Insert(ctx, meta.RegionalKey(rule.Name, region), rule)) + return mc.Observe(g.c.ForwardingRules().Insert(ctx, meta.RegionalKey(rule.Name, region), rule)) } // CreateAlphaRegionForwardingRule creates and returns an Alpha // forwarding fule in the given region. -func (gce *GCECloud) CreateAlphaRegionForwardingRule(rule *computealpha.ForwardingRule, region string) error { +func (g *Cloud) CreateAlphaRegionForwardingRule(rule *computealpha.ForwardingRule, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContextWithVersion("create", region, computeAlphaVersion) - return mc.Observe(gce.c.AlphaForwardingRules().Insert(ctx, meta.RegionalKey(rule.Name, region), rule)) + return mc.Observe(g.c.AlphaForwardingRules().Insert(ctx, meta.RegionalKey(rule.Name, region), rule)) } // DeleteRegionForwardingRule deletes the RegionalForwardingRule by name & region. -func (gce *GCECloud) DeleteRegionForwardingRule(name, region string) error { +func (g *Cloud) DeleteRegionForwardingRule(name, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newForwardingRuleMetricContext("delete", region) - return mc.Observe(gce.c.ForwardingRules().Delete(ctx, meta.RegionalKey(name, region))) + return mc.Observe(g.c.ForwardingRules().Delete(ctx, meta.RegionalKey(name, region))) } // TODO(#51665): retire this function once Network Tiers becomes Beta in GCP. -func (gce *GCECloud) getNetworkTierFromForwardingRule(name, region string) (string, error) { - if !gce.AlphaFeatureGate.Enabled(AlphaFeatureNetworkTiers) { +func (g *Cloud) getNetworkTierFromForwardingRule(name, region string) (string, error) { + if !g.AlphaFeatureGate.Enabled(AlphaFeatureNetworkTiers) { return cloud.NetworkTierDefault.ToGCEValue(), nil } - fwdRule, err := gce.GetAlphaRegionForwardingRule(name, region) + fwdRule, err := g.GetAlphaRegionForwardingRule(name, region) if err != nil { return handleAlphaNetworkTierGetError(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_healthchecks.go b/pkg/cloudprovider/providers/gce/gce_healthchecks.go index f82838516877a..10e1f72a3592c 100644 --- a/pkg/cloudprovider/providers/gce/gce_healthchecks.go +++ b/pkg/cloudprovider/providers/gce/gce_healthchecks.go @@ -56,204 +56,204 @@ func newHealthcheckMetricContextWithVersion(request, version string) *metricCont return newGenericMetricContext("healthcheck", request, unusedMetricLabel, unusedMetricLabel, version) } -// GetHttpHealthCheck returns the given HttpHealthCheck by name. -func (gce *GCECloud) GetHttpHealthCheck(name string) (*compute.HttpHealthCheck, error) { +// GetHTTPHealthCheck returns the given HttpHealthCheck by name. +func (g *Cloud) GetHTTPHealthCheck(name string) (*compute.HttpHealthCheck, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("get_legacy") - v, err := gce.c.HttpHealthChecks().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.HttpHealthChecks().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } -// UpdateHttpHealthCheck applies the given HttpHealthCheck as an update. -func (gce *GCECloud) UpdateHttpHealthCheck(hc *compute.HttpHealthCheck) error { +// UpdateHTTPHealthCheck applies the given HttpHealthCheck as an update. +func (g *Cloud) UpdateHTTPHealthCheck(hc *compute.HttpHealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("update_legacy") - return mc.Observe(gce.c.HttpHealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.HttpHealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) } -// DeleteHttpHealthCheck deletes the given HttpHealthCheck by name. -func (gce *GCECloud) DeleteHttpHealthCheck(name string) error { +// DeleteHTTPHealthCheck deletes the given HttpHealthCheck by name. +func (g *Cloud) DeleteHTTPHealthCheck(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("delete_legacy") - return mc.Observe(gce.c.HttpHealthChecks().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.HttpHealthChecks().Delete(ctx, meta.GlobalKey(name))) } -// CreateHttpHealthCheck creates the given HttpHealthCheck. -func (gce *GCECloud) CreateHttpHealthCheck(hc *compute.HttpHealthCheck) error { +// CreateHTTPHealthCheck creates the given HttpHealthCheck. +func (g *Cloud) CreateHTTPHealthCheck(hc *compute.HttpHealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("create_legacy") - return mc.Observe(gce.c.HttpHealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.HttpHealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) } -// ListHttpHealthChecks lists all HttpHealthChecks in the project. -func (gce *GCECloud) ListHttpHealthChecks() ([]*compute.HttpHealthCheck, error) { +// ListHTTPHealthChecks lists all HttpHealthChecks in the project. +func (g *Cloud) ListHTTPHealthChecks() ([]*compute.HttpHealthCheck, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("list_legacy") - v, err := gce.c.HttpHealthChecks().List(ctx, filter.None) + v, err := g.c.HttpHealthChecks().List(ctx, filter.None) return v, mc.Observe(err) } // Legacy HTTPS Health Checks -// GetHttpsHealthCheck returns the given HttpsHealthCheck by name. -func (gce *GCECloud) GetHttpsHealthCheck(name string) (*compute.HttpsHealthCheck, error) { +// GetHTTPSHealthCheck returns the given HttpsHealthCheck by name. +func (g *Cloud) GetHTTPSHealthCheck(name string) (*compute.HttpsHealthCheck, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("get_legacy") - v, err := gce.c.HttpsHealthChecks().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.HttpsHealthChecks().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } -// UpdateHttpsHealthCheck applies the given HttpsHealthCheck as an update. -func (gce *GCECloud) UpdateHttpsHealthCheck(hc *compute.HttpsHealthCheck) error { +// UpdateHTTPSHealthCheck applies the given HttpsHealthCheck as an update. +func (g *Cloud) UpdateHTTPSHealthCheck(hc *compute.HttpsHealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("update_legacy") - return mc.Observe(gce.c.HttpsHealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.HttpsHealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) } -// DeleteHttpsHealthCheck deletes the given HttpsHealthCheck by name. -func (gce *GCECloud) DeleteHttpsHealthCheck(name string) error { +// DeleteHTTPSHealthCheck deletes the given HttpsHealthCheck by name. +func (g *Cloud) DeleteHTTPSHealthCheck(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("delete_legacy") - return mc.Observe(gce.c.HttpsHealthChecks().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.HttpsHealthChecks().Delete(ctx, meta.GlobalKey(name))) } -// CreateHttpsHealthCheck creates the given HttpsHealthCheck. -func (gce *GCECloud) CreateHttpsHealthCheck(hc *compute.HttpsHealthCheck) error { +// CreateHTTPSHealthCheck creates the given HttpsHealthCheck. +func (g *Cloud) CreateHTTPSHealthCheck(hc *compute.HttpsHealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("create_legacy") - return mc.Observe(gce.c.HttpsHealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.HttpsHealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) } -// ListHttpsHealthChecks lists all HttpsHealthChecks in the project. -func (gce *GCECloud) ListHttpsHealthChecks() ([]*compute.HttpsHealthCheck, error) { +// ListHTTPSHealthChecks lists all HttpsHealthChecks in the project. +func (g *Cloud) ListHTTPSHealthChecks() ([]*compute.HttpsHealthCheck, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("list_legacy") - v, err := gce.c.HttpsHealthChecks().List(ctx, filter.None) + v, err := g.c.HttpsHealthChecks().List(ctx, filter.None) return v, mc.Observe(err) } // Generic HealthCheck // GetHealthCheck returns the given HealthCheck by name. -func (gce *GCECloud) GetHealthCheck(name string) (*compute.HealthCheck, error) { +func (g *Cloud) GetHealthCheck(name string) (*compute.HealthCheck, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("get") - v, err := gce.c.HealthChecks().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.HealthChecks().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // GetAlphaHealthCheck returns the given alpha HealthCheck by name. -func (gce *GCECloud) GetAlphaHealthCheck(name string) (*computealpha.HealthCheck, error) { +func (g *Cloud) GetAlphaHealthCheck(name string) (*computealpha.HealthCheck, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContextWithVersion("get", computeAlphaVersion) - v, err := gce.c.AlphaHealthChecks().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.AlphaHealthChecks().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // GetBetaHealthCheck returns the given beta HealthCheck by name. -func (gce *GCECloud) GetBetaHealthCheck(name string) (*computebeta.HealthCheck, error) { +func (g *Cloud) GetBetaHealthCheck(name string) (*computebeta.HealthCheck, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContextWithVersion("get", computeBetaVersion) - v, err := gce.c.BetaHealthChecks().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.BetaHealthChecks().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // UpdateHealthCheck applies the given HealthCheck as an update. -func (gce *GCECloud) UpdateHealthCheck(hc *compute.HealthCheck) error { +func (g *Cloud) UpdateHealthCheck(hc *compute.HealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("update") - return mc.Observe(gce.c.HealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.HealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) } // UpdateAlphaHealthCheck applies the given alpha HealthCheck as an update. -func (gce *GCECloud) UpdateAlphaHealthCheck(hc *computealpha.HealthCheck) error { +func (g *Cloud) UpdateAlphaHealthCheck(hc *computealpha.HealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContextWithVersion("update", computeAlphaVersion) - return mc.Observe(gce.c.AlphaHealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.AlphaHealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) } // UpdateBetaHealthCheck applies the given beta HealthCheck as an update. -func (gce *GCECloud) UpdateBetaHealthCheck(hc *computebeta.HealthCheck) error { +func (g *Cloud) UpdateBetaHealthCheck(hc *computebeta.HealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContextWithVersion("update", computeBetaVersion) - return mc.Observe(gce.c.BetaHealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.BetaHealthChecks().Update(ctx, meta.GlobalKey(hc.Name), hc)) } // DeleteHealthCheck deletes the given HealthCheck by name. -func (gce *GCECloud) DeleteHealthCheck(name string) error { +func (g *Cloud) DeleteHealthCheck(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("delete") - return mc.Observe(gce.c.HealthChecks().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.HealthChecks().Delete(ctx, meta.GlobalKey(name))) } // CreateHealthCheck creates the given HealthCheck. -func (gce *GCECloud) CreateHealthCheck(hc *compute.HealthCheck) error { +func (g *Cloud) CreateHealthCheck(hc *compute.HealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("create") - return mc.Observe(gce.c.HealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.HealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) } // CreateAlphaHealthCheck creates the given alpha HealthCheck. -func (gce *GCECloud) CreateAlphaHealthCheck(hc *computealpha.HealthCheck) error { +func (g *Cloud) CreateAlphaHealthCheck(hc *computealpha.HealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContextWithVersion("create", computeAlphaVersion) - return mc.Observe(gce.c.AlphaHealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.AlphaHealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) } // CreateBetaHealthCheck creates the given beta HealthCheck. -func (gce *GCECloud) CreateBetaHealthCheck(hc *computebeta.HealthCheck) error { +func (g *Cloud) CreateBetaHealthCheck(hc *computebeta.HealthCheck) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContextWithVersion("create", computeBetaVersion) - return mc.Observe(gce.c.BetaHealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) + return mc.Observe(g.c.BetaHealthChecks().Insert(ctx, meta.GlobalKey(hc.Name), hc)) } // ListHealthChecks lists all HealthCheck in the project. -func (gce *GCECloud) ListHealthChecks() ([]*compute.HealthCheck, error) { +func (g *Cloud) ListHealthChecks() ([]*compute.HealthCheck, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newHealthcheckMetricContext("list") - v, err := gce.c.HealthChecks().List(ctx, filter.None) + v, err := g.c.HealthChecks().List(ctx, filter.None) return v, mc.Observe(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_instancegroup.go b/pkg/cloudprovider/providers/gce/gce_instancegroup.go index 13b2c51e503bf..edc5f093339bf 100644 --- a/pkg/cloudprovider/providers/gce/gce_instancegroup.go +++ b/pkg/cloudprovider/providers/gce/gce_instancegroup.go @@ -30,49 +30,49 @@ func newInstanceGroupMetricContext(request string, zone string) *metricContext { // CreateInstanceGroup creates an instance group with the given // instances. It is the callers responsibility to add named ports. -func (gce *GCECloud) CreateInstanceGroup(ig *compute.InstanceGroup, zone string) error { +func (g *Cloud) CreateInstanceGroup(ig *compute.InstanceGroup, zone string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newInstanceGroupMetricContext("create", zone) - return mc.Observe(gce.c.InstanceGroups().Insert(ctx, meta.ZonalKey(ig.Name, zone), ig)) + return mc.Observe(g.c.InstanceGroups().Insert(ctx, meta.ZonalKey(ig.Name, zone), ig)) } // DeleteInstanceGroup deletes an instance group. -func (gce *GCECloud) DeleteInstanceGroup(name string, zone string) error { +func (g *Cloud) DeleteInstanceGroup(name string, zone string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newInstanceGroupMetricContext("delete", zone) - return mc.Observe(gce.c.InstanceGroups().Delete(ctx, meta.ZonalKey(name, zone))) + return mc.Observe(g.c.InstanceGroups().Delete(ctx, meta.ZonalKey(name, zone))) } // ListInstanceGroups lists all InstanceGroups in the project and // zone. -func (gce *GCECloud) ListInstanceGroups(zone string) ([]*compute.InstanceGroup, error) { +func (g *Cloud) ListInstanceGroups(zone string) ([]*compute.InstanceGroup, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newInstanceGroupMetricContext("list", zone) - v, err := gce.c.InstanceGroups().List(ctx, zone, filter.None) + v, err := g.c.InstanceGroups().List(ctx, zone, filter.None) return v, mc.Observe(err) } // ListInstancesInInstanceGroup lists all the instances in a given // instance group and state. -func (gce *GCECloud) ListInstancesInInstanceGroup(name string, zone string, state string) ([]*compute.InstanceWithNamedPorts, error) { +func (g *Cloud) ListInstancesInInstanceGroup(name string, zone string, state string) ([]*compute.InstanceWithNamedPorts, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newInstanceGroupMetricContext("list_instances", zone) req := &compute.InstanceGroupsListInstancesRequest{InstanceState: state} - v, err := gce.c.InstanceGroups().ListInstances(ctx, meta.ZonalKey(name, zone), req, filter.None) + v, err := g.c.InstanceGroups().ListInstances(ctx, meta.ZonalKey(name, zone), req, filter.None) return v, mc.Observe(err) } // AddInstancesToInstanceGroup adds the given instances to the given // instance group. -func (gce *GCECloud) AddInstancesToInstanceGroup(name string, zone string, instanceRefs []*compute.InstanceReference) error { +func (g *Cloud) AddInstancesToInstanceGroup(name string, zone string, instanceRefs []*compute.InstanceReference) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -84,12 +84,12 @@ func (gce *GCECloud) AddInstancesToInstanceGroup(name string, zone string, insta req := &compute.InstanceGroupsAddInstancesRequest{ Instances: instanceRefs, } - return mc.Observe(gce.c.InstanceGroups().AddInstances(ctx, meta.ZonalKey(name, zone), req)) + return mc.Observe(g.c.InstanceGroups().AddInstances(ctx, meta.ZonalKey(name, zone), req)) } // RemoveInstancesFromInstanceGroup removes the given instances from // the instance group. -func (gce *GCECloud) RemoveInstancesFromInstanceGroup(name string, zone string, instanceRefs []*compute.InstanceReference) error { +func (g *Cloud) RemoveInstancesFromInstanceGroup(name string, zone string, instanceRefs []*compute.InstanceReference) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -101,25 +101,25 @@ func (gce *GCECloud) RemoveInstancesFromInstanceGroup(name string, zone string, req := &compute.InstanceGroupsRemoveInstancesRequest{ Instances: instanceRefs, } - return mc.Observe(gce.c.InstanceGroups().RemoveInstances(ctx, meta.ZonalKey(name, zone), req)) + return mc.Observe(g.c.InstanceGroups().RemoveInstances(ctx, meta.ZonalKey(name, zone), req)) } // SetNamedPortsOfInstanceGroup sets the list of named ports on a given instance group -func (gce *GCECloud) SetNamedPortsOfInstanceGroup(igName, zone string, namedPorts []*compute.NamedPort) error { +func (g *Cloud) SetNamedPortsOfInstanceGroup(igName, zone string, namedPorts []*compute.NamedPort) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newInstanceGroupMetricContext("set_namedports", zone) req := &compute.InstanceGroupsSetNamedPortsRequest{NamedPorts: namedPorts} - return mc.Observe(gce.c.InstanceGroups().SetNamedPorts(ctx, meta.ZonalKey(igName, zone), req)) + return mc.Observe(g.c.InstanceGroups().SetNamedPorts(ctx, meta.ZonalKey(igName, zone), req)) } // GetInstanceGroup returns an instance group by name. -func (gce *GCECloud) GetInstanceGroup(name string, zone string) (*compute.InstanceGroup, error) { +func (g *Cloud) GetInstanceGroup(name string, zone string) (*compute.InstanceGroup, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newInstanceGroupMetricContext("get", zone) - v, err := gce.c.InstanceGroups().Get(ctx, meta.ZonalKey(name, zone)) + v, err := g.c.InstanceGroups().Get(ctx, meta.ZonalKey(name, zone)) return v, mc.Observe(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_instances.go b/pkg/cloudprovider/providers/gce/gce_instances.go index ff2dce89c37a8..f97d89648f852 100644 --- a/pkg/cloudprovider/providers/gce/gce_instances.go +++ b/pkg/cloudprovider/providers/gce/gce_instances.go @@ -67,22 +67,22 @@ func getZone(n *v1.Node) string { return zone } -func makeHostURL(projectsApiEndpoint, projectID, zone, host string) string { +func makeHostURL(projectsAPIEndpoint, projectID, zone, host string) string { host = canonicalizeInstanceName(host) - return projectsApiEndpoint + strings.Join([]string{projectID, "zones", zone, "instances", host}, "/") + return projectsAPIEndpoint + strings.Join([]string{projectID, "zones", zone, "instances", host}, "/") } // ToInstanceReferences returns instance references by links -func (gce *GCECloud) ToInstanceReferences(zone string, instanceNames []string) (refs []*compute.InstanceReference) { +func (g *Cloud) ToInstanceReferences(zone string, instanceNames []string) (refs []*compute.InstanceReference) { for _, ins := range instanceNames { - instanceLink := makeHostURL(gce.service.BasePath, gce.projectID, zone, ins) + instanceLink := makeHostURL(g.service.BasePath, g.projectID, zone, ins) refs = append(refs, &compute.InstanceReference{Instance: instanceLink}) } return refs } // NodeAddresses is an implementation of Instances.NodeAddresses. -func (gce *GCECloud) NodeAddresses(_ context.Context, _ types.NodeName) ([]v1.NodeAddress, error) { +func (g *Cloud) NodeAddresses(_ context.Context, _ types.NodeName) ([]v1.NodeAddress, error) { internalIP, err := metadata.Get("instance/network-interfaces/0/ip") if err != nil { return nil, fmt.Errorf("couldn't get internal IP: %v", err) @@ -109,7 +109,7 @@ func (gce *GCECloud) NodeAddresses(_ context.Context, _ types.NodeName) ([]v1.No // NodeAddressesByProviderID will not be called from the node that is requesting this ID. // i.e. metadata service and other local methods cannot be used here -func (gce *GCECloud) NodeAddressesByProviderID(ctx context.Context, providerID string) ([]v1.NodeAddress, error) { +func (g *Cloud) NodeAddressesByProviderID(ctx context.Context, providerID string) ([]v1.NodeAddress, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -118,7 +118,7 @@ func (gce *GCECloud) NodeAddressesByProviderID(ctx context.Context, providerID s return []v1.NodeAddress{}, err } - instance, err := gce.c.Instances().Get(ctx, meta.ZonalKey(canonicalizeInstanceName(name), zone)) + instance, err := g.c.Instances().Get(ctx, meta.ZonalKey(canonicalizeInstanceName(name), zone)) if err != nil { return []v1.NodeAddress{}, fmt.Errorf("error while querying for providerID %q: %v", providerID, err) } @@ -138,13 +138,13 @@ func (gce *GCECloud) NodeAddressesByProviderID(ctx context.Context, providerID s // instanceByProviderID returns the cloudprovider instance of the node // with the specified unique providerID -func (gce *GCECloud) instanceByProviderID(providerID string) (*gceInstance, error) { +func (g *Cloud) instanceByProviderID(providerID string) (*gceInstance, error) { project, zone, name, err := splitProviderID(providerID) if err != nil { return nil, err } - instance, err := gce.getInstanceFromProjectInZoneByName(project, zone, name) + instance, err := g.getInstanceFromProjectInZoneByName(project, zone, name) if err != nil { if isHTTPErrorCode(err, http.StatusNotFound) { return nil, cloudprovider.InstanceNotFound @@ -156,7 +156,7 @@ func (gce *GCECloud) instanceByProviderID(providerID string) (*gceInstance, erro } // InstanceShutdownByProviderID returns true if the instance is in safe state to detach volumes -func (gce *GCECloud) InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) { +func (g *Cloud) InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) { return false, cloudprovider.NotImplemented } @@ -164,8 +164,8 @@ func (gce *GCECloud) InstanceShutdownByProviderID(ctx context.Context, providerI // with the specified unique providerID This method will not be called from the // node that is requesting this ID. i.e. metadata service and other local // methods cannot be used here -func (gce *GCECloud) InstanceTypeByProviderID(ctx context.Context, providerID string) (string, error) { - instance, err := gce.instanceByProviderID(providerID) +func (g *Cloud) InstanceTypeByProviderID(ctx context.Context, providerID string) (string, error) { + instance, err := g.instanceByProviderID(providerID) if err != nil { return "", err } @@ -175,8 +175,8 @@ func (gce *GCECloud) InstanceTypeByProviderID(ctx context.Context, providerID st // InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running. // If false is returned with no error, the instance will be immediately deleted by the cloud controller manager. -func (gce *GCECloud) InstanceExistsByProviderID(ctx context.Context, providerID string) (bool, error) { - _, err := gce.instanceByProviderID(providerID) +func (g *Cloud) InstanceExistsByProviderID(ctx context.Context, providerID string) (bool, error) { + _, err := g.instanceByProviderID(providerID) if err != nil { if err == cloudprovider.InstanceNotFound { return false, nil @@ -188,49 +188,51 @@ func (gce *GCECloud) InstanceExistsByProviderID(ctx context.Context, providerID } // InstanceID returns the cloud provider ID of the node with the specified NodeName. -func (gce *GCECloud) InstanceID(ctx context.Context, nodeName types.NodeName) (string, error) { +func (g *Cloud) InstanceID(ctx context.Context, nodeName types.NodeName) (string, error) { instanceName := mapNodeNameToInstanceName(nodeName) - if gce.useMetadataServer { + if g.useMetadataServer { // Use metadata, if possible, to fetch ID. See issue #12000 - if gce.isCurrentInstance(instanceName) { + if g.isCurrentInstance(instanceName) { projectID, zone, err := getProjectAndZone() if err == nil { return projectID + "/" + zone + "/" + canonicalizeInstanceName(instanceName), nil } } } - instance, err := gce.getInstanceByName(instanceName) + instance, err := g.getInstanceByName(instanceName) if err != nil { return "", err } - return gce.projectID + "/" + instance.Zone + "/" + instance.Name, nil + return g.projectID + "/" + instance.Zone + "/" + instance.Name, nil } // InstanceType returns the type of the specified node with the specified NodeName. -func (gce *GCECloud) InstanceType(ctx context.Context, nodeName types.NodeName) (string, error) { +func (g *Cloud) InstanceType(ctx context.Context, nodeName types.NodeName) (string, error) { instanceName := mapNodeNameToInstanceName(nodeName) - if gce.useMetadataServer { + if g.useMetadataServer { // Use metadata, if possible, to fetch ID. See issue #12000 - if gce.isCurrentInstance(instanceName) { + if g.isCurrentInstance(instanceName) { mType, err := getCurrentMachineTypeViaMetadata() if err == nil { return mType, nil } } } - instance, err := gce.getInstanceByName(instanceName) + instance, err := g.getInstanceByName(instanceName) if err != nil { return "", err } return instance.Type, nil } -func (gce *GCECloud) AddSSHKeyToAllInstances(ctx context.Context, user string, keyData []byte) error { +// AddSSHKeyToAllInstances adds an SSH public key as a legal identity for all instances +// expected format for the key is standard ssh-keygen format: +func (g *Cloud) AddSSHKeyToAllInstances(ctx context.Context, user string, keyData []byte) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() return wait.Poll(2*time.Second, 30*time.Second, func() (bool, error) { - project, err := gce.c.Projects().Get(ctx, gce.projectID) + project, err := g.c.Projects().Get(ctx, g.projectID) if err != nil { glog.Errorf("Could not get project: %v", err) return false, nil @@ -261,7 +263,7 @@ func (gce *GCECloud) AddSSHKeyToAllInstances(ctx context.Context, user string, k } mc := newInstancesMetricContext("add_ssh_key", "") - err = gce.c.Projects().SetCommonInstanceMetadata(ctx, gce.projectID, project.CommonInstanceMetadata) + err = g.c.Projects().SetCommonInstanceMetadata(ctx, g.projectID, project.CommonInstanceMetadata) mc.Observe(err) if err != nil { @@ -274,18 +276,18 @@ func (gce *GCECloud) AddSSHKeyToAllInstances(ctx context.Context, user string, k } // GetAllCurrentZones returns all the zones in which k8s nodes are currently running -func (gce *GCECloud) GetAllCurrentZones() (sets.String, error) { - if gce.nodeInformerSynced == nil { - glog.Warningf("GCECloud object does not have informers set, should only happen in E2E binary.") - return gce.GetAllZonesFromCloudProvider() - } - gce.nodeZonesLock.Lock() - defer gce.nodeZonesLock.Unlock() - if !gce.nodeInformerSynced() { +func (g *Cloud) GetAllCurrentZones() (sets.String, error) { + if g.nodeInformerSynced == nil { + glog.Warningf("Cloud object does not have informers set, should only happen in E2E binary.") + return g.GetAllZonesFromCloudProvider() + } + g.nodeZonesLock.Lock() + defer g.nodeZonesLock.Unlock() + if !g.nodeInformerSynced() { return nil, fmt.Errorf("node informer is not synced when trying to GetAllCurrentZones") } zones := sets.NewString() - for zone, nodes := range gce.nodeZones { + for zone, nodes := range g.nodeZones { if len(nodes) > 0 { zones.Insert(zone) } @@ -300,13 +302,13 @@ func (gce *GCECloud) GetAllCurrentZones() (sets.String, error) { // a non-k8s compute in us-central1-a. This func will return a,b, and c. // // TODO: this should be removed from the cloud provider. -func (gce *GCECloud) GetAllZonesFromCloudProvider() (sets.String, error) { +func (g *Cloud) GetAllZonesFromCloudProvider() (sets.String, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() zones := sets.NewString() - for _, zone := range gce.managedZones { - instances, err := gce.c.Instances().List(ctx, zone, filter.None) + for _, zone := range g.managedZones { + instances, err := g.c.Instances().List(ctx, zone, filter.None) if err != nil { return sets.NewString(), err } @@ -318,22 +320,22 @@ func (gce *GCECloud) GetAllZonesFromCloudProvider() (sets.String, error) { } // InsertInstance creates a new instance on GCP -func (gce *GCECloud) InsertInstance(project string, zone string, i *compute.Instance) error { +func (g *Cloud) InsertInstance(project string, zone string, i *compute.Instance) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newInstancesMetricContext("create", zone) - return mc.Observe(gce.c.Instances().Insert(ctx, meta.ZonalKey(i.Name, zone), i)) + return mc.Observe(g.c.Instances().Insert(ctx, meta.ZonalKey(i.Name, zone), i)) } // ListInstanceNames returns a string of instance names separated by spaces. // This method should only be used for e2e testing. // TODO: remove this method. -func (gce *GCECloud) ListInstanceNames(project, zone string) (string, error) { +func (g *Cloud) ListInstanceNames(project, zone string) (string, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() - l, err := gce.c.Instances().List(ctx, zone, filter.None) + l, err := g.c.Instances().List(ctx, zone, filter.None) if err != nil { return "", err } @@ -345,33 +347,34 @@ func (gce *GCECloud) ListInstanceNames(project, zone string) (string, error) { } // DeleteInstance deletes an instance specified by project, zone, and name -func (gce *GCECloud) DeleteInstance(project, zone, name string) error { +func (g *Cloud) DeleteInstance(project, zone, name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() - return gce.c.Instances().Delete(ctx, meta.ZonalKey(name, zone)) + return g.c.Instances().Delete(ctx, meta.ZonalKey(name, zone)) } -// Implementation of Instances.CurrentNodeName -func (gce *GCECloud) CurrentNodeName(ctx context.Context, hostname string) (types.NodeName, error) { +// CurrentNodeName returns the name of the node we are currently running on +// On most clouds (e.g. GCE) this is the hostname, so we provide the hostname +func (g *Cloud) CurrentNodeName(ctx context.Context, hostname string) (types.NodeName, error) { return types.NodeName(hostname), nil } // AliasRanges returns a list of CIDR ranges that are assigned to the // `node` for allocation to pods. Returns a list of the form // "/". -func (gce *GCECloud) AliasRanges(nodeName types.NodeName) (cidrs []string, err error) { +func (g *Cloud) AliasRanges(nodeName types.NodeName) (cidrs []string, err error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() var instance *gceInstance - instance, err = gce.getInstanceByName(mapNodeNameToInstanceName(nodeName)) + instance, err = g.getInstanceByName(mapNodeNameToInstanceName(nodeName)) if err != nil { return } var res *computebeta.Instance - res, err = gce.c.BetaInstances().Get(ctx, meta.ZonalKey(instance.Name, lastComponent(instance.Zone))) + res, err = g.c.BetaInstances().Get(ctx, meta.ZonalKey(instance.Name, lastComponent(instance.Zone))) if err != nil { return } @@ -386,15 +389,15 @@ func (gce *GCECloud) AliasRanges(nodeName types.NodeName) (cidrs []string, err e // AddAliasToInstance adds an alias to the given instance from the named // secondary range. -func (gce *GCECloud) AddAliasToInstance(nodeName types.NodeName, alias *net.IPNet) error { +func (g *Cloud) AddAliasToInstance(nodeName types.NodeName, alias *net.IPNet) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() - v1instance, err := gce.getInstanceByName(mapNodeNameToInstanceName(nodeName)) + v1instance, err := g.getInstanceByName(mapNodeNameToInstanceName(nodeName)) if err != nil { return err } - instance, err := gce.c.BetaInstances().Get(ctx, meta.ZonalKey(v1instance.Name, lastComponent(v1instance.Zone))) + instance, err := g.c.BetaInstances().Get(ctx, meta.ZonalKey(v1instance.Name, lastComponent(v1instance.Zone))) if err != nil { return err } @@ -413,38 +416,38 @@ func (gce *GCECloud) AddAliasToInstance(nodeName types.NodeName, alias *net.IPNe iface.Fingerprint = instance.NetworkInterfaces[0].Fingerprint iface.AliasIpRanges = append(iface.AliasIpRanges, &computebeta.AliasIpRange{ IpCidrRange: alias.String(), - SubnetworkRangeName: gce.secondaryRangeName, + SubnetworkRangeName: g.secondaryRangeName, }) mc := newInstancesMetricContext("add_alias", v1instance.Zone) - err = gce.c.BetaInstances().UpdateNetworkInterface(ctx, meta.ZonalKey(instance.Name, lastComponent(instance.Zone)), iface.Name, iface) + err = g.c.BetaInstances().UpdateNetworkInterface(ctx, meta.ZonalKey(instance.Name, lastComponent(instance.Zone)), iface.Name, iface) return mc.Observe(err) } // Gets the named instances, returning cloudprovider.InstanceNotFound if any // instance is not found -func (gce *GCECloud) getInstancesByNames(names []string) ([]*gceInstance, error) { +func (g *Cloud) getInstancesByNames(names []string) ([]*gceInstance, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() found := map[string]*gceInstance{} remaining := len(names) - nodeInstancePrefix := gce.nodeInstancePrefix + nodeInstancePrefix := g.nodeInstancePrefix for _, name := range names { name = canonicalizeInstanceName(name) - if !strings.HasPrefix(name, gce.nodeInstancePrefix) { - glog.Warningf("Instance %q does not conform to prefix %q, removing filter", name, gce.nodeInstancePrefix) + if !strings.HasPrefix(name, g.nodeInstancePrefix) { + glog.Warningf("Instance %q does not conform to prefix %q, removing filter", name, g.nodeInstancePrefix) nodeInstancePrefix = "" } found[name] = nil } - for _, zone := range gce.managedZones { + for _, zone := range g.managedZones { if remaining == 0 { break } - instances, err := gce.c.Instances().List(ctx, zone, filter.Regexp("name", nodeInstancePrefix+".*")) + instances, err := g.c.Instances().List(ctx, zone, filter.Regexp("name", nodeInstancePrefix+".*")) if err != nil { return nil, err } @@ -490,10 +493,10 @@ func (gce *GCECloud) getInstancesByNames(names []string) ([]*gceInstance, error) } // Gets the named instance, returning cloudprovider.InstanceNotFound if the instance is not found -func (gce *GCECloud) getInstanceByName(name string) (*gceInstance, error) { +func (g *Cloud) getInstanceByName(name string) (*gceInstance, error) { // Avoid changing behaviour when not managing multiple zones - for _, zone := range gce.managedZones { - instance, err := gce.getInstanceFromProjectInZoneByName(gce.projectID, zone, name) + for _, zone := range g.managedZones { + instance, err := g.getInstanceFromProjectInZoneByName(g.projectID, zone, name) if err != nil { if isHTTPErrorCode(err, http.StatusNotFound) { continue @@ -507,13 +510,13 @@ func (gce *GCECloud) getInstanceByName(name string) (*gceInstance, error) { return nil, cloudprovider.InstanceNotFound } -func (gce *GCECloud) getInstanceFromProjectInZoneByName(project, zone, name string) (*gceInstance, error) { +func (g *Cloud) getInstanceFromProjectInZoneByName(project, zone, name string) (*gceInstance, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() name = canonicalizeInstanceName(name) mc := newInstancesMetricContext("get", zone) - res, err := gce.c.Instances().Get(ctx, meta.ZonalKey(name, zone)) + res, err := g.c.Instances().Get(ctx, meta.ZonalKey(name, zone)) mc.Observe(err) if err != nil { return nil, err @@ -554,7 +557,7 @@ func getCurrentMachineTypeViaMetadata() (string, error) { // isCurrentInstance uses metadata server to check if specified // instanceID matches current machine's instanceID -func (gce *GCECloud) isCurrentInstance(instanceID string) bool { +func (g *Cloud) isCurrentInstance(instanceID string) bool { currentInstanceID, err := getInstanceIDViaMetadata() if err != nil { // Log and swallow error @@ -571,16 +574,16 @@ func (gce *GCECloud) isCurrentInstance(instanceID string) bool { // Invoking this method to get host tags is risky since it depends on the // format of the host names in the cluster. Only use it as a fallback if // gce.nodeTags is unspecified -func (gce *GCECloud) computeHostTags(hosts []*gceInstance) ([]string, error) { +func (g *Cloud) computeHostTags(hosts []*gceInstance) ([]string, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() // TODO: We could store the tags in gceInstance, so we could have already fetched it hostNamesByZone := make(map[string]map[string]bool) // map of zones -> map of names -> bool (for easy lookup) - nodeInstancePrefix := gce.nodeInstancePrefix + nodeInstancePrefix := g.nodeInstancePrefix for _, host := range hosts { - if !strings.HasPrefix(host.Name, gce.nodeInstancePrefix) { - glog.Warningf("instance %v does not conform to prefix '%s', ignoring filter", host, gce.nodeInstancePrefix) + if !strings.HasPrefix(host.Name, g.nodeInstancePrefix) { + glog.Warningf("instance %v does not conform to prefix '%s', ignoring filter", host, g.nodeInstancePrefix) nodeInstancePrefix = "" } @@ -599,7 +602,7 @@ func (gce *GCECloud) computeHostTags(hosts []*gceInstance) ([]string, error) { filt = filter.Regexp("name", nodeInstancePrefix+".*") } for zone, hostNames := range hostNamesByZone { - instances, err := gce.c.Instances().List(ctx, zone, filt) + instances, err := g.c.Instances().List(ctx, zone, filt) if err != nil { return nil, err } @@ -607,14 +610,14 @@ func (gce *GCECloud) computeHostTags(hosts []*gceInstance) ([]string, error) { if !hostNames[instance.Name] { continue } - longest_tag := "" + longestTag := "" for _, tag := range instance.Tags.Items { - if strings.HasPrefix(instance.Name, tag) && len(tag) > len(longest_tag) { - longest_tag = tag + if strings.HasPrefix(instance.Name, tag) && len(tag) > len(longestTag) { + longestTag = tag } } - if len(longest_tag) > 0 { - tags.Insert(longest_tag) + if len(longestTag) > 0 { + tags.Insert(longestTag) } else { return nil, fmt.Errorf("could not find any tag that is a prefix of instance name for instance %s", instance.Name) } @@ -629,35 +632,35 @@ func (gce *GCECloud) computeHostTags(hosts []*gceInstance) ([]string, error) { // GetNodeTags will first try returning the list of tags specified in GCE cloud Configuration. // If they weren't provided, it'll compute the host tags with the given hostnames. If the list // of hostnames has not changed, a cached set of nodetags are returned. -func (gce *GCECloud) GetNodeTags(nodeNames []string) ([]string, error) { +func (g *Cloud) GetNodeTags(nodeNames []string) ([]string, error) { // If nodeTags were specified through configuration, use them - if len(gce.nodeTags) > 0 { - return gce.nodeTags, nil + if len(g.nodeTags) > 0 { + return g.nodeTags, nil } - gce.computeNodeTagLock.Lock() - defer gce.computeNodeTagLock.Unlock() + g.computeNodeTagLock.Lock() + defer g.computeNodeTagLock.Unlock() // Early return if hosts have not changed hosts := sets.NewString(nodeNames...) - if hosts.Equal(gce.lastKnownNodeNames) { - return gce.lastComputedNodeTags, nil + if hosts.Equal(g.lastKnownNodeNames) { + return g.lastComputedNodeTags, nil } // Get GCE instance data by hostname - instances, err := gce.getInstancesByNames(nodeNames) + instances, err := g.getInstancesByNames(nodeNames) if err != nil { return nil, err } // Determine list of host tags - tags, err := gce.computeHostTags(instances) + tags, err := g.computeHostTags(instances) if err != nil { return nil, err } // Save the list of tags - gce.lastKnownNodeNames = hosts - gce.lastComputedNodeTags = tags + g.lastKnownNodeNames = hosts + g.lastComputedNodeTags = tags return tags, nil } diff --git a/pkg/cloudprovider/providers/gce/gce_loadbalancer.go b/pkg/cloudprovider/providers/gce/gce_loadbalancer.go index da8819d93ccef..b6e55d6e9dd39 100644 --- a/pkg/cloudprovider/providers/gce/gce_loadbalancer.go +++ b/pkg/cloudprovider/providers/gce/gce_loadbalancer.go @@ -87,9 +87,9 @@ func LoadBalancerSrcRanges() []string { } // GetLoadBalancer is an implementation of LoadBalancer.GetLoadBalancer -func (gce *GCECloud) GetLoadBalancer(ctx context.Context, clusterName string, svc *v1.Service) (*v1.LoadBalancerStatus, bool, error) { - loadBalancerName := gce.GetLoadBalancerName(ctx, clusterName, svc) - fwd, err := gce.GetRegionForwardingRule(loadBalancerName, gce.region) +func (g *Cloud) GetLoadBalancer(ctx context.Context, clusterName string, svc *v1.Service) (*v1.LoadBalancerStatus, bool, error) { + loadBalancerName := g.GetLoadBalancerName(ctx, clusterName, svc) + fwd, err := g.GetRegionForwardingRule(loadBalancerName, g.region) if err == nil { status := &v1.LoadBalancerStatus{} status.Ingress = []v1.LoadBalancerIngress{{IP: fwd.IPAddress}} @@ -100,23 +100,23 @@ func (gce *GCECloud) GetLoadBalancer(ctx context.Context, clusterName string, sv } // GetLoadBalancerName is an implementation of LoadBalancer.GetLoadBalancerName. -func (gce *GCECloud) GetLoadBalancerName(ctx context.Context, clusterName string, svc *v1.Service) string { +func (g *Cloud) GetLoadBalancerName(ctx context.Context, clusterName string, svc *v1.Service) string { // TODO: replace DefaultLoadBalancerName to generate more meaningful loadbalancer names. return cloudprovider.DefaultLoadBalancerName(svc) } // EnsureLoadBalancer is an implementation of LoadBalancer.EnsureLoadBalancer. -func (gce *GCECloud) EnsureLoadBalancer(ctx context.Context, clusterName string, svc *v1.Service, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) { - loadBalancerName := gce.GetLoadBalancerName(ctx, clusterName, svc) +func (g *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, svc *v1.Service, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) { + loadBalancerName := g.GetLoadBalancerName(ctx, clusterName, svc) desiredScheme := getSvcScheme(svc) - clusterID, err := gce.ClusterID.GetID() + clusterID, err := g.ClusterID.GetID() if err != nil { return nil, err } - glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v): ensure %v loadbalancer", clusterName, svc.Namespace, svc.Name, loadBalancerName, gce.region, desiredScheme) + glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v): ensure %v loadbalancer", clusterName, svc.Namespace, svc.Name, loadBalancerName, g.region, desiredScheme) - existingFwdRule, err := gce.GetRegionForwardingRule(loadBalancerName, gce.region) + existingFwdRule, err := g.GetRegionForwardingRule(loadBalancerName, g.region) if err != nil && !isNotFound(err) { return nil, err } @@ -126,14 +126,14 @@ func (gce *GCECloud) EnsureLoadBalancer(ctx context.Context, clusterName string, // If the loadbalancer type changes between INTERNAL and EXTERNAL, the old load balancer should be deleted. if existingScheme != desiredScheme { - glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v): deleting existing %v loadbalancer", clusterName, svc.Namespace, svc.Name, loadBalancerName, gce.region, existingScheme) + glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v): deleting existing %v loadbalancer", clusterName, svc.Namespace, svc.Name, loadBalancerName, g.region, existingScheme) switch existingScheme { case cloud.SchemeInternal: - err = gce.ensureInternalLoadBalancerDeleted(clusterName, clusterID, svc) + err = g.ensureInternalLoadBalancerDeleted(clusterName, clusterID, svc) default: - err = gce.ensureExternalLoadBalancerDeleted(clusterName, clusterID, svc) + err = g.ensureExternalLoadBalancerDeleted(clusterName, clusterID, svc) } - glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v): done deleting existing %v loadbalancer. err: %v", clusterName, svc.Namespace, svc.Name, loadBalancerName, gce.region, existingScheme, err) + glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v): done deleting existing %v loadbalancer. err: %v", clusterName, svc.Namespace, svc.Name, loadBalancerName, g.region, existingScheme, err) if err != nil { return nil, err } @@ -146,53 +146,53 @@ func (gce *GCECloud) EnsureLoadBalancer(ctx context.Context, clusterName string, var status *v1.LoadBalancerStatus switch desiredScheme { case cloud.SchemeInternal: - status, err = gce.ensureInternalLoadBalancer(clusterName, clusterID, svc, existingFwdRule, nodes) + status, err = g.ensureInternalLoadBalancer(clusterName, clusterID, svc, existingFwdRule, nodes) default: - status, err = gce.ensureExternalLoadBalancer(clusterName, clusterID, svc, existingFwdRule, nodes) + status, err = g.ensureExternalLoadBalancer(clusterName, clusterID, svc, existingFwdRule, nodes) } - glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v): done ensuring loadbalancer. err: %v", clusterName, svc.Namespace, svc.Name, loadBalancerName, gce.region, err) + glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v): done ensuring loadbalancer. err: %v", clusterName, svc.Namespace, svc.Name, loadBalancerName, g.region, err) return status, err } // UpdateLoadBalancer is an implementation of LoadBalancer.UpdateLoadBalancer. -func (gce *GCECloud) UpdateLoadBalancer(ctx context.Context, clusterName string, svc *v1.Service, nodes []*v1.Node) error { - loadBalancerName := gce.GetLoadBalancerName(ctx, clusterName, svc) +func (g *Cloud) UpdateLoadBalancer(ctx context.Context, clusterName string, svc *v1.Service, nodes []*v1.Node) error { + loadBalancerName := g.GetLoadBalancerName(ctx, clusterName, svc) scheme := getSvcScheme(svc) - clusterID, err := gce.ClusterID.GetID() + clusterID, err := g.ClusterID.GetID() if err != nil { return err } - glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v, %v, %v): updating with %d nodes", clusterName, svc.Namespace, svc.Name, loadBalancerName, gce.region, len(nodes)) + glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v, %v, %v): updating with %d nodes", clusterName, svc.Namespace, svc.Name, loadBalancerName, g.region, len(nodes)) switch scheme { case cloud.SchemeInternal: - err = gce.updateInternalLoadBalancer(clusterName, clusterID, svc, nodes) + err = g.updateInternalLoadBalancer(clusterName, clusterID, svc, nodes) default: - err = gce.updateExternalLoadBalancer(clusterName, svc, nodes) + err = g.updateExternalLoadBalancer(clusterName, svc, nodes) } - glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v, %v, %v): done updating. err: %v", clusterName, svc.Namespace, svc.Name, loadBalancerName, gce.region, err) + glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v, %v, %v): done updating. err: %v", clusterName, svc.Namespace, svc.Name, loadBalancerName, g.region, err) return err } // EnsureLoadBalancerDeleted is an implementation of LoadBalancer.EnsureLoadBalancerDeleted. -func (gce *GCECloud) EnsureLoadBalancerDeleted(ctx context.Context, clusterName string, svc *v1.Service) error { - loadBalancerName := gce.GetLoadBalancerName(ctx, clusterName, svc) +func (g *Cloud) EnsureLoadBalancerDeleted(ctx context.Context, clusterName string, svc *v1.Service) error { + loadBalancerName := g.GetLoadBalancerName(ctx, clusterName, svc) scheme := getSvcScheme(svc) - clusterID, err := gce.ClusterID.GetID() + clusterID, err := g.ClusterID.GetID() if err != nil { return err } - glog.V(4).Infof("EnsureLoadBalancerDeleted(%v, %v, %v, %v, %v): deleting loadbalancer", clusterName, svc.Namespace, svc.Name, loadBalancerName, gce.region) + glog.V(4).Infof("EnsureLoadBalancerDeleted(%v, %v, %v, %v, %v): deleting loadbalancer", clusterName, svc.Namespace, svc.Name, loadBalancerName, g.region) switch scheme { case cloud.SchemeInternal: - err = gce.ensureInternalLoadBalancerDeleted(clusterName, clusterID, svc) + err = g.ensureInternalLoadBalancerDeleted(clusterName, clusterID, svc) default: - err = gce.ensureExternalLoadBalancerDeleted(clusterName, clusterID, svc) + err = g.ensureExternalLoadBalancerDeleted(clusterName, clusterID, svc) } - glog.V(4).Infof("EnsureLoadBalancerDeleted(%v, %v, %v, %v, %v): done deleting loadbalancer. err: %v", clusterName, svc.Namespace, svc.Name, loadBalancerName, gce.region, err) + glog.V(4).Infof("EnsureLoadBalancerDeleted(%v, %v, %v, %v, %v): done deleting loadbalancer. err: %v", clusterName, svc.Namespace, svc.Name, loadBalancerName, g.region, err) return err } diff --git a/pkg/cloudprovider/providers/gce/gce_loadbalancer_external.go b/pkg/cloudprovider/providers/gce/gce_loadbalancer_external.go index 9687393b45338..62531716662e5 100644 --- a/pkg/cloudprovider/providers/gce/gce_loadbalancer_external.go +++ b/pkg/cloudprovider/providers/gce/gce_loadbalancer_external.go @@ -44,19 +44,19 @@ import ( // Due to an interesting series of design decisions, this handles both creating // new load balancers and updating existing load balancers, recognizing when // each is needed. -func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID string, apiService *v1.Service, existingFwdRule *compute.ForwardingRule, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) { +func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string, apiService *v1.Service, existingFwdRule *compute.ForwardingRule, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) { if len(nodes) == 0 { return nil, fmt.Errorf("Cannot EnsureLoadBalancer() with no hosts") } hostNames := nodeNames(nodes) supportsNodesHealthCheck := supportsNodesHealthCheck(nodes) - hosts, err := gce.getInstancesByNames(hostNames) + hosts, err := g.getInstancesByNames(hostNames) if err != nil { return nil, err } - loadBalancerName := gce.GetLoadBalancerName(context.TODO(), clusterName, apiService) + loadBalancerName := g.GetLoadBalancerName(context.TODO(), clusterName, apiService) requestedIP := apiService.Spec.LoadBalancerIP ports := apiService.Spec.Ports portStr := []string{} @@ -66,22 +66,22 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st serviceName := types.NamespacedName{Namespace: apiService.Namespace, Name: apiService.Name} lbRefStr := fmt.Sprintf("%v(%v)", loadBalancerName, serviceName) - glog.V(2).Infof("ensureExternalLoadBalancer(%s, %v, %v, %v, %v, %v)", lbRefStr, gce.region, requestedIP, portStr, hostNames, apiService.Annotations) + glog.V(2).Infof("ensureExternalLoadBalancer(%s, %v, %v, %v, %v, %v)", lbRefStr, g.region, requestedIP, portStr, hostNames, apiService.Annotations) // Check the current and the desired network tiers. If they do not match, // tear down the existing resources with the wrong tier. - netTier, err := gce.getServiceNetworkTier(apiService) + netTier, err := g.getServiceNetworkTier(apiService) if err != nil { glog.Errorf("ensureExternalLoadBalancer(%s): Failed to get the desired network tier: %v.", lbRefStr, err) return nil, err } glog.V(4).Infof("ensureExternalLoadBalancer(%s): Desired network tier %q.", lbRefStr, netTier) - if gce.AlphaFeatureGate.Enabled(AlphaFeatureNetworkTiers) { - gce.deleteWrongNetworkTieredResources(loadBalancerName, lbRefStr, netTier) + if g.AlphaFeatureGate.Enabled(AlphaFeatureNetworkTiers) { + g.deleteWrongNetworkTieredResources(loadBalancerName, lbRefStr, netTier) } // Check if the forwarding rule exists, and if so, what its IP is. - fwdRuleExists, fwdRuleNeedsUpdate, fwdRuleIP, err := gce.forwardingRuleNeedsUpdate(loadBalancerName, gce.region, requestedIP, ports) + fwdRuleExists, fwdRuleNeedsUpdate, fwdRuleIP, err := g.forwardingRuleNeedsUpdate(loadBalancerName, g.region, requestedIP, ports) if err != nil { return nil, err } @@ -120,22 +120,22 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st return } if isSafeToReleaseIP { - if err := gce.DeleteRegionAddress(loadBalancerName, gce.region); err != nil && !isNotFound(err) { - glog.Errorf("ensureExternalLoadBalancer(%s): Failed to release static IP %s in region %v: %v.", lbRefStr, ipAddressToUse, gce.region, err) + if err := g.DeleteRegionAddress(loadBalancerName, g.region); err != nil && !isNotFound(err) { + glog.Errorf("ensureExternalLoadBalancer(%s): Failed to release static IP %s in region %v: %v.", lbRefStr, ipAddressToUse, g.region, err) } else if isNotFound(err) { glog.V(2).Infof("ensureExternalLoadBalancer(%s): IP address %s is not reserved.", lbRefStr, ipAddressToUse) } else { glog.Infof("ensureExternalLoadBalancer(%s): Released static IP %s.", lbRefStr, ipAddressToUse) } } else { - glog.Warningf("ensureExternalLoadBalancer(%s): Orphaning static IP %s in region %v: %v.", lbRefStr, ipAddressToUse, gce.region, err) + glog.Warningf("ensureExternalLoadBalancer(%s): Orphaning static IP %s in region %v: %v.", lbRefStr, ipAddressToUse, g.region, err) } }() if requestedIP != "" { // If user requests a specific IP address, verify first. No mutation to // the GCE resources will be performed in the verification process. - isUserOwnedIP, err = verifyUserRequestedIP(gce, gce.region, requestedIP, fwdRuleIP, lbRefStr, netTier) + isUserOwnedIP, err = verifyUserRequestedIP(g, g.region, requestedIP, fwdRuleIP, lbRefStr, netTier) if err != nil { return nil, err } @@ -145,7 +145,7 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st if !isUserOwnedIP { // If we are not using the user-owned IP, either promote the // emphemeral IP used by the fwd rule, or create a new static IP. - ipAddr, existed, err := ensureStaticIP(gce, loadBalancerName, serviceName.String(), gce.region, fwdRuleIP, netTier) + ipAddr, existed, err := ensureStaticIP(g, loadBalancerName, serviceName.String(), g.region, fwdRuleIP, netTier) if err != nil { return nil, fmt.Errorf("failed to ensure a static IP for load balancer (%s): %v", lbRefStr, err) } @@ -167,7 +167,7 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st return nil, err } - firewallExists, firewallNeedsUpdate, err := gce.firewallNeedsUpdate(loadBalancerName, serviceName.String(), gce.region, ipAddressToUse, ports, sourceRanges) + firewallExists, firewallNeedsUpdate, err := g.firewallNeedsUpdate(loadBalancerName, serviceName.String(), g.region, ipAddressToUse, ports, sourceRanges) if err != nil { return nil, err } @@ -178,20 +178,20 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st // without needing to be deleted and recreated. if firewallExists { glog.Infof("ensureExternalLoadBalancer(%s): Updating firewall.", lbRefStr) - if err := gce.updateFirewall(apiService, MakeFirewallName(loadBalancerName), gce.region, desc, sourceRanges, ports, hosts); err != nil { + if err := g.updateFirewall(apiService, MakeFirewallName(loadBalancerName), g.region, desc, sourceRanges, ports, hosts); err != nil { return nil, err } glog.Infof("ensureExternalLoadBalancer(%s): Updated firewall.", lbRefStr) } else { glog.Infof("ensureExternalLoadBalancer(%s): Creating firewall.", lbRefStr) - if err := gce.createFirewall(apiService, MakeFirewallName(loadBalancerName), gce.region, desc, sourceRanges, ports, hosts); err != nil { + if err := g.createFirewall(apiService, MakeFirewallName(loadBalancerName), g.region, desc, sourceRanges, ports, hosts); err != nil { return nil, err } glog.Infof("ensureExternalLoadBalancer(%s): Created firewall.", lbRefStr) } } - tpExists, tpNeedsRecreation, err := gce.targetPoolNeedsRecreation(loadBalancerName, gce.region, apiService.Spec.SessionAffinity) + tpExists, tpNeedsRecreation, err := g.targetPoolNeedsRecreation(loadBalancerName, g.region, apiService.Spec.SessionAffinity) if err != nil { return nil, err } @@ -202,7 +202,7 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st // Check which health check needs to create and which health check needs to delete. // Health check management is coupled with target pool operation to prevent leaking. var hcToCreate, hcToDelete *compute.HttpHealthCheck - hcLocalTrafficExisting, err := gce.GetHttpHealthCheck(loadBalancerName) + hcLocalTrafficExisting, err := g.GetHTTPHealthCheck(loadBalancerName) if err != nil && !isHTTPErrorCode(err, http.StatusNotFound) { return nil, fmt.Errorf("error checking HTTP health check for load balancer (%s): %v", lbRefStr, err) } @@ -214,11 +214,11 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st // target pool to use local traffic health check. glog.V(2).Infof("ensureExternalLoadBalancer(%s): Updating from nodes health checks to local traffic health checks.", lbRefStr) if supportsNodesHealthCheck { - hcToDelete = makeHttpHealthCheck(MakeNodesHealthCheckName(clusterID), GetNodesHealthCheckPath(), GetNodesHealthCheckPort()) + hcToDelete = makeHTTPHealthCheck(MakeNodesHealthCheckName(clusterID), GetNodesHealthCheckPath(), GetNodesHealthCheckPort()) } tpNeedsRecreation = true } - hcToCreate = makeHttpHealthCheck(loadBalancerName, path, healthCheckNodePort) + hcToCreate = makeHTTPHealthCheck(loadBalancerName, path, healthCheckNodePort) } else { glog.V(4).Infof("ensureExternalLoadBalancer(%s): Service needs nodes health checks.", lbRefStr) if hcLocalTrafficExisting != nil { @@ -230,7 +230,7 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st tpNeedsRecreation = true } if supportsNodesHealthCheck { - hcToCreate = makeHttpHealthCheck(MakeNodesHealthCheckName(clusterID), GetNodesHealthCheckPath(), GetNodesHealthCheckPort()) + hcToCreate = makeHTTPHealthCheck(MakeNodesHealthCheckName(clusterID), GetNodesHealthCheckPath(), GetNodesHealthCheckPort()) } } // Now we get to some slightly more interesting logic. @@ -245,19 +245,19 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st // and something should fail before we recreate it, don't release the // IP. That way we can come back to it later. isSafeToReleaseIP = false - if err := gce.DeleteRegionForwardingRule(loadBalancerName, gce.region); err != nil && !isNotFound(err) { + if err := g.DeleteRegionForwardingRule(loadBalancerName, g.region); err != nil && !isNotFound(err) { return nil, fmt.Errorf("failed to delete existing forwarding rule for load balancer (%s) update: %v", lbRefStr, err) } glog.Infof("ensureExternalLoadBalancer(%s): Deleted forwarding rule.", lbRefStr) } - if err := gce.ensureTargetPoolAndHealthCheck(tpExists, tpNeedsRecreation, apiService, loadBalancerName, clusterID, ipAddressToUse, hosts, hcToCreate, hcToDelete); err != nil { + if err := g.ensureTargetPoolAndHealthCheck(tpExists, tpNeedsRecreation, apiService, loadBalancerName, clusterID, ipAddressToUse, hosts, hcToCreate, hcToDelete); err != nil { return nil, err } if tpNeedsRecreation || fwdRuleNeedsUpdate { glog.Infof("ensureExternalLoadBalancer(%s): Creating forwarding rule, IP %s (tier: %s).", lbRefStr, ipAddressToUse, netTier) - if err := createForwardingRule(gce, loadBalancerName, serviceName.String(), gce.region, ipAddressToUse, gce.targetPoolURL(loadBalancerName), ports, netTier); err != nil { + if err := createForwardingRule(g, loadBalancerName, serviceName.String(), g.region, ipAddressToUse, g.targetPoolURL(loadBalancerName), ports, netTier); err != nil { return nil, fmt.Errorf("failed to create forwarding rule for load balancer (%s): %v", lbRefStr, err) } // End critical section. It is safe to release the static IP (which @@ -275,25 +275,25 @@ func (gce *GCECloud) ensureExternalLoadBalancer(clusterName string, clusterID st } // updateExternalLoadBalancer is the external implementation of LoadBalancer.UpdateLoadBalancer. -func (gce *GCECloud) updateExternalLoadBalancer(clusterName string, service *v1.Service, nodes []*v1.Node) error { - hosts, err := gce.getInstancesByNames(nodeNames(nodes)) +func (g *Cloud) updateExternalLoadBalancer(clusterName string, service *v1.Service, nodes []*v1.Node) error { + hosts, err := g.getInstancesByNames(nodeNames(nodes)) if err != nil { return err } - loadBalancerName := gce.GetLoadBalancerName(context.TODO(), clusterName, service) - return gce.updateTargetPool(loadBalancerName, hosts) + loadBalancerName := g.GetLoadBalancerName(context.TODO(), clusterName, service) + return g.updateTargetPool(loadBalancerName, hosts) } // ensureExternalLoadBalancerDeleted is the external implementation of LoadBalancer.EnsureLoadBalancerDeleted -func (gce *GCECloud) ensureExternalLoadBalancerDeleted(clusterName, clusterID string, service *v1.Service) error { - loadBalancerName := gce.GetLoadBalancerName(context.TODO(), clusterName, service) +func (g *Cloud) ensureExternalLoadBalancerDeleted(clusterName, clusterID string, service *v1.Service) error { + loadBalancerName := g.GetLoadBalancerName(context.TODO(), clusterName, service) serviceName := types.NamespacedName{Namespace: service.Namespace, Name: service.Name} lbRefStr := fmt.Sprintf("%v(%v)", loadBalancerName, serviceName) var hcNames []string if path, _ := apiservice.GetServiceHealthCheckPathPort(service); path != "" { - hcToDelete, err := gce.GetHttpHealthCheck(loadBalancerName) + hcToDelete, err := g.GetHTTPHealthCheck(loadBalancerName) if err != nil && !isHTTPErrorCode(err, http.StatusNotFound) { glog.Infof("ensureExternalLoadBalancerDeleted(%s): Failed to retrieve health check:%v.", lbRefStr, err) return err @@ -315,10 +315,10 @@ func (gce *GCECloud) ensureExternalLoadBalancerDeleted(clusterName, clusterID st func() error { glog.Infof("ensureExternalLoadBalancerDeleted(%s): Deleting firewall rule.", lbRefStr) fwName := MakeFirewallName(loadBalancerName) - err := ignoreNotFound(gce.DeleteFirewall(fwName)) - if isForbidden(err) && gce.OnXPN() { + err := ignoreNotFound(g.DeleteFirewall(fwName)) + if isForbidden(err) && g.OnXPN() { glog.V(4).Infof("ensureExternalLoadBalancerDeleted(%s): Do not have permission to delete firewall rule %v (on XPN). Raising event.", lbRefStr, fwName) - gce.raiseFirewallChangeNeededEvent(service, FirewallToGCloudDeleteCmd(fwName, gce.NetworkProjectID())) + g.raiseFirewallChangeNeededEvent(service, FirewallToGCloudDeleteCmd(fwName, g.NetworkProjectID())) return nil } return err @@ -328,17 +328,17 @@ func (gce *GCECloud) ensureExternalLoadBalancerDeleted(clusterName, clusterID st // creation/update attempt, so make sure we clean it up here just in case. func() error { glog.Infof("ensureExternalLoadBalancerDeleted(%s): Deleting IP address.", lbRefStr) - return ignoreNotFound(gce.DeleteRegionAddress(loadBalancerName, gce.region)) + return ignoreNotFound(g.DeleteRegionAddress(loadBalancerName, g.region)) }, func() error { glog.Infof("ensureExternalLoadBalancerDeleted(%s): Deleting forwarding rule.", lbRefStr) // The forwarding rule must be deleted before either the target pool can, // unfortunately, so we have to do these two serially. - if err := ignoreNotFound(gce.DeleteRegionForwardingRule(loadBalancerName, gce.region)); err != nil { + if err := ignoreNotFound(g.DeleteRegionForwardingRule(loadBalancerName, g.region)); err != nil { return err } glog.Infof("ensureExternalLoadBalancerDeleted(%s): Deleting target pool.", lbRefStr) - if err := gce.DeleteExternalTargetPoolAndChecks(service, loadBalancerName, gce.region, clusterID, hcNames...); err != nil { + if err := g.DeleteExternalTargetPoolAndChecks(service, loadBalancerName, g.region, clusterID, hcNames...); err != nil { return err } return nil @@ -350,11 +350,12 @@ func (gce *GCECloud) ensureExternalLoadBalancerDeleted(clusterName, clusterID st return nil } -func (gce *GCECloud) DeleteExternalTargetPoolAndChecks(service *v1.Service, name, region, clusterID string, hcNames ...string) error { +// DeleteExternalTargetPoolAndChecks Deletes an external load balancer pool and verifies the operation +func (g *Cloud) DeleteExternalTargetPoolAndChecks(service *v1.Service, name, region, clusterID string, hcNames ...string) error { serviceName := types.NamespacedName{Namespace: service.Namespace, Name: service.Name} lbRefStr := fmt.Sprintf("%v(%v)", name, serviceName) - if err := gce.DeleteTargetPool(name, region); err != nil && isHTTPErrorCode(err, http.StatusNotFound) { + if err := g.DeleteTargetPool(name, region); err != nil && isHTTPErrorCode(err, http.StatusNotFound) { glog.Infof("DeleteExternalTargetPoolAndChecks(%v): Target pool already deleted. Continuing to delete other resources.", lbRefStr) } else if err != nil { glog.Warningf("DeleteExternalTargetPoolAndChecks(%v): Failed to delete target pool, got error %s.", lbRefStr, err.Error()) @@ -369,11 +370,11 @@ func (gce *GCECloud) DeleteExternalTargetPoolAndChecks(service *v1.Service, name if isNodesHealthCheck { // Lock to prevent deleting necessary nodes health check before it gets attached // to target pool. - gce.sharedResourceLock.Lock() - defer gce.sharedResourceLock.Unlock() + g.sharedResourceLock.Lock() + defer g.sharedResourceLock.Unlock() } glog.Infof("DeleteExternalTargetPoolAndChecks(%v): Deleting health check %v.", lbRefStr, hcName) - if err := gce.DeleteHttpHealthCheck(hcName); err != nil { + if err := g.DeleteHTTPHealthCheck(hcName); err != nil { // Delete nodes health checks will fail if any other target pool is using it. if isInUsedByError(err) { glog.V(4).Infof("DeleteExternalTargetPoolAndChecks(%v): Health check %v is in used: %v.", lbRefStr, hcName, err) @@ -395,10 +396,10 @@ func (gce *GCECloud) DeleteExternalTargetPoolAndChecks(service *v1.Service, name // So we should delete the health check firewall as well. fwName := MakeHealthCheckFirewallName(clusterID, hcName, isNodesHealthCheck) glog.Infof("DeleteExternalTargetPoolAndChecks(%v): Deleting health check firewall %v.", lbRefStr, fwName) - if err := ignoreNotFound(gce.DeleteFirewall(fwName)); err != nil { - if isForbidden(err) && gce.OnXPN() { + if err := ignoreNotFound(g.DeleteFirewall(fwName)); err != nil { + if isForbidden(err) && g.OnXPN() { glog.V(4).Infof("DeleteExternalTargetPoolAndChecks(%v): Do not have permission to delete firewall rule %v (on XPN). Raising event.", lbRefStr, fwName) - gce.raiseFirewallChangeNeededEvent(service, FirewallToGCloudDeleteCmd(fwName, gce.NetworkProjectID())) + g.raiseFirewallChangeNeededEvent(service, FirewallToGCloudDeleteCmd(fwName, g.NetworkProjectID())) return nil } return err @@ -462,7 +463,7 @@ func verifyUserRequestedIP(s CloudAddressService, region, requestedIP, fwdRuleIP return false, fmt.Errorf("requested ip %q is neither static nor assigned to the LB", requestedIP) } -func (gce *GCECloud) ensureTargetPoolAndHealthCheck(tpExists, tpNeedsRecreation bool, svc *v1.Service, loadBalancerName, clusterID, ipAddressToUse string, hosts []*gceInstance, hcToCreate, hcToDelete *compute.HttpHealthCheck) error { +func (g *Cloud) ensureTargetPoolAndHealthCheck(tpExists, tpNeedsRecreation bool, svc *v1.Service, loadBalancerName, clusterID, ipAddressToUse string, hosts []*gceInstance, hcToCreate, hcToDelete *compute.HttpHealthCheck) error { serviceName := types.NamespacedName{Namespace: svc.Namespace, Name: svc.Name} lbRefStr := fmt.Sprintf("%v(%v)", loadBalancerName, serviceName) @@ -472,7 +473,7 @@ func (gce *GCECloud) ensureTargetPoolAndHealthCheck(tpExists, tpNeedsRecreation if hcToDelete != nil { hcNames = append(hcNames, hcToDelete.Name) } - if err := gce.DeleteExternalTargetPoolAndChecks(svc, loadBalancerName, gce.region, clusterID, hcNames...); err != nil { + if err := g.DeleteExternalTargetPoolAndChecks(svc, loadBalancerName, g.region, clusterID, hcNames...); err != nil { return fmt.Errorf("failed to delete existing target pool for load balancer (%s) update: %v", lbRefStr, err) } glog.Infof("ensureTargetPoolAndHealthCheck(%s): Deleted target pool.", lbRefStr) @@ -484,7 +485,7 @@ func (gce *GCECloud) ensureTargetPoolAndHealthCheck(tpExists, tpNeedsRecreation if len(hosts) > maxTargetPoolCreateInstances { createInstances = createInstances[:maxTargetPoolCreateInstances] } - if err := gce.createTargetPoolAndHealthCheck(svc, loadBalancerName, serviceName.String(), ipAddressToUse, gce.region, clusterID, createInstances, hcToCreate); err != nil { + if err := g.createTargetPoolAndHealthCheck(svc, loadBalancerName, serviceName.String(), ipAddressToUse, g.region, clusterID, createInstances, hcToCreate); err != nil { return fmt.Errorf("failed to create target pool for load balancer (%s): %v", lbRefStr, err) } if hcToCreate != nil { @@ -494,22 +495,30 @@ func (gce *GCECloud) ensureTargetPoolAndHealthCheck(tpExists, tpNeedsRecreation glog.Infof("ensureTargetPoolAndHealthCheck(%s): Created target pool.", lbRefStr) } else { glog.Infof("ensureTargetPoolAndHealthCheck(%s): Created initial target pool (now updating the remaining %d hosts).", lbRefStr, len(hosts)-maxTargetPoolCreateInstances) - if err := gce.updateTargetPool(loadBalancerName, hosts); err != nil { + if err := g.updateTargetPool(loadBalancerName, hosts); err != nil { return fmt.Errorf("failed to update target pool for load balancer (%s): %v", lbRefStr, err) } glog.Infof("ensureTargetPoolAndHealthCheck(%s): Updated target pool (with %d hosts).", lbRefStr, len(hosts)-maxTargetPoolCreateInstances) } } else if tpExists { // Ensure hosts are updated even if there is no other changes required on target pool. - if err := gce.updateTargetPool(loadBalancerName, hosts); err != nil { + if err := g.updateTargetPool(loadBalancerName, hosts); err != nil { return fmt.Errorf("failed to update target pool for load balancer (%s): %v", lbRefStr, err) } glog.Infof("ensureTargetPoolAndHealthCheck(%s): Updated target pool (with %d hosts).", lbRefStr, len(hosts)) + if hcToCreate != nil { + if hc, err := g.ensureHTTPHealthCheck(hcToCreate.Name, hcToCreate.RequestPath, int32(hcToCreate.Port)); err != nil || hc == nil { + return fmt.Errorf("Failed to ensure health check for %v port %d path %v: %v", loadBalancerName, hcToCreate.Port, hcToCreate.RequestPath, err) + } + } + } else { + // Panic worthy. + glog.Errorf("ensureTargetPoolAndHealthCheck(%s): target pool not exists and doesn't need to be created.", lbRefStr) } return nil } -func (gce *GCECloud) createTargetPoolAndHealthCheck(svc *v1.Service, name, serviceName, ipAddress, region, clusterID string, hosts []*gceInstance, hc *compute.HttpHealthCheck) error { +func (g *Cloud) createTargetPoolAndHealthCheck(svc *v1.Service, name, serviceName, ipAddress, region, clusterID string, hosts []*gceInstance, hc *compute.HttpHealthCheck) error { // health check management is coupled with targetPools to prevent leaks. A // target pool is the only thing that requires a health check, so we delete // associated checks on teardown, and ensure checks on setup. @@ -519,16 +528,16 @@ func (gce *GCECloud) createTargetPoolAndHealthCheck(svc *v1.Service, name, servi isNodesHealthCheck := hc.Name != name if isNodesHealthCheck { // Lock to prevent necessary nodes health check / firewall gets deleted. - gce.sharedResourceLock.Lock() - defer gce.sharedResourceLock.Unlock() + g.sharedResourceLock.Lock() + defer g.sharedResourceLock.Unlock() } - if err := gce.ensureHttpHealthCheckFirewall(svc, serviceName, ipAddress, region, clusterID, hosts, hc.Name, int32(hc.Port), isNodesHealthCheck); err != nil { + if err := g.ensureHTTPHealthCheckFirewall(svc, serviceName, ipAddress, region, clusterID, hosts, hc.Name, int32(hc.Port), isNodesHealthCheck); err != nil { return err } var err error hcRequestPath, hcPort := hc.RequestPath, hc.Port - if hc, err = gce.ensureHttpHealthCheck(hc.Name, hc.RequestPath, int32(hc.Port)); err != nil || hc == nil { + if hc, err = g.ensureHTTPHealthCheck(hc.Name, hc.RequestPath, int32(hc.Port)); err != nil || hc == nil { return fmt.Errorf("Failed to ensure health check for %v port %d path %v: %v", name, hcPort, hcRequestPath, err) } hcLinks = append(hcLinks, hc.SelfLink) @@ -547,14 +556,14 @@ func (gce *GCECloud) createTargetPoolAndHealthCheck(svc *v1.Service, name, servi HealthChecks: hcLinks, } - if err := gce.CreateTargetPool(pool, region); err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + if err := g.CreateTargetPool(pool, region); err != nil && !isHTTPErrorCode(err, http.StatusConflict) { return err } return nil } -func (gce *GCECloud) updateTargetPool(loadBalancerName string, hosts []*gceInstance) error { - pool, err := gce.GetTargetPool(loadBalancerName, gce.region) +func (g *Cloud) updateTargetPool(loadBalancerName string, hosts []*gceInstance) error { + pool, err := g.GetTargetPool(loadBalancerName, g.region) if err != nil { return err } @@ -577,13 +586,13 @@ func (gce *GCECloud) updateTargetPool(loadBalancerName string, hosts []*gceInsta } if len(toAdd) > 0 { - if err := gce.AddInstancesToTargetPool(loadBalancerName, gce.region, toAdd); err != nil { + if err := g.AddInstancesToTargetPool(loadBalancerName, g.region, toAdd); err != nil { return err } } if len(toRemove) > 0 { - if err := gce.RemoveInstancesFromTargetPool(loadBalancerName, gce.region, toRemove); err != nil { + if err := g.RemoveInstancesFromTargetPool(loadBalancerName, g.region, toRemove); err != nil { return err } } @@ -591,7 +600,7 @@ func (gce *GCECloud) updateTargetPool(loadBalancerName string, hosts []*gceInsta // Try to verify that the correct number of nodes are now in the target pool. // We've been bitten by a bug here before (#11327) where all nodes were // accidentally removed and want to make similar problems easier to notice. - updatedPool, err := gce.GetTargetPool(loadBalancerName, gce.region) + updatedPool, err := g.GetTargetPool(loadBalancerName, g.region) if err != nil { return err } @@ -603,11 +612,11 @@ func (gce *GCECloud) updateTargetPool(loadBalancerName string, hosts []*gceInsta return nil } -func (gce *GCECloud) targetPoolURL(name string) string { - return gce.service.BasePath + strings.Join([]string{gce.projectID, "regions", gce.region, "targetPools", name}, "/") +func (g *Cloud) targetPoolURL(name string) string { + return g.service.BasePath + strings.Join([]string{g.projectID, "regions", g.region, "targetPools", name}, "/") } -func makeHttpHealthCheck(name, path string, port int32) *compute.HttpHealthCheck { +func makeHTTPHealthCheck(name, path string, port int32) *compute.HttpHealthCheck { return &compute.HttpHealthCheck{ Name: name, Port: int64(port), @@ -621,15 +630,46 @@ func makeHttpHealthCheck(name, path string, port int32) *compute.HttpHealthCheck } } -func (gce *GCECloud) ensureHttpHealthCheck(name, path string, port int32) (hc *compute.HttpHealthCheck, err error) { - newHC := makeHttpHealthCheck(name, path, port) - hc, err = gce.GetHttpHealthCheck(name) +// mergeHTTPHealthChecks reconciles HttpHealthCheck configures to be no smaller +// than the default values. +// E.g. old health check interval is 2s, new default is 8. +// The HC interval will be reconciled to 8 seconds. +// If the existing health check is larger than the default interval, +// the configuration will be kept. +func mergeHTTPHealthChecks(hc, newHC *compute.HttpHealthCheck) *compute.HttpHealthCheck { + if hc.CheckIntervalSec > newHC.CheckIntervalSec { + newHC.CheckIntervalSec = hc.CheckIntervalSec + } + if hc.TimeoutSec > newHC.TimeoutSec { + newHC.TimeoutSec = hc.TimeoutSec + } + if hc.UnhealthyThreshold > newHC.UnhealthyThreshold { + newHC.UnhealthyThreshold = hc.UnhealthyThreshold + } + if hc.HealthyThreshold > newHC.HealthyThreshold { + newHC.HealthyThreshold = hc.HealthyThreshold + } + return newHC +} + +// needToUpdateHTTPHealthChecks checks whether the http healthcheck needs to be +// updated. +func needToUpdateHTTPHealthChecks(hc, newHC *compute.HttpHealthCheck) bool { + changed := hc.Port != newHC.Port || hc.RequestPath != newHC.RequestPath || hc.Description != newHC.Description + changed = changed || hc.CheckIntervalSec < newHC.CheckIntervalSec || hc.TimeoutSec < newHC.TimeoutSec + changed = changed || hc.UnhealthyThreshold < newHC.UnhealthyThreshold || hc.HealthyThreshold < newHC.HealthyThreshold + return changed +} + +func (g *Cloud) ensureHTTPHealthCheck(name, path string, port int32) (hc *compute.HttpHealthCheck, err error) { + newHC := makeHTTPHealthCheck(name, path, port) + hc, err = g.GetHTTPHealthCheck(name) if hc == nil || err != nil && isHTTPErrorCode(err, http.StatusNotFound) { glog.Infof("Did not find health check %v, creating port %v path %v", name, port, path) - if err = gce.CreateHttpHealthCheck(newHC); err != nil { + if err = g.CreateHTTPHealthCheck(newHC); err != nil { return nil, err } - hc, err = gce.GetHttpHealthCheck(name) + hc, err = g.GetHTTPHealthCheck(name) if err != nil { glog.Errorf("Failed to get http health check %v", err) return nil, err @@ -639,16 +679,18 @@ func (gce *GCECloud) ensureHttpHealthCheck(name, path string, port int32) (hc *c } // Validate health check fields glog.V(4).Infof("Checking http health check params %s", name) - drift := hc.Port != int64(port) || hc.RequestPath != path || hc.Description != makeHealthCheckDescription(name) - drift = drift || hc.CheckIntervalSec != gceHcCheckIntervalSeconds || hc.TimeoutSec != gceHcTimeoutSeconds - drift = drift || hc.UnhealthyThreshold != gceHcUnhealthyThreshold || hc.HealthyThreshold != gceHcHealthyThreshold - if drift { + if needToUpdateHTTPHealthChecks(hc, newHC) { glog.Warningf("Health check %v exists but parameters have drifted - updating...", name) - if err := gce.UpdateHttpHealthCheck(newHC); err != nil { + newHC = mergeHTTPHealthChecks(hc, newHC) + if err := g.UpdateHTTPHealthCheck(newHC); err != nil { glog.Warningf("Failed to reconcile http health check %v parameters", name) return nil, err } glog.V(4).Infof("Corrected health check %v parameters successful", name) + hc, err = g.GetHTTPHealthCheck(name) + if err != nil { + return nil, err + } } return hc, nil } @@ -657,14 +699,14 @@ func (gce *GCECloud) ensureHttpHealthCheck(name, path string, port int32) (hc *c // IP is being requested. // Returns whether the forwarding rule exists, whether it needs to be updated, // what its IP address is (if it exists), and any error we encountered. -func (gce *GCECloud) forwardingRuleNeedsUpdate(name, region string, loadBalancerIP string, ports []v1.ServicePort) (exists bool, needsUpdate bool, ipAddress string, err error) { - fwd, err := gce.GetRegionForwardingRule(name, region) +func (g *Cloud) forwardingRuleNeedsUpdate(name, region string, loadBalancerIP string, ports []v1.ServicePort) (exists bool, needsUpdate bool, ipAddress string, err error) { + fwd, err := g.GetRegionForwardingRule(name, region) if err != nil { if isHTTPErrorCode(err, http.StatusNotFound) { return false, true, "", nil } // Err on the side of caution in case of errors. Caller should notice the error and retry. - // We never want to end up recreating resources because gce api flaked. + // We never want to end up recreating resources because g api flaked. return true, false, "", fmt.Errorf("error getting load balancer's forwarding rule: %v", err) } // If the user asks for a specific static ip through the Service spec, @@ -678,7 +720,7 @@ func (gce *GCECloud) forwardingRuleNeedsUpdate(name, region string, loadBalancer portRange, err := loadBalancerPortRange(ports) if err != nil { // Err on the side of caution in case of errors. Caller should notice the error and retry. - // We never want to end up recreating resources because gce api flaked. + // We never want to end up recreating resources because g api flaked. return true, false, "", err } if portRange != fwd.PortRange { @@ -696,14 +738,14 @@ func (gce *GCECloud) forwardingRuleNeedsUpdate(name, region string, loadBalancer // Doesn't check whether the hosts have changed, since host updating is handled // separately. -func (gce *GCECloud) targetPoolNeedsRecreation(name, region string, affinityType v1.ServiceAffinity) (exists bool, needsRecreation bool, err error) { - tp, err := gce.GetTargetPool(name, region) +func (g *Cloud) targetPoolNeedsRecreation(name, region string, affinityType v1.ServiceAffinity) (exists bool, needsRecreation bool, err error) { + tp, err := g.GetTargetPool(name, region) if err != nil { if isHTTPErrorCode(err, http.StatusNotFound) { return false, true, nil } // Err on the side of caution in case of errors. Caller should notice the error and retry. - // We never want to end up recreating resources because gce api flaked. + // We never want to end up recreating resources because g api flaked. return true, false, fmt.Errorf("error getting load balancer's target pool: %v", err) } // TODO: If the user modifies their Service's session affinity, it *should* @@ -777,8 +819,8 @@ func translateAffinityType(affinityType v1.ServiceAffinity) string { } } -func (gce *GCECloud) firewallNeedsUpdate(name, serviceName, region, ipAddress string, ports []v1.ServicePort, sourceRanges netsets.IPNet) (exists bool, needsUpdate bool, err error) { - fw, err := gce.GetFirewall(MakeFirewallName(name)) +func (g *Cloud) firewallNeedsUpdate(name, serviceName, region, ipAddress string, ports []v1.ServicePort, sourceRanges netsets.IPNet) (exists bool, needsUpdate bool, err error) { + fw, err := g.GetFirewall(MakeFirewallName(name)) if err != nil { if isHTTPErrorCode(err, http.StatusNotFound) { return false, true, nil @@ -815,7 +857,7 @@ func (gce *GCECloud) firewallNeedsUpdate(name, serviceName, region, ipAddress st return true, false, nil } -func (gce *GCECloud) ensureHttpHealthCheckFirewall(svc *v1.Service, serviceName, ipAddress, region, clusterID string, hosts []*gceInstance, hcName string, hcPort int32, isNodesHealthCheck bool) error { +func (g *Cloud) ensureHTTPHealthCheckFirewall(svc *v1.Service, serviceName, ipAddress, region, clusterID string, hosts []*gceInstance, hcName string, hcPort int32, isNodesHealthCheck bool) error { // Prepare the firewall params for creating / checking. desc := fmt.Sprintf(`{"kubernetes.io/cluster-id":"%s"}`, clusterID) if !isNodesHealthCheck { @@ -825,13 +867,13 @@ func (gce *GCECloud) ensureHttpHealthCheckFirewall(svc *v1.Service, serviceName, ports := []v1.ServicePort{{Protocol: "tcp", Port: hcPort}} fwName := MakeHealthCheckFirewallName(clusterID, hcName, isNodesHealthCheck) - fw, err := gce.GetFirewall(fwName) + fw, err := g.GetFirewall(fwName) if err != nil { if !isHTTPErrorCode(err, http.StatusNotFound) { return fmt.Errorf("error getting firewall for health checks: %v", err) } glog.Infof("Creating firewall %v for health checks.", fwName) - if err := gce.createFirewall(svc, fwName, region, desc, sourceRanges, ports, hosts); err != nil { + if err := g.createFirewall(svc, fwName, region, desc, sourceRanges, ports, hosts); err != nil { return err } glog.Infof("Created firewall %v for health checks.", fwName) @@ -844,7 +886,7 @@ func (gce *GCECloud) ensureHttpHealthCheckFirewall(svc *v1.Service, serviceName, !equalStringSets(fw.Allowed[0].Ports, []string{strconv.Itoa(int(ports[0].Port))}) || !equalStringSets(fw.SourceRanges, sourceRanges.StringSlice()) { glog.Warningf("Firewall %v exists but parameters have drifted - updating...", fwName) - if err := gce.updateFirewall(svc, fwName, region, desc, sourceRanges, ports, hosts); err != nil { + if err := g.updateFirewall(svc, fwName, region, desc, sourceRanges, ports, hosts); err != nil { glog.Warningf("Failed to reconcile firewall %v parameters.", fwName) return err } @@ -892,17 +934,17 @@ func createForwardingRule(s CloudForwardingRuleService, name, serviceName, regio return nil } -func (gce *GCECloud) createFirewall(svc *v1.Service, name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) error { - firewall, err := gce.firewallObject(name, region, desc, sourceRanges, ports, hosts) +func (g *Cloud) createFirewall(svc *v1.Service, name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) error { + firewall, err := g.firewallObject(name, region, desc, sourceRanges, ports, hosts) if err != nil { return err } - if err = gce.CreateFirewall(firewall); err != nil { + if err = g.CreateFirewall(firewall); err != nil { if isHTTPErrorCode(err, http.StatusConflict) { return nil - } else if isForbidden(err) && gce.OnXPN() { + } else if isForbidden(err) && g.OnXPN() { glog.V(4).Infof("createFirewall(%v): do not have permission to create firewall rule (on XPN). Raising event.", firewall.Name) - gce.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudCreateCmd(firewall, gce.NetworkProjectID())) + g.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudCreateCmd(firewall, g.NetworkProjectID())) return nil } return err @@ -910,18 +952,18 @@ func (gce *GCECloud) createFirewall(svc *v1.Service, name, region, desc string, return nil } -func (gce *GCECloud) updateFirewall(svc *v1.Service, name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) error { - firewall, err := gce.firewallObject(name, region, desc, sourceRanges, ports, hosts) +func (g *Cloud) updateFirewall(svc *v1.Service, name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) error { + firewall, err := g.firewallObject(name, region, desc, sourceRanges, ports, hosts) if err != nil { return err } - if err = gce.UpdateFirewall(firewall); err != nil { + if err = g.UpdateFirewall(firewall); err != nil { if isHTTPErrorCode(err, http.StatusConflict) { return nil - } else if isForbidden(err) && gce.OnXPN() { + } else if isForbidden(err) && g.OnXPN() { glog.V(4).Infof("updateFirewall(%v): do not have permission to update firewall rule (on XPN). Raising event.", firewall.Name) - gce.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudUpdateCmd(firewall, gce.NetworkProjectID())) + g.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudUpdateCmd(firewall, g.NetworkProjectID())) return nil } return err @@ -929,25 +971,25 @@ func (gce *GCECloud) updateFirewall(svc *v1.Service, name, region, desc string, return nil } -func (gce *GCECloud) firewallObject(name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) (*compute.Firewall, error) { +func (g *Cloud) firewallObject(name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) (*compute.Firewall, error) { allowedPorts := make([]string, len(ports)) for ix := range ports { allowedPorts[ix] = strconv.Itoa(int(ports[ix].Port)) } // If the node tags to be used for this cluster have been predefined in the // provider config, just use them. Otherwise, invoke computeHostTags method to get the tags. - hostTags := gce.nodeTags + hostTags := g.nodeTags if len(hostTags) == 0 { var err error - if hostTags, err = gce.computeHostTags(hosts); err != nil { - return nil, fmt.Errorf("No node tags supplied and also failed to parse the given lists of hosts for tags. Abort creating firewall rule.") + if hostTags, err = g.computeHostTags(hosts); err != nil { + return nil, fmt.Errorf("no node tags supplied and also failed to parse the given lists of hosts for tags. Abort creating firewall rule") } } firewall := &compute.Firewall{ Name: name, Description: desc, - Network: gce.networkURL, + Network: g.networkURL, SourceRanges: sourceRanges.StringSlice(), TargetTags: hostTags, Allowed: []*compute.FirewallAllowed{ @@ -1013,8 +1055,8 @@ func ensureStaticIP(s CloudAddressService, name, serviceName, region, existingIP return addr.Address, existed, nil } -func (gce *GCECloud) getServiceNetworkTier(svc *v1.Service) (cloud.NetworkTier, error) { - if !gce.AlphaFeatureGate.Enabled(AlphaFeatureNetworkTiers) { +func (g *Cloud) getServiceNetworkTier(svc *v1.Service) (cloud.NetworkTier, error) { + if !g.AlphaFeatureGate.Enabled(AlphaFeatureNetworkTiers) { return cloud.NetworkTierDefault, nil } tier, err := GetServiceNetworkTier(svc) @@ -1025,12 +1067,12 @@ func (gce *GCECloud) getServiceNetworkTier(svc *v1.Service) (cloud.NetworkTier, return tier, nil } -func (gce *GCECloud) deleteWrongNetworkTieredResources(lbName, lbRef string, desiredNetTier cloud.NetworkTier) error { +func (g *Cloud) deleteWrongNetworkTieredResources(lbName, lbRef string, desiredNetTier cloud.NetworkTier) error { logPrefix := fmt.Sprintf("deleteWrongNetworkTieredResources:(%s)", lbRef) - if err := deleteFWDRuleWithWrongTier(gce, gce.region, lbName, logPrefix, desiredNetTier); err != nil { + if err := deleteFWDRuleWithWrongTier(g, g.region, lbName, logPrefix, desiredNetTier); err != nil { return err } - if err := deleteAddressWithWrongTier(gce, gce.region, lbName, logPrefix, desiredNetTier); err != nil { + if err := deleteAddressWithWrongTier(g, g.region, lbName, logPrefix, desiredNetTier); err != nil { return err } return nil diff --git a/pkg/cloudprovider/providers/gce/gce_loadbalancer_external_test.go b/pkg/cloudprovider/providers/gce/gce_loadbalancer_external_test.go index 1831285714412..a238d888db8a8 100644 --- a/pkg/cloudprovider/providers/gce/gce_loadbalancer_external_test.go +++ b/pkg/cloudprovider/providers/gce/gce_loadbalancer_external_test.go @@ -164,7 +164,7 @@ func TestCreateForwardingRuleWithTier(t *testing.T) { vals := DefaultTestClusterValues() serviceName := "foo-svc" - baseLinkUrl := "https://www.googleapis.com/compute/%v/projects/%v/regions/%v/forwardingRules/%v" + baseLinkURL := "https://www.googleapis.com/compute/%v/projects/%v/regions/%v/forwardingRules/%v" for desc, tc := range map[string]struct { netTier cloud.NetworkTier @@ -180,7 +180,7 @@ func TestCreateForwardingRuleWithTier(t *testing.T) { PortRange: "123-123", Target: target, NetworkTier: "PREMIUM", - SelfLink: fmt.Sprintf(baseLinkUrl, "v1", vals.ProjectID, vals.Region, "lb-1"), + SelfLink: fmt.Sprintf(baseLinkURL, "v1", vals.ProjectID, vals.Region, "lb-1"), }, }, "Standard tier": { @@ -193,7 +193,7 @@ func TestCreateForwardingRuleWithTier(t *testing.T) { PortRange: "123-123", Target: target, NetworkTier: "STANDARD", - SelfLink: fmt.Sprintf(baseLinkUrl, "alpha", vals.ProjectID, vals.Region, "lb-2"), + SelfLink: fmt.Sprintf(baseLinkURL, "alpha", vals.ProjectID, vals.Region, "lb-2"), }, }, } { @@ -276,7 +276,7 @@ func TestDeleteAddressWithWrongTier(t *testing.T) { } } -func createExternalLoadBalancer(gce *GCECloud, svc *v1.Service, nodeNames []string, clusterName, clusterID, zoneName string) (*v1.LoadBalancerStatus, error) { +func createExternalLoadBalancer(gce *Cloud, svc *v1.Service, nodeNames []string, clusterName, clusterID, zoneName string) (*v1.LoadBalancerStatus, error) { nodes, err := createAndInsertNodes(gce, nodeNames, zoneName) if err != nil { return nil, err @@ -498,7 +498,7 @@ func TestForwardingRuleNeedsUpdate(t *testing.T) { ports []v1.ServicePort exists bool needsUpdate bool - expectIpAddr string + expectIPAddr string expectError bool }{ "When the loadBalancerIP does not equal the FwdRule IP address.": { @@ -506,7 +506,7 @@ func TestForwardingRuleNeedsUpdate(t *testing.T) { ports: svc.Spec.Ports, exists: true, needsUpdate: true, - expectIpAddr: ipAddr, + expectIPAddr: ipAddr, expectError: false, }, "When loadBalancerPortRange returns an error.": { @@ -514,7 +514,7 @@ func TestForwardingRuleNeedsUpdate(t *testing.T) { ports: []v1.ServicePort{}, exists: true, needsUpdate: false, - expectIpAddr: "", + expectIPAddr: "", expectError: true, }, "When portRange not equals to the forwardingRule port range.": { @@ -522,7 +522,7 @@ func TestForwardingRuleNeedsUpdate(t *testing.T) { ports: wrongPorts, exists: true, needsUpdate: true, - expectIpAddr: ipAddr, + expectIPAddr: ipAddr, expectError: false, }, "When the ports protocol does not equal the ForwardingRuel IP Protocol.": { @@ -530,7 +530,7 @@ func TestForwardingRuleNeedsUpdate(t *testing.T) { ports: wrongProtocolPorts, exists: true, needsUpdate: true, - expectIpAddr: ipAddr, + expectIPAddr: ipAddr, expectError: false, }, "When basic workflow.": { @@ -538,7 +538,7 @@ func TestForwardingRuleNeedsUpdate(t *testing.T) { ports: svc.Spec.Ports, exists: true, needsUpdate: false, - expectIpAddr: ipAddr, + expectIPAddr: ipAddr, expectError: false, }, } { @@ -546,7 +546,7 @@ func TestForwardingRuleNeedsUpdate(t *testing.T) { exists, needsUpdate, ipAddress, err := gce.forwardingRuleNeedsUpdate(lbName, vals.Region, tc.lbIP, tc.ports) assert.Equal(t, tc.exists, exists, "'exists' didn't return as expected "+desc) assert.Equal(t, tc.needsUpdate, needsUpdate, "'needsUpdate' didn't return as expected "+desc) - assert.Equal(t, tc.expectIpAddr, ipAddress, "'ipAddress' didn't return as expected "+desc) + assert.Equal(t, tc.expectIPAddr, ipAddress, "'ipAddress' didn't return as expected "+desc) if tc.expectError { assert.Error(t, err, "Should returns an error "+desc) } else { @@ -806,8 +806,8 @@ func TestEnsureTargetPoolAndHealthCheck(t *testing.T) { lbName := gce.GetLoadBalancerName(context.TODO(), "", svc) region := vals.Region - hcToCreate := makeHttpHealthCheck(MakeNodesHealthCheckName(clusterID), GetNodesHealthCheckPath(), GetNodesHealthCheckPort()) - hcToDelete := makeHttpHealthCheck(MakeNodesHealthCheckName(clusterID), GetNodesHealthCheckPath(), GetNodesHealthCheckPort()) + hcToCreate := makeHTTPHealthCheck(MakeNodesHealthCheckName(clusterID), GetNodesHealthCheckPath(), GetNodesHealthCheckPort()) + hcToDelete := makeHTTPHealthCheck(MakeNodesHealthCheckName(clusterID), GetNodesHealthCheckPath(), GetNodesHealthCheckPort()) // Apply a tag on the target pool. By verifying the change of the tag, target pool update can be ensured. tag := "A Tag" @@ -823,7 +823,7 @@ func TestEnsureTargetPoolAndHealthCheck(t *testing.T) { pool, err = gce.GetTargetPool(lbName, region) assert.Equal(t, 1, len(pool.Instances)) var manyNodeName [maxTargetPoolCreateInstances + 1]string - for i := 0; i < maxTargetPoolCreateInstances+1; i += 1 { + for i := 0; i < maxTargetPoolCreateInstances+1; i++ { manyNodeName[i] = fmt.Sprintf("testnode_%d", i) } manyNodes, err := createAndInsertNodes(gce, manyNodeName[:], vals.ZoneName) @@ -1032,3 +1032,154 @@ func TestEnsureExternalLoadBalancerErrors(t *testing.T) { }) } } + +func TestExternalLoadBalancerEnsureHttpHealthCheck(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + desc string + modifier func(*compute.HttpHealthCheck) *compute.HttpHealthCheck + wantEqual bool + }{ + {"should ensure HC", func(_ *compute.HttpHealthCheck) *compute.HttpHealthCheck { return nil }, false}, + { + "should reconcile HC interval", + func(hc *compute.HttpHealthCheck) *compute.HttpHealthCheck { + hc.CheckIntervalSec = gceHcCheckIntervalSeconds - 1 + return hc + }, + false, + }, + { + "should allow HC to be configurable to bigger intervals", + func(hc *compute.HttpHealthCheck) *compute.HttpHealthCheck { + hc.CheckIntervalSec = gceHcCheckIntervalSeconds * 10 + return hc + }, + true, + }, + { + "should allow HC to accept bigger intervals while applying default value to small thresholds", + func(hc *compute.HttpHealthCheck) *compute.HttpHealthCheck { + hc.CheckIntervalSec = gceHcCheckIntervalSeconds * 10 + hc.UnhealthyThreshold = gceHcUnhealthyThreshold - 1 + return hc + }, + false, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + + gce, err := fakeGCECloud(DefaultTestClusterValues()) + require.NoError(t, err) + c := gce.c.(*cloud.MockGCE) + c.MockHttpHealthChecks.UpdateHook = func(ctx context.Context, key *meta.Key, obj *ga.HttpHealthCheck, m *cloud.MockHttpHealthChecks) error { + m.Objects[*key] = &cloud.MockHttpHealthChecksObj{Obj: obj} + return nil + } + + hcName, hcPath, hcPort := "test-hc", "/healthz", int32(12345) + existingHC := makeHTTPHealthCheck(hcName, hcPath, hcPort) + existingHC = tc.modifier(existingHC) + if existingHC != nil { + if err := gce.CreateHTTPHealthCheck(existingHC); err != nil { + t.Fatalf("gce.CreateHttpHealthCheck(%#v) = %v; want err = nil", existingHC, err) + } + } + if _, err := gce.ensureHTTPHealthCheck(hcName, hcPath, hcPort); err != nil { + t.Fatalf("gce.ensureHttpHealthCheck(%q, %q, %v) = _, %d; want err = nil", hcName, hcPath, hcPort, err) + } + if hc, err := gce.GetHTTPHealthCheck(hcName); err != nil { + t.Fatalf("gce.GetHttpHealthCheck(%q) = _, %d; want err = nil", hcName, err) + } else { + if tc.wantEqual { + assert.Equal(t, hc, existingHC) + } else { + assert.NotEqual(t, hc, existingHC) + } + } + }) + } + +} + +func TestMergeHttpHealthChecks(t *testing.T) { + t.Parallel() + for _, tc := range []struct { + desc string + checkIntervalSec int64 + timeoutSec int64 + healthyThreshold int64 + unhealthyThreshold int64 + wantCheckIntervalSec int64 + wantTimeoutSec int64 + wantHealthyThreshold int64 + wantUnhealthyThreshold int64 + }{ + {"unchanged", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"interval - too small - should reconcile", gceHcCheckIntervalSeconds - 1, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"timeout - too small - should reconcile", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds - 1, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"healthy threshold - too small - should reconcile", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold - 1, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"unhealthy threshold - too small - should reconcile", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold - 1, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"interval - user configured - should keep", gceHcCheckIntervalSeconds + 1, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds + 1, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"timeout - user configured - should keep", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds + 1, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds + 1, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"healthy threshold - user configured - should keep", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold + 1, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold + 1, gceHcUnhealthyThreshold}, + {"unhealthy threshold - user configured - should keep", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold + 1, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold + 1}, + } { + t.Run(tc.desc, func(t *testing.T) { + wantHC := makeHTTPHealthCheck("hc", "/", 12345) + hc := &compute.HttpHealthCheck{ + CheckIntervalSec: tc.checkIntervalSec, + TimeoutSec: tc.timeoutSec, + HealthyThreshold: tc.healthyThreshold, + UnhealthyThreshold: tc.unhealthyThreshold, + } + mergeHTTPHealthChecks(hc, wantHC) + if wantHC.CheckIntervalSec != tc.wantCheckIntervalSec { + t.Errorf("wantHC.CheckIntervalSec = %d; want %d", wantHC.CheckIntervalSec, tc.checkIntervalSec) + } + if wantHC.TimeoutSec != tc.wantTimeoutSec { + t.Errorf("wantHC.TimeoutSec = %d; want %d", wantHC.TimeoutSec, tc.timeoutSec) + } + if wantHC.HealthyThreshold != tc.wantHealthyThreshold { + t.Errorf("wantHC.HealthyThreshold = %d; want %d", wantHC.HealthyThreshold, tc.healthyThreshold) + } + if wantHC.UnhealthyThreshold != tc.wantUnhealthyThreshold { + t.Errorf("wantHC.UnhealthyThreshold = %d; want %d", wantHC.UnhealthyThreshold, tc.unhealthyThreshold) + } + }) + } +} + +func TestNeedToUpdateHttpHealthChecks(t *testing.T) { + t.Parallel() + for _, tc := range []struct { + desc string + modifier func(*compute.HttpHealthCheck) + wantChanged bool + }{ + {"unchanged", nil, false}, + {"desc does not match", func(hc *compute.HttpHealthCheck) { hc.Description = "bad-desc" }, true}, + {"port does not match", func(hc *compute.HttpHealthCheck) { hc.Port = 54321 }, true}, + {"requestPath does not match", func(hc *compute.HttpHealthCheck) { hc.RequestPath = "/anotherone" }, true}, + {"interval needs update", func(hc *compute.HttpHealthCheck) { hc.CheckIntervalSec = gceHcCheckIntervalSeconds - 1 }, true}, + {"timeout needs update", func(hc *compute.HttpHealthCheck) { hc.TimeoutSec = gceHcTimeoutSeconds - 1 }, true}, + {"healthy threshold needs update", func(hc *compute.HttpHealthCheck) { hc.HealthyThreshold = gceHcHealthyThreshold - 1 }, true}, + {"unhealthy threshold needs update", func(hc *compute.HttpHealthCheck) { hc.UnhealthyThreshold = gceHcUnhealthyThreshold - 1 }, true}, + {"interval does not need update", func(hc *compute.HttpHealthCheck) { hc.CheckIntervalSec = gceHcCheckIntervalSeconds + 1 }, false}, + {"timeout does not need update", func(hc *compute.HttpHealthCheck) { hc.TimeoutSec = gceHcTimeoutSeconds + 1 }, false}, + {"healthy threshold does not need update", func(hc *compute.HttpHealthCheck) { hc.HealthyThreshold = gceHcHealthyThreshold + 1 }, false}, + {"unhealthy threshold does not need update", func(hc *compute.HttpHealthCheck) { hc.UnhealthyThreshold = gceHcUnhealthyThreshold + 1 }, false}, + } { + t.Run(tc.desc, func(t *testing.T) { + hc := makeHTTPHealthCheck("hc", "/", 12345) + wantHC := makeHTTPHealthCheck("hc", "/", 12345) + if tc.modifier != nil { + tc.modifier(hc) + } + if gotChanged := needToUpdateHTTPHealthChecks(hc, wantHC); gotChanged != tc.wantChanged { + t.Errorf("needToUpdateHTTPHealthChecks(%#v, %#v) = %t; want changed = %t", hc, wantHC, gotChanged, tc.wantChanged) + } + }) + } +} diff --git a/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal.go b/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal.go index 4542fa1232bea..49a2885520706 100644 --- a/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal.go +++ b/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal.go @@ -35,21 +35,21 @@ const ( allInstances = "ALL" ) -func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v1.Service, existingFwdRule *compute.ForwardingRule, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) { +func (g *Cloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v1.Service, existingFwdRule *compute.ForwardingRule, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) { nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace} ports, protocol := getPortsAndProtocol(svc.Spec.Ports) if protocol != v1.ProtocolTCP && protocol != v1.ProtocolUDP { return nil, fmt.Errorf("Invalid protocol %s, only TCP and UDP are supported", string(protocol)) } scheme := cloud.SchemeInternal - loadBalancerName := gce.GetLoadBalancerName(context.TODO(), clusterName, svc) + loadBalancerName := g.GetLoadBalancerName(context.TODO(), clusterName, svc) sharedBackend := shareBackendService(svc) backendServiceName := makeBackendServiceName(loadBalancerName, clusterID, sharedBackend, scheme, protocol, svc.Spec.SessionAffinity) - backendServiceLink := gce.getBackendServiceLink(backendServiceName) + backendServiceLink := g.getBackendServiceLink(backendServiceName) // Ensure instance groups exist and nodes are assigned to groups igName := makeInstanceGroupName(clusterID) - igLinks, err := gce.ensureInternalInstanceGroups(igName, nodes) + igLinks, err := g.ensureInternalInstanceGroups(igName, nodes) if err != nil { return nil, err } @@ -58,14 +58,14 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s var existingBackendService *compute.BackendService if existingFwdRule != nil && existingFwdRule.BackendService != "" { existingBSName := getNameFromLink(existingFwdRule.BackendService) - if existingBackendService, err = gce.GetRegionBackendService(existingBSName, gce.region); err != nil && !isNotFound(err) { + if existingBackendService, err = g.GetRegionBackendService(existingBSName, g.region); err != nil && !isNotFound(err) { return nil, err } } // Lock the sharedResourceLock to prevent any deletions of shared resources while assembling shared resources here - gce.sharedResourceLock.Lock() - defer gce.sharedResourceLock.Unlock() + g.sharedResourceLock.Lock() + defer g.sharedResourceLock.Unlock() // Ensure health check exists before creating the backend service. The health check is shared // if externalTrafficPolicy=Cluster. @@ -76,7 +76,7 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s // Service requires a special health check, retrieve the OnlyLocal port & path hcPath, hcPort = v1_service.GetServiceHealthCheckPathPort(svc) } - hc, err := gce.ensureInternalHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort) + hc, err := g.ensureInternalHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort) if err != nil { return nil, err } @@ -88,7 +88,7 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s // If the ILB already exists, continue using the subnet that it's already using. // This is to support existing ILBs that were setup using the wrong subnet. - subnetworkURL := gce.SubnetworkURL() + subnetworkURL := g.SubnetworkURL() if existingFwdRule != nil && existingFwdRule.Subnetwork != "" { // external LBs have an empty Subnetwork field. subnetworkURL = existingFwdRule.Subnetwork @@ -96,8 +96,8 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s var addrMgr *addressManager // If the network is not a legacy network, use the address manager - if !gce.IsLegacyNetwork() { - addrMgr = newAddressManager(gce, nm.String(), gce.Region(), subnetworkURL, loadBalancerName, requestedIP, cloud.SchemeInternal) + if !g.IsLegacyNetwork() { + addrMgr = newAddressManager(g, nm.String(), g.Region(), subnetworkURL, loadBalancerName, requestedIP, cloud.SchemeInternal) ipToUse, err = addrMgr.HoldAddress() if err != nil { return nil, err @@ -106,7 +106,7 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s } // Ensure firewall rules if necessary - if err = gce.ensureInternalFirewalls(loadBalancerName, ipToUse, clusterID, nm, svc, strconv.Itoa(int(hcPort)), sharedHealthCheck, nodes); err != nil { + if err = g.ensureInternalFirewalls(loadBalancerName, ipToUse, clusterID, nm, svc, strconv.Itoa(int(hcPort)), sharedHealthCheck, nodes); err != nil { return nil, err } @@ -125,20 +125,20 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s if subnetworkURL != "" { expectedFwdRule.Subnetwork = subnetworkURL } else { - expectedFwdRule.Network = gce.networkURL + expectedFwdRule.Network = g.networkURL } fwdRuleDeleted := false if existingFwdRule != nil && !fwdRuleEqual(existingFwdRule, expectedFwdRule) { glog.V(2).Infof("ensureInternalLoadBalancer(%v): deleting existing forwarding rule with IP address %v", loadBalancerName, existingFwdRule.IPAddress) - if err = ignoreNotFound(gce.DeleteRegionForwardingRule(loadBalancerName, gce.region)); err != nil { + if err = ignoreNotFound(g.DeleteRegionForwardingRule(loadBalancerName, g.region)); err != nil { return nil, err } fwdRuleDeleted = true } bsDescription := makeBackendServiceDescription(nm, sharedBackend) - err = gce.ensureInternalBackendService(backendServiceName, bsDescription, svc.Spec.SessionAffinity, scheme, protocol, igLinks, hc.SelfLink) + err = g.ensureInternalBackendService(backendServiceName, bsDescription, svc.Spec.SessionAffinity, scheme, protocol, igLinks, hc.SelfLink) if err != nil { return nil, err } @@ -146,7 +146,7 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s // If we previously deleted the forwarding rule or it never existed, finally create it. if fwdRuleDeleted || existingFwdRule == nil { glog.V(2).Infof("ensureInternalLoadBalancer(%v): creating forwarding rule", loadBalancerName) - if err = gce.CreateRegionForwardingRule(expectedFwdRule, gce.region); err != nil { + if err = g.CreateRegionForwardingRule(expectedFwdRule, g.region); err != nil { return nil, err } glog.V(2).Infof("ensureInternalLoadBalancer(%v): created forwarding rule", loadBalancerName) @@ -154,7 +154,7 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s // Delete the previous internal load balancer resources if necessary if existingBackendService != nil { - gce.clearPreviousInternalResources(svc, loadBalancerName, existingBackendService, backendServiceName, hcName) + g.clearPreviousInternalResources(svc, loadBalancerName, existingBackendService, backendServiceName, hcName) } if addrMgr != nil { @@ -165,7 +165,7 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s } // Get the most recent forwarding rule for the address. - updatedFwdRule, err := gce.GetRegionForwardingRule(loadBalancerName, gce.region) + updatedFwdRule, err := g.GetRegionForwardingRule(loadBalancerName, g.region) if err != nil { return nil, err } @@ -175,11 +175,11 @@ func (gce *GCECloud) ensureInternalLoadBalancer(clusterName, clusterID string, s return status, nil } -func (gce *GCECloud) clearPreviousInternalResources(svc *v1.Service, loadBalancerName string, existingBackendService *compute.BackendService, expectedBSName, expectedHCName string) { +func (g *Cloud) clearPreviousInternalResources(svc *v1.Service, loadBalancerName string, existingBackendService *compute.BackendService, expectedBSName, expectedHCName string) { // If a new backend service was created, delete the old one. if existingBackendService.Name != expectedBSName { glog.V(2).Infof("clearPreviousInternalResources(%v): expected backend service %q does not match previous %q - deleting backend service", loadBalancerName, expectedBSName, existingBackendService.Name) - if err := gce.teardownInternalBackendService(existingBackendService.Name); err != nil && !isNotFound(err) { + if err := g.teardownInternalBackendService(existingBackendService.Name); err != nil && !isNotFound(err) { glog.Warningf("clearPreviousInternalResources: could not delete old backend service: %v, err: %v", existingBackendService.Name, err) } } @@ -189,7 +189,7 @@ func (gce *GCECloud) clearPreviousInternalResources(svc *v1.Service, loadBalance existingHCName := getNameFromLink(existingBackendService.HealthChecks[0]) if existingHCName != expectedHCName { glog.V(2).Infof("clearPreviousInternalResources(%v): expected health check %q does not match previous %q - deleting health check", loadBalancerName, expectedHCName, existingHCName) - if err := gce.teardownInternalHealthCheckAndFirewall(svc, existingHCName); err != nil { + if err := g.teardownInternalHealthCheckAndFirewall(svc, existingHCName); err != nil { glog.Warningf("clearPreviousInternalResources: could not delete existing healthcheck: %v, err: %v", existingHCName, err) } } @@ -200,12 +200,12 @@ func (gce *GCECloud) clearPreviousInternalResources(svc *v1.Service, loadBalance // updateInternalLoadBalancer is called when the list of nodes has changed. Therefore, only the instance groups // and possibly the backend service need to be updated. -func (gce *GCECloud) updateInternalLoadBalancer(clusterName, clusterID string, svc *v1.Service, nodes []*v1.Node) error { - gce.sharedResourceLock.Lock() - defer gce.sharedResourceLock.Unlock() +func (g *Cloud) updateInternalLoadBalancer(clusterName, clusterID string, svc *v1.Service, nodes []*v1.Node) error { + g.sharedResourceLock.Lock() + defer g.sharedResourceLock.Unlock() igName := makeInstanceGroupName(clusterID) - igLinks, err := gce.ensureInternalInstanceGroups(igName, nodes) + igLinks, err := g.ensureInternalInstanceGroups(igName, nodes) if err != nil { return err } @@ -213,41 +213,41 @@ func (gce *GCECloud) updateInternalLoadBalancer(clusterName, clusterID string, s // Generate the backend service name _, protocol := getPortsAndProtocol(svc.Spec.Ports) scheme := cloud.SchemeInternal - loadBalancerName := gce.GetLoadBalancerName(context.TODO(), clusterName, svc) + loadBalancerName := g.GetLoadBalancerName(context.TODO(), clusterName, svc) backendServiceName := makeBackendServiceName(loadBalancerName, clusterID, shareBackendService(svc), scheme, protocol, svc.Spec.SessionAffinity) // Ensure the backend service has the proper backend/instance-group links - return gce.ensureInternalBackendServiceGroups(backendServiceName, igLinks) + return g.ensureInternalBackendServiceGroups(backendServiceName, igLinks) } -func (gce *GCECloud) ensureInternalLoadBalancerDeleted(clusterName, clusterID string, svc *v1.Service) error { - loadBalancerName := gce.GetLoadBalancerName(context.TODO(), clusterName, svc) +func (g *Cloud) ensureInternalLoadBalancerDeleted(clusterName, clusterID string, svc *v1.Service) error { + loadBalancerName := g.GetLoadBalancerName(context.TODO(), clusterName, svc) _, protocol := getPortsAndProtocol(svc.Spec.Ports) scheme := cloud.SchemeInternal sharedBackend := shareBackendService(svc) sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc) - gce.sharedResourceLock.Lock() - defer gce.sharedResourceLock.Unlock() + g.sharedResourceLock.Lock() + defer g.sharedResourceLock.Unlock() glog.V(2).Infof("ensureInternalLoadBalancerDeleted(%v): attempting delete of region internal address", loadBalancerName) - ensureAddressDeleted(gce, loadBalancerName, gce.region) + ensureAddressDeleted(g, loadBalancerName, g.region) glog.V(2).Infof("ensureInternalLoadBalancerDeleted(%v): deleting region internal forwarding rule", loadBalancerName) - if err := ignoreNotFound(gce.DeleteRegionForwardingRule(loadBalancerName, gce.region)); err != nil { + if err := ignoreNotFound(g.DeleteRegionForwardingRule(loadBalancerName, g.region)); err != nil { return err } backendServiceName := makeBackendServiceName(loadBalancerName, clusterID, sharedBackend, scheme, protocol, svc.Spec.SessionAffinity) glog.V(2).Infof("ensureInternalLoadBalancerDeleted(%v): deleting region backend service %v", loadBalancerName, backendServiceName) - if err := gce.teardownInternalBackendService(backendServiceName); err != nil { + if err := g.teardownInternalBackendService(backendServiceName); err != nil { return err } glog.V(2).Infof("ensureInternalLoadBalancerDeleted(%v): deleting firewall for traffic", loadBalancerName) - if err := ignoreNotFound(gce.DeleteFirewall(loadBalancerName)); err != nil { - if isForbidden(err) && gce.OnXPN() { + if err := ignoreNotFound(g.DeleteFirewall(loadBalancerName)); err != nil { + if isForbidden(err) && g.OnXPN() { glog.V(2).Infof("ensureInternalLoadBalancerDeleted(%v): could not delete traffic firewall on XPN cluster. Raising event.", loadBalancerName) - gce.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudDeleteCmd(loadBalancerName, gce.NetworkProjectID())) + g.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudDeleteCmd(loadBalancerName, g.NetworkProjectID())) } else { return err } @@ -255,21 +255,21 @@ func (gce *GCECloud) ensureInternalLoadBalancerDeleted(clusterName, clusterID st hcName := makeHealthCheckName(loadBalancerName, clusterID, sharedHealthCheck) glog.V(2).Infof("ensureInternalLoadBalancerDeleted(%v): deleting health check %v and its firewall", loadBalancerName, hcName) - if err := gce.teardownInternalHealthCheckAndFirewall(svc, hcName); err != nil { + if err := g.teardownInternalHealthCheckAndFirewall(svc, hcName); err != nil { return err } // Try deleting instance groups - expect ResourceInuse error if needed by other LBs igName := makeInstanceGroupName(clusterID) - if err := gce.ensureInternalInstanceGroupsDeleted(igName); err != nil && !isInUsedByError(err) { + if err := g.ensureInternalInstanceGroupsDeleted(igName); err != nil && !isInUsedByError(err) { return err } return nil } -func (gce *GCECloud) teardownInternalBackendService(bsName string) error { - if err := gce.DeleteRegionBackendService(bsName, gce.region); err != nil { +func (g *Cloud) teardownInternalBackendService(bsName string) error { + if err := g.DeleteRegionBackendService(bsName, g.region); err != nil { if isNotFound(err) { glog.V(2).Infof("teardownInternalBackendService(%v): backend service already deleted. err: %v", bsName, err) return nil @@ -284,8 +284,8 @@ func (gce *GCECloud) teardownInternalBackendService(bsName string) error { return nil } -func (gce *GCECloud) teardownInternalHealthCheckAndFirewall(svc *v1.Service, hcName string) error { - if err := gce.DeleteHealthCheck(hcName); err != nil { +func (g *Cloud) teardownInternalHealthCheckAndFirewall(svc *v1.Service, hcName string) error { + if err := g.DeleteHealthCheck(hcName); err != nil { if isNotFound(err) { glog.V(2).Infof("teardownInternalHealthCheckAndFirewall(%v): health check does not exist.", hcName) // Purposely do not early return - double check the firewall does not exist @@ -299,10 +299,10 @@ func (gce *GCECloud) teardownInternalHealthCheckAndFirewall(svc *v1.Service, hcN glog.V(2).Infof("teardownInternalHealthCheckAndFirewall(%v): health check deleted", hcName) hcFirewallName := makeHealthCheckFirewallNameFromHC(hcName) - if err := ignoreNotFound(gce.DeleteFirewall(hcFirewallName)); err != nil { - if isForbidden(err) && gce.OnXPN() { + if err := ignoreNotFound(g.DeleteFirewall(hcFirewallName)); err != nil { + if isForbidden(err) && g.OnXPN() { glog.V(2).Infof("teardownInternalHealthCheckAndFirewall(%v): could not delete health check traffic firewall on XPN cluster. Raising Event.", hcName) - gce.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudDeleteCmd(hcFirewallName, gce.NetworkProjectID())) + g.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudDeleteCmd(hcFirewallName, g.NetworkProjectID())) return nil } @@ -312,14 +312,14 @@ func (gce *GCECloud) teardownInternalHealthCheckAndFirewall(svc *v1.Service, hcN return nil } -func (gce *GCECloud) ensureInternalFirewall(svc *v1.Service, fwName, fwDesc string, sourceRanges []string, ports []string, protocol v1.Protocol, nodes []*v1.Node) error { +func (g *Cloud) ensureInternalFirewall(svc *v1.Service, fwName, fwDesc string, sourceRanges []string, ports []string, protocol v1.Protocol, nodes []*v1.Node) error { glog.V(2).Infof("ensureInternalFirewall(%v): checking existing firewall", fwName) - targetTags, err := gce.GetNodeTags(nodeNames(nodes)) + targetTags, err := g.GetNodeTags(nodeNames(nodes)) if err != nil { return err } - existingFirewall, err := gce.GetFirewall(fwName) + existingFirewall, err := g.GetFirewall(fwName) if err != nil && !isNotFound(err) { return err } @@ -327,7 +327,7 @@ func (gce *GCECloud) ensureInternalFirewall(svc *v1.Service, fwName, fwDesc stri expectedFirewall := &compute.Firewall{ Name: fwName, Description: fwDesc, - Network: gce.networkURL, + Network: g.networkURL, SourceRanges: sourceRanges, TargetTags: targetTags, Allowed: []*compute.FirewallAllowed{ @@ -340,10 +340,10 @@ func (gce *GCECloud) ensureInternalFirewall(svc *v1.Service, fwName, fwDesc stri if existingFirewall == nil { glog.V(2).Infof("ensureInternalFirewall(%v): creating firewall", fwName) - err = gce.CreateFirewall(expectedFirewall) - if err != nil && isForbidden(err) && gce.OnXPN() { + err = g.CreateFirewall(expectedFirewall) + if err != nil && isForbidden(err) && g.OnXPN() { glog.V(2).Infof("ensureInternalFirewall(%v): do not have permission to create firewall rule (on XPN). Raising event.", fwName) - gce.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudCreateCmd(expectedFirewall, gce.NetworkProjectID())) + g.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudCreateCmd(expectedFirewall, g.NetworkProjectID())) return nil } return err @@ -354,16 +354,16 @@ func (gce *GCECloud) ensureInternalFirewall(svc *v1.Service, fwName, fwDesc stri } glog.V(2).Infof("ensureInternalFirewall(%v): updating firewall", fwName) - err = gce.UpdateFirewall(expectedFirewall) - if err != nil && isForbidden(err) && gce.OnXPN() { + err = g.UpdateFirewall(expectedFirewall) + if err != nil && isForbidden(err) && g.OnXPN() { glog.V(2).Infof("ensureInternalFirewall(%v): do not have permission to update firewall rule (on XPN). Raising event.", fwName) - gce.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudUpdateCmd(expectedFirewall, gce.NetworkProjectID())) + g.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudUpdateCmd(expectedFirewall, g.NetworkProjectID())) return nil } return err } -func (gce *GCECloud) ensureInternalFirewalls(loadBalancerName, ipAddress, clusterID string, nm types.NamespacedName, svc *v1.Service, healthCheckPort string, sharedHealthCheck bool, nodes []*v1.Node) error { +func (g *Cloud) ensureInternalFirewalls(loadBalancerName, ipAddress, clusterID string, nm types.NamespacedName, svc *v1.Service, healthCheckPort string, sharedHealthCheck bool, nodes []*v1.Node) error { // First firewall is for ingress traffic fwDesc := makeFirewallDescription(nm.String(), ipAddress) ports, protocol := getPortsAndProtocol(svc.Spec.Ports) @@ -371,7 +371,7 @@ func (gce *GCECloud) ensureInternalFirewalls(loadBalancerName, ipAddress, cluste if err != nil { return err } - err = gce.ensureInternalFirewall(svc, loadBalancerName, fwDesc, sourceRanges.StringSlice(), ports, protocol, nodes) + err = g.ensureInternalFirewall(svc, loadBalancerName, fwDesc, sourceRanges.StringSlice(), ports, protocol, nodes) if err != nil { return err } @@ -379,24 +379,24 @@ func (gce *GCECloud) ensureInternalFirewalls(loadBalancerName, ipAddress, cluste // Second firewall is for health checking nodes / services fwHCName := makeHealthCheckFirewallName(loadBalancerName, clusterID, sharedHealthCheck) hcSrcRanges := LoadBalancerSrcRanges() - return gce.ensureInternalFirewall(svc, fwHCName, "", hcSrcRanges, []string{healthCheckPort}, v1.ProtocolTCP, nodes) + return g.ensureInternalFirewall(svc, fwHCName, "", hcSrcRanges, []string{healthCheckPort}, v1.ProtocolTCP, nodes) } -func (gce *GCECloud) ensureInternalHealthCheck(name string, svcName types.NamespacedName, shared bool, path string, port int32) (*compute.HealthCheck, error) { +func (g *Cloud) ensureInternalHealthCheck(name string, svcName types.NamespacedName, shared bool, path string, port int32) (*compute.HealthCheck, error) { glog.V(2).Infof("ensureInternalHealthCheck(%v, %v, %v): checking existing health check", name, path, port) expectedHC := newInternalLBHealthCheck(name, svcName, shared, path, port) - hc, err := gce.GetHealthCheck(name) + hc, err := g.GetHealthCheck(name) if err != nil && !isNotFound(err) { return nil, err } if hc == nil { glog.V(2).Infof("ensureInternalHealthCheck: did not find health check %v, creating one with port %v path %v", name, port, path) - if err = gce.CreateHealthCheck(expectedHC); err != nil { + if err = g.CreateHealthCheck(expectedHC); err != nil { return nil, err } - hc, err = gce.GetHealthCheck(name) + hc, err = g.GetHealthCheck(name) if err != nil { glog.Errorf("Failed to get http health check %v", err) return nil, err @@ -405,22 +405,25 @@ func (gce *GCECloud) ensureInternalHealthCheck(name string, svcName types.Namesp return hc, nil } - if healthChecksEqual(expectedHC, hc) { - return hc, nil - } - - glog.V(2).Infof("ensureInternalHealthCheck: health check %v exists but parameters have drifted - updating...", name) - if err := gce.UpdateHealthCheck(expectedHC); err != nil { - glog.Warningf("Failed to reconcile http health check %v parameters", name) - return nil, err + if needToUpdateHealthChecks(hc, expectedHC) { + glog.V(2).Infof("ensureInternalHealthCheck: health check %v exists but parameters have drifted - updating...", name) + expectedHC = mergeHealthChecks(hc, expectedHC) + if err := g.UpdateHealthCheck(expectedHC); err != nil { + glog.Warningf("Failed to reconcile http health check %v parameters", name) + return nil, err + } + glog.V(2).Infof("ensureInternalHealthCheck: corrected health check %v parameters successful", name) + hc, err = g.GetHealthCheck(name) + if err != nil { + return nil, err + } } - glog.V(2).Infof("ensureInternalHealthCheck: corrected health check %v parameters successful", name) return hc, nil } -func (gce *GCECloud) ensureInternalInstanceGroup(name, zone string, nodes []*v1.Node) (string, error) { +func (g *Cloud) ensureInternalInstanceGroup(name, zone string, nodes []*v1.Node) (string, error) { glog.V(2).Infof("ensureInternalInstanceGroup(%v, %v): checking group that it contains %v nodes", name, zone, len(nodes)) - ig, err := gce.GetInstanceGroup(name, zone) + ig, err := g.GetInstanceGroup(name, zone) if err != nil && !isNotFound(err) { return "", err } @@ -434,16 +437,16 @@ func (gce *GCECloud) ensureInternalInstanceGroup(name, zone string, nodes []*v1. if ig == nil { glog.V(2).Infof("ensureInternalInstanceGroup(%v, %v): creating instance group", name, zone) newIG := &compute.InstanceGroup{Name: name} - if err = gce.CreateInstanceGroup(newIG, zone); err != nil { + if err = g.CreateInstanceGroup(newIG, zone); err != nil { return "", err } - ig, err = gce.GetInstanceGroup(name, zone) + ig, err = g.GetInstanceGroup(name, zone) if err != nil { return "", err } } else { - instances, err := gce.ListInstancesInInstanceGroup(name, zone, allInstances) + instances, err := g.ListInstancesInInstanceGroup(name, zone, allInstances) if err != nil { return "", err } @@ -459,17 +462,17 @@ func (gce *GCECloud) ensureInternalInstanceGroup(name, zone string, nodes []*v1. if len(removeNodes) != 0 { glog.V(2).Infof("ensureInternalInstanceGroup(%v, %v): removing nodes: %v", name, zone, removeNodes) - instanceRefs := gce.ToInstanceReferences(zone, removeNodes) + instanceRefs := g.ToInstanceReferences(zone, removeNodes) // Possible we'll receive 404's here if the instance was deleted before getting to this point. - if err = gce.RemoveInstancesFromInstanceGroup(name, zone, instanceRefs); err != nil && !isNotFound(err) { + if err = g.RemoveInstancesFromInstanceGroup(name, zone, instanceRefs); err != nil && !isNotFound(err) { return "", err } } if len(addNodes) != 0 { glog.V(2).Infof("ensureInternalInstanceGroup(%v, %v): adding nodes: %v", name, zone, addNodes) - instanceRefs := gce.ToInstanceReferences(zone, addNodes) - if err = gce.AddInstancesToInstanceGroup(name, zone, instanceRefs); err != nil { + instanceRefs := g.ToInstanceReferences(zone, addNodes) + if err = g.AddInstancesToInstanceGroup(name, zone, instanceRefs); err != nil { return "", err } } @@ -479,12 +482,12 @@ func (gce *GCECloud) ensureInternalInstanceGroup(name, zone string, nodes []*v1. // ensureInternalInstanceGroups generates an unmanaged instance group for every zone // where a K8s node exists. It also ensures that each node belongs to an instance group -func (gce *GCECloud) ensureInternalInstanceGroups(name string, nodes []*v1.Node) ([]string, error) { +func (g *Cloud) ensureInternalInstanceGroups(name string, nodes []*v1.Node) ([]string, error) { zonedNodes := splitNodesByZone(nodes) - glog.V(2).Infof("ensureInternalInstanceGroups(%v): %d nodes over %d zones in region %v", name, len(nodes), len(zonedNodes), gce.region) + glog.V(2).Infof("ensureInternalInstanceGroups(%v): %d nodes over %d zones in region %v", name, len(nodes), len(zonedNodes), g.region) var igLinks []string for zone, nodes := range zonedNodes { - igLink, err := gce.ensureInternalInstanceGroup(name, zone, nodes) + igLink, err := g.ensureInternalInstanceGroup(name, zone, nodes) if err != nil { return []string{}, err } @@ -494,25 +497,25 @@ func (gce *GCECloud) ensureInternalInstanceGroups(name string, nodes []*v1.Node) return igLinks, nil } -func (gce *GCECloud) ensureInternalInstanceGroupsDeleted(name string) error { +func (g *Cloud) ensureInternalInstanceGroupsDeleted(name string) error { // List of nodes isn't available here - fetch all zones in region and try deleting this cluster's ig - zones, err := gce.ListZonesInRegion(gce.region) + zones, err := g.ListZonesInRegion(g.region) if err != nil { return err } glog.V(2).Infof("ensureInternalInstanceGroupsDeleted(%v): attempting delete instance group in all %d zones", name, len(zones)) for _, z := range zones { - if err := gce.DeleteInstanceGroup(name, z.Name); err != nil && !isNotFoundOrInUse(err) { + if err := g.DeleteInstanceGroup(name, z.Name); err != nil && !isNotFoundOrInUse(err) { return err } } return nil } -func (gce *GCECloud) ensureInternalBackendService(name, description string, affinityType v1.ServiceAffinity, scheme cloud.LbScheme, protocol v1.Protocol, igLinks []string, hcLink string) error { +func (g *Cloud) ensureInternalBackendService(name, description string, affinityType v1.ServiceAffinity, scheme cloud.LbScheme, protocol v1.Protocol, igLinks []string, hcLink string) error { glog.V(2).Infof("ensureInternalBackendService(%v, %v, %v): checking existing backend service with %d groups", name, scheme, protocol, len(igLinks)) - bs, err := gce.GetRegionBackendService(name, gce.region) + bs, err := g.GetRegionBackendService(name, g.region) if err != nil && !isNotFound(err) { return err } @@ -531,7 +534,7 @@ func (gce *GCECloud) ensureInternalBackendService(name, description string, affi // Create backend service if none was found if bs == nil { glog.V(2).Infof("ensureInternalBackendService: creating backend service %v", name) - err := gce.CreateRegionBackendService(expectedBS, gce.region) + err := g.CreateRegionBackendService(expectedBS, g.region) if err != nil { return err } @@ -546,7 +549,7 @@ func (gce *GCECloud) ensureInternalBackendService(name, description string, affi glog.V(2).Infof("ensureInternalBackendService: updating backend service %v", name) // Set fingerprint for optimistic locking expectedBS.Fingerprint = bs.Fingerprint - if err := gce.UpdateRegionBackendService(expectedBS, gce.region); err != nil { + if err := g.UpdateRegionBackendService(expectedBS, g.region); err != nil { return err } glog.V(2).Infof("ensureInternalBackendService: updated backend service %v successfully", name) @@ -554,9 +557,9 @@ func (gce *GCECloud) ensureInternalBackendService(name, description string, affi } // ensureInternalBackendServiceGroups updates backend services if their list of backend instance groups is incorrect. -func (gce *GCECloud) ensureInternalBackendServiceGroups(name string, igLinks []string) error { +func (g *Cloud) ensureInternalBackendServiceGroups(name string, igLinks []string) error { glog.V(2).Infof("ensureInternalBackendServiceGroups(%v): checking existing backend service's groups", name) - bs, err := gce.GetRegionBackendService(name, gce.region) + bs, err := g.GetRegionBackendService(name, g.region) if err != nil { return err } @@ -570,7 +573,7 @@ func (gce *GCECloud) ensureInternalBackendServiceGroups(name string, igLinks []s bs.Backends = backends glog.V(2).Infof("ensureInternalBackendServiceGroups: updating backend service %v", name) - if err := gce.UpdateRegionBackendService(bs, gce.region); err != nil { + if err := g.UpdateRegionBackendService(bs, g.region); err != nil { return err } glog.V(2).Infof("ensureInternalBackendServiceGroups: updated backend service %v successfully", name) @@ -620,15 +623,37 @@ func firewallRuleEqual(a, b *compute.Firewall) bool { equalStringSets(a.TargetTags, b.TargetTags) } -func healthChecksEqual(a, b *compute.HealthCheck) bool { - return a.HttpHealthCheck != nil && b.HttpHealthCheck != nil && - a.HttpHealthCheck.Port == b.HttpHealthCheck.Port && - a.HttpHealthCheck.RequestPath == b.HttpHealthCheck.RequestPath && - a.Description == b.Description && - a.CheckIntervalSec == b.CheckIntervalSec && - a.TimeoutSec == b.TimeoutSec && - a.UnhealthyThreshold == b.UnhealthyThreshold && - a.HealthyThreshold == b.HealthyThreshold +// mergeHealthChecks reconciles HealthCheck configures to be no smaller than +// the default values. +// E.g. old health check interval is 2s, new default is 8. +// The HC interval will be reconciled to 8 seconds. +// If the existing health check is larger than the default interval, +// the configuration will be kept. +func mergeHealthChecks(hc, newHC *compute.HealthCheck) *compute.HealthCheck { + if hc.CheckIntervalSec > newHC.CheckIntervalSec { + newHC.CheckIntervalSec = hc.CheckIntervalSec + } + if hc.TimeoutSec > newHC.TimeoutSec { + newHC.TimeoutSec = hc.TimeoutSec + } + if hc.UnhealthyThreshold > newHC.UnhealthyThreshold { + newHC.UnhealthyThreshold = hc.UnhealthyThreshold + } + if hc.HealthyThreshold > newHC.HealthyThreshold { + newHC.HealthyThreshold = hc.HealthyThreshold + } + return newHC +} + +// needToUpdateHealthChecks checks whether the healthcheck needs to be updated. +func needToUpdateHealthChecks(hc, newHC *compute.HealthCheck) bool { + if hc.HttpHealthCheck == nil || newHC.HttpHealthCheck == nil { + return true + } + changed := hc.HttpHealthCheck.Port != newHC.HttpHealthCheck.Port || hc.HttpHealthCheck.RequestPath != newHC.HttpHealthCheck.RequestPath || hc.Description != newHC.Description + changed = changed || hc.CheckIntervalSec < newHC.CheckIntervalSec || hc.TimeoutSec < newHC.TimeoutSec + changed = changed || hc.UnhealthyThreshold < newHC.UnhealthyThreshold || hc.HealthyThreshold < newHC.HealthyThreshold + return changed } // backendsListEqual asserts that backend lists are equal by instance group link only @@ -682,8 +707,8 @@ func getPortsAndProtocol(svcPorts []v1.ServicePort) (ports []string, protocol v1 return ports, protocol } -func (gce *GCECloud) getBackendServiceLink(name string) string { - return gce.service.BasePath + strings.Join([]string{gce.projectID, "regions", gce.region, "backendServices", name}, "/") +func (g *Cloud) getBackendServiceLink(name string) string { + return g.service.BasePath + strings.Join([]string{g.projectID, "regions", g.region, "backendServices", name}, "/") } func getNameFromLink(link string) string { diff --git a/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal_test.go b/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal_test.go index 328084091029d..8b08ce378e80e 100644 --- a/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal_test.go +++ b/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal_test.go @@ -34,7 +34,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/mock" ) -func createInternalLoadBalancer(gce *GCECloud, svc *v1.Service, existingFwdRule *compute.ForwardingRule, nodeNames []string, clusterName, clusterID, zoneName string) (*v1.LoadBalancerStatus, error) { +func createInternalLoadBalancer(gce *Cloud, svc *v1.Service, existingFwdRule *compute.ForwardingRule, nodeNames []string, clusterName, clusterID, zoneName string) (*v1.LoadBalancerStatus, error) { nodes, err := createAndInsertNodes(gce, nodeNames, zoneName) if err != nil { return nil, err @@ -231,7 +231,7 @@ func TestEnsureInternalLoadBalancerClearPreviousResources(t *testing.T) { // Create a healthcheck with an incorrect threshold existingHC := newInternalLBHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort) - existingHC.HealthyThreshold = gceHcHealthyThreshold * 10 + existingHC.CheckIntervalSec = gceHcCheckIntervalSeconds - 1 gce.CreateHealthCheck(existingHC) // Create a backend Service that's missing Description and Backends @@ -268,6 +268,34 @@ func TestEnsureInternalLoadBalancerClearPreviousResources(t *testing.T) { assert.NotEqual(t, bs, existingBS) } +func TestEnsureInternalLoadBalancerHealthCheckConfigurable(t *testing.T) { + t.Parallel() + + vals := DefaultTestClusterValues() + gce, err := fakeGCECloud(vals) + require.NoError(t, err) + + svc := fakeLoadbalancerService(string(LBTypeInternal)) + lbName := gce.GetLoadBalancerName(context.TODO(), "", svc) + + sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc) + hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck) + hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort() + nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace} + + // Create a healthcheck with an incorrect threshold + existingHC := newInternalLBHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort) + existingHC.CheckIntervalSec = gceHcCheckIntervalSeconds * 10 + gce.CreateHealthCheck(existingHC) + + _, err = createInternalLoadBalancer(gce, svc, nil, []string{"test-node-1"}, vals.ClusterName, vals.ClusterID, vals.ZoneName) + assert.NoError(t, err) + + healthcheck, err := gce.GetHealthCheck(hcName) + require.NoError(t, err) + assert.Equal(t, healthcheck, existingHC) +} + func TestUpdateInternalLoadBalancerBackendServices(t *testing.T) { t.Parallel() @@ -307,19 +335,19 @@ func TestUpdateInternalLoadBalancerBackendServices(t *testing.T) { require.NoError(t, err) // Check that the new BackendService has the correct attributes - url_base := fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s", vals.ProjectID) + urlBase := fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s", vals.ProjectID) assert.NotEqual(t, existingBS, bs) assert.Equal( t, bs.SelfLink, - fmt.Sprintf("%s/regions/%s/backendServices/%s", url_base, vals.Region, bs.Name), + fmt.Sprintf("%s/regions/%s/backendServices/%s", urlBase, vals.Region, bs.Name), ) assert.Equal(t, bs.Description, `{"kubernetes.io/service-name":"/"}`) assert.Equal( t, bs.HealthChecks, - []string{fmt.Sprintf("%s/global/healthChecks/k8s-%s-node", url_base, vals.ClusterID)}, + []string{fmt.Sprintf("%s/global/healthChecks/k8s-%s-node", urlBase, vals.ClusterID)}, ) } @@ -459,16 +487,16 @@ func TestClearPreviousInternalResources(t *testing.T) { c := gce.c.(*cloud.MockGCE) require.NoError(t, err) - hc_1, err := gce.ensureInternalHealthCheck("hc_1", nm, false, "healthz", 12345) + hc1, err := gce.ensureInternalHealthCheck("hc1", nm, false, "healthz", 12345) require.NoError(t, err) - hc_2, err := gce.ensureInternalHealthCheck("hc_2", nm, false, "healthz", 12346) + hc2, err := gce.ensureInternalHealthCheck("hc2", nm, false, "healthz", 12346) require.NoError(t, err) err = gce.ensureInternalBackendService(svc.ObjectMeta.Name, "", svc.Spec.SessionAffinity, cloud.SchemeInternal, v1.ProtocolTCP, []string{}, "") require.NoError(t, err) backendSvc, err := gce.GetRegionBackendService(svc.ObjectMeta.Name, gce.region) - backendSvc.HealthChecks = []string{hc_1.SelfLink, hc_2.SelfLink} + backendSvc.HealthChecks = []string{hc1.SelfLink, hc2.SelfLink} c.MockRegionBackendServices.DeleteHook = mock.DeleteRegionBackendServicesErrHook c.MockHealthChecks.DeleteHook = mock.DeleteHealthChecksInternalErrHook @@ -477,27 +505,27 @@ func TestClearPreviousInternalResources(t *testing.T) { backendSvc, err = gce.GetRegionBackendService(svc.ObjectMeta.Name, gce.region) assert.NoError(t, err) assert.NotNil(t, backendSvc, "BackendService should not be deleted when api is mocked out.") - hc_1, err = gce.GetHealthCheck("hc_1") + hc1, err = gce.GetHealthCheck("hc1") assert.NoError(t, err) - assert.NotNil(t, hc_1, "HealthCheck should not be deleted when there are more than one healthcheck attached.") - hc_2, err = gce.GetHealthCheck("hc_2") + assert.NotNil(t, hc1, "HealthCheck should not be deleted when there are more than one healthcheck attached.") + hc2, err = gce.GetHealthCheck("hc2") assert.NoError(t, err) - assert.NotNil(t, hc_2, "HealthCheck should not be deleted when there are more than one healthcheck attached.") + assert.NotNil(t, hc2, "HealthCheck should not be deleted when there are more than one healthcheck attached.") c.MockRegionBackendServices.DeleteHook = mock.DeleteRegionBackendServicesInUseErrHook - backendSvc.HealthChecks = []string{hc_1.SelfLink} + backendSvc.HealthChecks = []string{hc1.SelfLink} gce.clearPreviousInternalResources(svc, loadBalancerName, backendSvc, "expectedBSName", "expectedHCName") - hc_1, err = gce.GetHealthCheck("hc_1") + hc1, err = gce.GetHealthCheck("hc1") assert.NoError(t, err) - assert.NotNil(t, hc_1, "HealthCheck should not be deleted when api is mocked out.") + assert.NotNil(t, hc1, "HealthCheck should not be deleted when api is mocked out.") c.MockHealthChecks.DeleteHook = mock.DeleteHealthChecksInuseErrHook gce.clearPreviousInternalResources(svc, loadBalancerName, backendSvc, "expectedBSName", "expectedHCName") - hc_1, err = gce.GetHealthCheck("hc_1") + hc1, err = gce.GetHealthCheck("hc1") assert.NoError(t, err) - assert.NotNil(t, hc_1, "HealthCheck should not be deleted when api is mocked out.") + assert.NotNil(t, hc1, "HealthCheck should not be deleted when api is mocked out.") c.MockRegionBackendServices.DeleteHook = nil c.MockHealthChecks.DeleteHook = nil @@ -506,9 +534,9 @@ func TestClearPreviousInternalResources(t *testing.T) { backendSvc, err = gce.GetRegionBackendService(svc.ObjectMeta.Name, gce.region) assert.Error(t, err) assert.Nil(t, backendSvc, "BackendService should be deleted.") - hc_1, err = gce.GetHealthCheck("hc_1") + hc1, err = gce.GetHealthCheck("hc1") assert.Error(t, err) - assert.Nil(t, hc_1, "HealthCheck should be deleted.") + assert.Nil(t, hc1, "HealthCheck should be deleted.") } func TestEnsureInternalFirewallSucceedsOnXPN(t *testing.T) { @@ -737,3 +765,85 @@ func TestEnsureInternalLoadBalancerErrors(t *testing.T) { }) } } + +func TestMergeHealthChecks(t *testing.T) { + t.Parallel() + for _, tc := range []struct { + desc string + checkIntervalSec int64 + timeoutSec int64 + healthyThreshold int64 + unhealthyThreshold int64 + wantCheckIntervalSec int64 + wantTimeoutSec int64 + wantHealthyThreshold int64 + wantUnhealthyThreshold int64 + }{ + {"unchanged", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"interval - too small - should reconcile", gceHcCheckIntervalSeconds - 1, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"timeout - too small - should reconcile", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds - 1, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"healthy threshold - too small - should reconcile", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold - 1, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"unhealthy threshold - too small - should reconcile", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold - 1, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"interval - user configured - should keep", gceHcCheckIntervalSeconds + 1, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds + 1, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"timeout - user configured - should keep", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds + 1, gceHcHealthyThreshold, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds + 1, gceHcHealthyThreshold, gceHcUnhealthyThreshold}, + {"healthy threshold - user configured - should keep", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold + 1, gceHcUnhealthyThreshold, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold + 1, gceHcUnhealthyThreshold}, + {"unhealthy threshold - user configured - should keep", gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold + 1, gceHcCheckIntervalSeconds, gceHcTimeoutSeconds, gceHcHealthyThreshold, gceHcUnhealthyThreshold + 1}, + } { + t.Run(tc.desc, func(t *testing.T) { + wantHC := newInternalLBHealthCheck("hc", types.NamespacedName{Name: "svc", Namespace: "default"}, false, "/", 12345) + hc := &compute.HealthCheck{ + CheckIntervalSec: tc.checkIntervalSec, + TimeoutSec: tc.timeoutSec, + HealthyThreshold: tc.healthyThreshold, + UnhealthyThreshold: tc.unhealthyThreshold, + } + mergeHealthChecks(hc, wantHC) + if wantHC.CheckIntervalSec != tc.wantCheckIntervalSec { + t.Errorf("wantHC.CheckIntervalSec = %d; want %d", wantHC.CheckIntervalSec, tc.checkIntervalSec) + } + if wantHC.TimeoutSec != tc.wantTimeoutSec { + t.Errorf("wantHC.TimeoutSec = %d; want %d", wantHC.TimeoutSec, tc.timeoutSec) + } + if wantHC.HealthyThreshold != tc.wantHealthyThreshold { + t.Errorf("wantHC.HealthyThreshold = %d; want %d", wantHC.HealthyThreshold, tc.healthyThreshold) + } + if wantHC.UnhealthyThreshold != tc.wantUnhealthyThreshold { + t.Errorf("wantHC.UnhealthyThreshold = %d; want %d", wantHC.UnhealthyThreshold, tc.unhealthyThreshold) + } + }) + } +} + +func TestCompareHealthChecks(t *testing.T) { + t.Parallel() + for _, tc := range []struct { + desc string + modifier func(*compute.HealthCheck) + wantChanged bool + }{ + {"unchanged", nil, false}, + {"nil HttpHealthCheck", func(hc *compute.HealthCheck) { hc.HttpHealthCheck = nil }, true}, + {"desc does not match", func(hc *compute.HealthCheck) { hc.Description = "bad-desc" }, true}, + {"port does not match", func(hc *compute.HealthCheck) { hc.HttpHealthCheck.Port = 54321 }, true}, + {"requestPath does not match", func(hc *compute.HealthCheck) { hc.HttpHealthCheck.RequestPath = "/anotherone" }, true}, + {"interval needs update", func(hc *compute.HealthCheck) { hc.CheckIntervalSec = gceHcCheckIntervalSeconds - 1 }, true}, + {"timeout needs update", func(hc *compute.HealthCheck) { hc.TimeoutSec = gceHcTimeoutSeconds - 1 }, true}, + {"healthy threshold needs update", func(hc *compute.HealthCheck) { hc.HealthyThreshold = gceHcHealthyThreshold - 1 }, true}, + {"unhealthy threshold needs update", func(hc *compute.HealthCheck) { hc.UnhealthyThreshold = gceHcUnhealthyThreshold - 1 }, true}, + {"interval does not need update", func(hc *compute.HealthCheck) { hc.CheckIntervalSec = gceHcCheckIntervalSeconds + 1 }, false}, + {"timeout does not need update", func(hc *compute.HealthCheck) { hc.TimeoutSec = gceHcTimeoutSeconds + 1 }, false}, + {"healthy threshold does not need update", func(hc *compute.HealthCheck) { hc.HealthyThreshold = gceHcHealthyThreshold + 1 }, false}, + {"unhealthy threshold does not need update", func(hc *compute.HealthCheck) { hc.UnhealthyThreshold = gceHcUnhealthyThreshold + 1 }, false}, + } { + t.Run(tc.desc, func(t *testing.T) { + hc := newInternalLBHealthCheck("hc", types.NamespacedName{Name: "svc", Namespace: "default"}, false, "/", 12345) + wantHC := newInternalLBHealthCheck("hc", types.NamespacedName{Name: "svc", Namespace: "default"}, false, "/", 12345) + if tc.modifier != nil { + tc.modifier(hc) + } + if gotChanged := needToUpdateHealthChecks(hc, wantHC); gotChanged != tc.wantChanged { + t.Errorf("needToUpdateHealthChecks(%#v, %#v) = %t; want changed = %t", hc, wantHC, gotChanged, tc.wantChanged) + } + }) + } +} diff --git a/pkg/cloudprovider/providers/gce/gce_loadbalancer_utils_test.go b/pkg/cloudprovider/providers/gce/gce_loadbalancer_utils_test.go index bdea0d5eb037a..7c133c7c9a227 100644 --- a/pkg/cloudprovider/providers/gce/gce_loadbalancer_utils_test.go +++ b/pkg/cloudprovider/providers/gce/gce_loadbalancer_utils_test.go @@ -67,7 +67,7 @@ var ( FilewallChangeMsg = fmt.Sprintf("%s %s %s", v1.EventTypeNormal, eventReasonManualChange, eventMsgFirewallChange) ) -func createAndInsertNodes(gce *GCECloud, nodeNames []string, zoneName string) ([]*v1.Node, error) { +func createAndInsertNodes(gce *Cloud, nodeNames []string, zoneName string) ([]*v1.Node, error) { nodes := []*v1.Node{} for _, name := range nodeNames { @@ -116,7 +116,7 @@ func createAndInsertNodes(gce *GCECloud, nodeNames []string, zoneName string) ([ return nodes, nil } -func assertExternalLbResources(t *testing.T, gce *GCECloud, apiService *v1.Service, vals TestClusterValues, nodeNames []string) { +func assertExternalLbResources(t *testing.T, gce *Cloud, apiService *v1.Service, vals TestClusterValues, nodeNames []string) { lbName := gce.GetLoadBalancerName(context.TODO(), "", apiService) hcName := MakeNodesHealthCheckName(vals.ClusterID) @@ -141,7 +141,7 @@ func assertExternalLbResources(t *testing.T, gce *GCECloud, apiService *v1.Servi assert.Equal(t, 1, len(pool.Instances)) // Check that HealthCheck is created - healthcheck, err := gce.GetHttpHealthCheck(hcName) + healthcheck, err := gce.GetHTTPHealthCheck(hcName) require.NoError(t, err) assert.Equal(t, hcName, healthcheck.Name) @@ -153,7 +153,7 @@ func assertExternalLbResources(t *testing.T, gce *GCECloud, apiService *v1.Servi assert.Equal(t, "123-123", fwdRule.PortRange) } -func assertExternalLbResourcesDeleted(t *testing.T, gce *GCECloud, apiService *v1.Service, vals TestClusterValues, firewallsDeleted bool) { +func assertExternalLbResourcesDeleted(t *testing.T, gce *Cloud, apiService *v1.Service, vals TestClusterValues, firewallsDeleted bool) { lbName := gce.GetLoadBalancerName(context.TODO(), "", apiService) hcName := MakeNodesHealthCheckName(vals.ClusterID) @@ -182,13 +182,13 @@ func assertExternalLbResourcesDeleted(t *testing.T, gce *GCECloud, apiService *v assert.Nil(t, pool) // Check that HealthCheck is deleted - healthcheck, err := gce.GetHttpHealthCheck(hcName) + healthcheck, err := gce.GetHTTPHealthCheck(hcName) require.Error(t, err) assert.Nil(t, healthcheck) } -func assertInternalLbResources(t *testing.T, gce *GCECloud, apiService *v1.Service, vals TestClusterValues, nodeNames []string) { +func assertInternalLbResources(t *testing.T, gce *Cloud, apiService *v1.Service, vals TestClusterValues, nodeNames []string) { lbName := gce.GetLoadBalancerName(context.TODO(), "", apiService) // Check that Instance Group is created @@ -241,7 +241,7 @@ func assertInternalLbResources(t *testing.T, gce *GCECloud, apiService *v1.Servi assert.Equal(t, gce.NetworkURL(), fwdRule.Subnetwork) } -func assertInternalLbResourcesDeleted(t *testing.T, gce *GCECloud, apiService *v1.Service, vals TestClusterValues, firewallsDeleted bool) { +func assertInternalLbResourcesDeleted(t *testing.T, gce *Cloud, apiService *v1.Service, vals TestClusterValues, firewallsDeleted bool) { lbName := gce.GetLoadBalancerName(context.TODO(), "", apiService) sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(apiService) hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck) diff --git a/pkg/cloudprovider/providers/gce/gce_networkendpointgroup.go b/pkg/cloudprovider/providers/gce/gce_networkendpointgroup.go index f82781e08d9ba..b7aa998cc34e8 100644 --- a/pkg/cloudprovider/providers/gce/gce_networkendpointgroup.go +++ b/pkg/cloudprovider/providers/gce/gce_networkendpointgroup.go @@ -27,40 +27,38 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta" ) -const ( - NEGIPPortNetworkEndpointType = "GCE_VM_IP_PORT" -) - func newNetworkEndpointGroupMetricContext(request string, zone string) *metricContext { return newGenericMetricContext("networkendpointgroup_", request, unusedMetricLabel, zone, computeBetaVersion) } -func (gce *GCECloud) GetNetworkEndpointGroup(name string, zone string) (*computebeta.NetworkEndpointGroup, error) { +// GetNetworkEndpointGroup returns the collection of network endpoints for the name in zone +func (g *Cloud) GetNetworkEndpointGroup(name string, zone string) (*computebeta.NetworkEndpointGroup, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newNetworkEndpointGroupMetricContext("get", zone) - v, err := gce.c.BetaNetworkEndpointGroups().Get(ctx, meta.ZonalKey(name, zone)) + v, err := g.c.BetaNetworkEndpointGroups().Get(ctx, meta.ZonalKey(name, zone)) return v, mc.Observe(err) } -func (gce *GCECloud) ListNetworkEndpointGroup(zone string) ([]*computebeta.NetworkEndpointGroup, error) { +// ListNetworkEndpointGroup returns the collection of network endpoints for the zone +func (g *Cloud) ListNetworkEndpointGroup(zone string) ([]*computebeta.NetworkEndpointGroup, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newNetworkEndpointGroupMetricContext("list", zone) - negs, err := gce.c.BetaNetworkEndpointGroups().List(ctx, zone, filter.None) + negs, err := g.c.BetaNetworkEndpointGroups().List(ctx, zone, filter.None) return negs, mc.Observe(err) } // AggregatedListNetworkEndpointGroup returns a map of zone -> endpoint group. -func (gce *GCECloud) AggregatedListNetworkEndpointGroup() (map[string][]*computebeta.NetworkEndpointGroup, error) { +func (g *Cloud) AggregatedListNetworkEndpointGroup() (map[string][]*computebeta.NetworkEndpointGroup, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newNetworkEndpointGroupMetricContext("aggregated_list", "") // TODO: filter for the region the cluster is in. - all, err := gce.c.BetaNetworkEndpointGroups().AggregatedList(ctx, filter.None) + all, err := g.c.BetaNetworkEndpointGroups().AggregatedList(ctx, filter.None) if err != nil { return nil, mc.Observe(err) } @@ -77,23 +75,26 @@ func (gce *GCECloud) AggregatedListNetworkEndpointGroup() (map[string][]*compute return ret, mc.Observe(nil) } -func (gce *GCECloud) CreateNetworkEndpointGroup(neg *computebeta.NetworkEndpointGroup, zone string) error { +// CreateNetworkEndpointGroup creates an endpoint group in the zone +func (g *Cloud) CreateNetworkEndpointGroup(neg *computebeta.NetworkEndpointGroup, zone string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newNetworkEndpointGroupMetricContext("create", zone) - return mc.Observe(gce.c.BetaNetworkEndpointGroups().Insert(ctx, meta.ZonalKey(neg.Name, zone), neg)) + return mc.Observe(g.c.BetaNetworkEndpointGroups().Insert(ctx, meta.ZonalKey(neg.Name, zone), neg)) } -func (gce *GCECloud) DeleteNetworkEndpointGroup(name string, zone string) error { +// DeleteNetworkEndpointGroup deletes the name endpoint group from the zone +func (g *Cloud) DeleteNetworkEndpointGroup(name string, zone string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newNetworkEndpointGroupMetricContext("delete", zone) - return mc.Observe(gce.c.BetaNetworkEndpointGroups().Delete(ctx, meta.ZonalKey(name, zone))) + return mc.Observe(g.c.BetaNetworkEndpointGroups().Delete(ctx, meta.ZonalKey(name, zone))) } -func (gce *GCECloud) AttachNetworkEndpoints(name, zone string, endpoints []*computebeta.NetworkEndpoint) error { +// AttachNetworkEndpoints associates the referenced endpoints with the named endpoint group in the zone +func (g *Cloud) AttachNetworkEndpoints(name, zone string, endpoints []*computebeta.NetworkEndpoint) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -101,10 +102,11 @@ func (gce *GCECloud) AttachNetworkEndpoints(name, zone string, endpoints []*comp req := &computebeta.NetworkEndpointGroupsAttachEndpointsRequest{ NetworkEndpoints: endpoints, } - return mc.Observe(gce.c.BetaNetworkEndpointGroups().AttachNetworkEndpoints(ctx, meta.ZonalKey(name, zone), req)) + return mc.Observe(g.c.BetaNetworkEndpointGroups().AttachNetworkEndpoints(ctx, meta.ZonalKey(name, zone), req)) } -func (gce *GCECloud) DetachNetworkEndpoints(name, zone string, endpoints []*computebeta.NetworkEndpoint) error { +// DetachNetworkEndpoints breaks the association between the referenced endpoints and the named endpoint group in the zone +func (g *Cloud) DetachNetworkEndpoints(name, zone string, endpoints []*computebeta.NetworkEndpoint) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -112,10 +114,11 @@ func (gce *GCECloud) DetachNetworkEndpoints(name, zone string, endpoints []*comp req := &computebeta.NetworkEndpointGroupsDetachEndpointsRequest{ NetworkEndpoints: endpoints, } - return mc.Observe(gce.c.BetaNetworkEndpointGroups().DetachNetworkEndpoints(ctx, meta.ZonalKey(name, zone), req)) + return mc.Observe(g.c.BetaNetworkEndpointGroups().DetachNetworkEndpoints(ctx, meta.ZonalKey(name, zone), req)) } -func (gce *GCECloud) ListNetworkEndpoints(name, zone string, showHealthStatus bool) ([]*computebeta.NetworkEndpointWithHealthStatus, error) { +// ListNetworkEndpoints returns all the endpoints associated with the endpoint group in zone and optionally their status. +func (g *Cloud) ListNetworkEndpoints(name, zone string, showHealthStatus bool) ([]*computebeta.NetworkEndpointWithHealthStatus, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -127,6 +130,6 @@ func (gce *GCECloud) ListNetworkEndpoints(name, zone string, showHealthStatus bo req := &computebeta.NetworkEndpointGroupsListEndpointsRequest{ HealthStatus: healthStatus, } - l, err := gce.c.BetaNetworkEndpointGroups().ListNetworkEndpoints(ctx, meta.ZonalKey(name, zone), req, filter.None) + l, err := g.c.BetaNetworkEndpointGroups().ListNetworkEndpoints(ctx, meta.ZonalKey(name, zone), req, filter.None) return l, mc.Observe(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_routes.go b/pkg/cloudprovider/providers/gce/gce_routes.go index f53a620912e93..703e2dd3cf2b2 100644 --- a/pkg/cloudprovider/providers/gce/gce_routes.go +++ b/pkg/cloudprovider/providers/gce/gce_routes.go @@ -37,14 +37,14 @@ func newRoutesMetricContext(request string) *metricContext { } // ListRoutes in the cloud environment. -func (gce *GCECloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudprovider.Route, error) { +func (g *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudprovider.Route, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newRoutesMetricContext("list") prefix := truncateClusterName(clusterName) - f := filter.Regexp("name", prefix+"-.*").AndRegexp("network", gce.NetworkURL()).AndRegexp("description", k8sNodeRouteTag) - routes, err := gce.c.Routes().List(ctx, f) + f := filter.Regexp("name", prefix+"-.*").AndRegexp("network", g.NetworkURL()).AndRegexp("description", k8sNodeRouteTag) + routes, err := g.c.Routes().List(ctx, f) if err != nil { return nil, mc.Observe(err) } @@ -63,13 +63,13 @@ func (gce *GCECloud) ListRoutes(ctx context.Context, clusterName string) ([]*clo } // CreateRoute in the cloud environment. -func (gce *GCECloud) CreateRoute(ctx context.Context, clusterName string, nameHint string, route *cloudprovider.Route) error { +func (g *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint string, route *cloudprovider.Route) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newRoutesMetricContext("create") - targetInstance, err := gce.getInstanceByName(mapNodeNameToInstanceName(route.TargetNode)) + targetInstance, err := g.getInstanceByName(mapNodeNameToInstanceName(route.TargetNode)) if err != nil { return mc.Observe(err) } @@ -77,11 +77,11 @@ func (gce *GCECloud) CreateRoute(ctx context.Context, clusterName string, nameHi Name: truncateClusterName(clusterName) + "-" + nameHint, DestRange: route.DestinationCIDR, NextHopInstance: fmt.Sprintf("zones/%s/instances/%s", targetInstance.Zone, targetInstance.Name), - Network: gce.NetworkURL(), + Network: g.NetworkURL(), Priority: 1000, Description: k8sNodeRouteTag, } - err = gce.c.Routes().Insert(ctx, meta.GlobalKey(cr.Name), cr) + err = g.c.Routes().Insert(ctx, meta.GlobalKey(cr.Name), cr) if isHTTPErrorCode(err, http.StatusConflict) { glog.Infof("Route %q already exists.", cr.Name) err = nil @@ -90,12 +90,12 @@ func (gce *GCECloud) CreateRoute(ctx context.Context, clusterName string, nameHi } // DeleteRoute from the cloud environment. -func (gce *GCECloud) DeleteRoute(ctx context.Context, clusterName string, route *cloudprovider.Route) error { +func (g *Cloud) DeleteRoute(ctx context.Context, clusterName string, route *cloudprovider.Route) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newRoutesMetricContext("delete") - return mc.Observe(gce.c.Routes().Delete(ctx, meta.GlobalKey(route.Name))) + return mc.Observe(g.c.Routes().Delete(ctx, meta.GlobalKey(route.Name))) } func truncateClusterName(clusterName string) string { diff --git a/pkg/cloudprovider/providers/gce/gce_securitypolicy.go b/pkg/cloudprovider/providers/gce/gce_securitypolicy.go index 293946590b3d7..3ce2f71fa5406 100644 --- a/pkg/cloudprovider/providers/gce/gce_securitypolicy.go +++ b/pkg/cloudprovider/providers/gce/gce_securitypolicy.go @@ -29,88 +29,88 @@ func newSecurityPolicyMetricContextWithVersion(request, version string) *metricC } // GetBetaSecurityPolicy retrieves a security policy. -func (gce *GCECloud) GetBetaSecurityPolicy(name string) (*computebeta.SecurityPolicy, error) { +func (g *Cloud) GetBetaSecurityPolicy(name string) (*computebeta.SecurityPolicy, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("get", computeBetaVersion) - v, err := gce.c.BetaSecurityPolicies().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.BetaSecurityPolicies().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // ListBetaSecurityPolicy lists all security policies in the project. -func (gce *GCECloud) ListBetaSecurityPolicy() ([]*computebeta.SecurityPolicy, error) { +func (g *Cloud) ListBetaSecurityPolicy() ([]*computebeta.SecurityPolicy, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("list", computeBetaVersion) - v, err := gce.c.BetaSecurityPolicies().List(ctx, filter.None) + v, err := g.c.BetaSecurityPolicies().List(ctx, filter.None) return v, mc.Observe(err) } // CreateBetaSecurityPolicy creates the given security policy. -func (gce *GCECloud) CreateBetaSecurityPolicy(sp *computebeta.SecurityPolicy) error { +func (g *Cloud) CreateBetaSecurityPolicy(sp *computebeta.SecurityPolicy) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("create", computeBetaVersion) - return mc.Observe(gce.c.BetaSecurityPolicies().Insert(ctx, meta.GlobalKey(sp.Name), sp)) + return mc.Observe(g.c.BetaSecurityPolicies().Insert(ctx, meta.GlobalKey(sp.Name), sp)) } // DeleteBetaSecurityPolicy deletes the given security policy. -func (gce *GCECloud) DeleteBetaSecurityPolicy(name string) error { +func (g *Cloud) DeleteBetaSecurityPolicy(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("delete", computeBetaVersion) - return mc.Observe(gce.c.BetaSecurityPolicies().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.BetaSecurityPolicies().Delete(ctx, meta.GlobalKey(name))) } // PatchBetaSecurityPolicy applies the given security policy as a // patch to an existing security policy. -func (gce *GCECloud) PatchBetaSecurityPolicy(sp *computebeta.SecurityPolicy) error { +func (g *Cloud) PatchBetaSecurityPolicy(sp *computebeta.SecurityPolicy) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("patch", computeBetaVersion) - return mc.Observe(gce.c.BetaSecurityPolicies().Patch(ctx, meta.GlobalKey(sp.Name), sp)) + return mc.Observe(g.c.BetaSecurityPolicies().Patch(ctx, meta.GlobalKey(sp.Name), sp)) } // GetRuleForBetaSecurityPolicy gets rule from a security policy. -func (gce *GCECloud) GetRuleForBetaSecurityPolicy(name string) (*computebeta.SecurityPolicyRule, error) { +func (g *Cloud) GetRuleForBetaSecurityPolicy(name string) (*computebeta.SecurityPolicyRule, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("get_rule", computeBetaVersion) - v, err := gce.c.BetaSecurityPolicies().GetRule(ctx, meta.GlobalKey(name)) + v, err := g.c.BetaSecurityPolicies().GetRule(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } // AddRuletoBetaSecurityPolicy adds the given security policy rule to // a security policy. -func (gce *GCECloud) AddRuletoBetaSecurityPolicy(name string, spr *computebeta.SecurityPolicyRule) error { +func (g *Cloud) AddRuletoBetaSecurityPolicy(name string, spr *computebeta.SecurityPolicyRule) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("add_rule", computeBetaVersion) - return mc.Observe(gce.c.BetaSecurityPolicies().AddRule(ctx, meta.GlobalKey(name), spr)) + return mc.Observe(g.c.BetaSecurityPolicies().AddRule(ctx, meta.GlobalKey(name), spr)) } // PatchRuleForBetaSecurityPolicy patches the given security policy // rule to a security policy. -func (gce *GCECloud) PatchRuleForBetaSecurityPolicy(name string, spr *computebeta.SecurityPolicyRule) error { +func (g *Cloud) PatchRuleForBetaSecurityPolicy(name string, spr *computebeta.SecurityPolicyRule) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("patch_rule", computeBetaVersion) - return mc.Observe(gce.c.BetaSecurityPolicies().PatchRule(ctx, meta.GlobalKey(name), spr)) + return mc.Observe(g.c.BetaSecurityPolicies().PatchRule(ctx, meta.GlobalKey(name), spr)) } // RemoveRuleFromBetaSecurityPolicy removes rule from a security policy. -func (gce *GCECloud) RemoveRuleFromBetaSecurityPolicy(name string) error { +func (g *Cloud) RemoveRuleFromBetaSecurityPolicy(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newSecurityPolicyMetricContextWithVersion("remove_rule", computeBetaVersion) - return mc.Observe(gce.c.BetaSecurityPolicies().RemoveRule(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.BetaSecurityPolicies().RemoveRule(ctx, meta.GlobalKey(name))) } diff --git a/pkg/cloudprovider/providers/gce/gce_targetpool.go b/pkg/cloudprovider/providers/gce/gce_targetpool.go index 8c1127e749e65..65388b44980a6 100644 --- a/pkg/cloudprovider/providers/gce/gce_targetpool.go +++ b/pkg/cloudprovider/providers/gce/gce_targetpool.go @@ -28,35 +28,35 @@ func newTargetPoolMetricContext(request, region string) *metricContext { } // GetTargetPool returns the TargetPool by name. -func (gce *GCECloud) GetTargetPool(name, region string) (*compute.TargetPool, error) { +func (g *Cloud) GetTargetPool(name, region string) (*compute.TargetPool, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetPoolMetricContext("get", region) - v, err := gce.c.TargetPools().Get(ctx, meta.RegionalKey(name, region)) + v, err := g.c.TargetPools().Get(ctx, meta.RegionalKey(name, region)) return v, mc.Observe(err) } // CreateTargetPool creates the passed TargetPool -func (gce *GCECloud) CreateTargetPool(tp *compute.TargetPool, region string) error { +func (g *Cloud) CreateTargetPool(tp *compute.TargetPool, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetPoolMetricContext("create", region) - return mc.Observe(gce.c.TargetPools().Insert(ctx, meta.RegionalKey(tp.Name, region), tp)) + return mc.Observe(g.c.TargetPools().Insert(ctx, meta.RegionalKey(tp.Name, region), tp)) } // DeleteTargetPool deletes TargetPool by name. -func (gce *GCECloud) DeleteTargetPool(name, region string) error { +func (g *Cloud) DeleteTargetPool(name, region string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetPoolMetricContext("delete", region) - return mc.Observe(gce.c.TargetPools().Delete(ctx, meta.RegionalKey(name, region))) + return mc.Observe(g.c.TargetPools().Delete(ctx, meta.RegionalKey(name, region))) } // AddInstancesToTargetPool adds instances by link to the TargetPool -func (gce *GCECloud) AddInstancesToTargetPool(name, region string, instanceRefs []*compute.InstanceReference) error { +func (g *Cloud) AddInstancesToTargetPool(name, region string, instanceRefs []*compute.InstanceReference) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -64,11 +64,11 @@ func (gce *GCECloud) AddInstancesToTargetPool(name, region string, instanceRefs Instances: instanceRefs, } mc := newTargetPoolMetricContext("add_instances", region) - return mc.Observe(gce.c.TargetPools().AddInstance(ctx, meta.RegionalKey(name, region), req)) + return mc.Observe(g.c.TargetPools().AddInstance(ctx, meta.RegionalKey(name, region), req)) } // RemoveInstancesFromTargetPool removes instances by link to the TargetPool -func (gce *GCECloud) RemoveInstancesFromTargetPool(name, region string, instanceRefs []*compute.InstanceReference) error { +func (g *Cloud) RemoveInstancesFromTargetPool(name, region string, instanceRefs []*compute.InstanceReference) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -76,5 +76,5 @@ func (gce *GCECloud) RemoveInstancesFromTargetPool(name, region string, instance Instances: instanceRefs, } mc := newTargetPoolMetricContext("remove_instances", region) - return mc.Observe(gce.c.TargetPools().RemoveInstance(ctx, meta.RegionalKey(name, region), req)) + return mc.Observe(g.c.TargetPools().RemoveInstance(ctx, meta.RegionalKey(name, region), req)) } diff --git a/pkg/cloudprovider/providers/gce/gce_targetproxy.go b/pkg/cloudprovider/providers/gce/gce_targetproxy.go index c5bd21aaedf5d..64a4190628eae 100644 --- a/pkg/cloudprovider/providers/gce/gce_targetproxy.go +++ b/pkg/cloudprovider/providers/gce/gce_targetproxy.go @@ -28,87 +28,87 @@ func newTargetProxyMetricContext(request string) *metricContext { return newGenericMetricContext("targetproxy", request, unusedMetricLabel, unusedMetricLabel, computeV1Version) } -// GetTargetHttpProxy returns the UrlMap by name. -func (gce *GCECloud) GetTargetHttpProxy(name string) (*compute.TargetHttpProxy, error) { +// GetTargetHTTPProxy returns the UrlMap by name. +func (g *Cloud) GetTargetHTTPProxy(name string) (*compute.TargetHttpProxy, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("get") - v, err := gce.c.TargetHttpProxies().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.TargetHttpProxies().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } -// CreateTargetHttpProxy creates a TargetHttpProxy -func (gce *GCECloud) CreateTargetHttpProxy(proxy *compute.TargetHttpProxy) error { +// CreateTargetHTTPProxy creates a TargetHttpProxy +func (g *Cloud) CreateTargetHTTPProxy(proxy *compute.TargetHttpProxy) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("create") - return mc.Observe(gce.c.TargetHttpProxies().Insert(ctx, meta.GlobalKey(proxy.Name), proxy)) + return mc.Observe(g.c.TargetHttpProxies().Insert(ctx, meta.GlobalKey(proxy.Name), proxy)) } -// SetUrlMapForTargetHttpProxy sets the given UrlMap for the given TargetHttpProxy. -func (gce *GCECloud) SetUrlMapForTargetHttpProxy(proxy *compute.TargetHttpProxy, urlMapLink string) error { +// SetURLMapForTargetHTTPProxy sets the given UrlMap for the given TargetHttpProxy. +func (g *Cloud) SetURLMapForTargetHTTPProxy(proxy *compute.TargetHttpProxy, urlMapLink string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() ref := &compute.UrlMapReference{UrlMap: urlMapLink} mc := newTargetProxyMetricContext("set_url_map") - return mc.Observe(gce.c.TargetHttpProxies().SetUrlMap(ctx, meta.GlobalKey(proxy.Name), ref)) + return mc.Observe(g.c.TargetHttpProxies().SetUrlMap(ctx, meta.GlobalKey(proxy.Name), ref)) } -// DeleteTargetHttpProxy deletes the TargetHttpProxy by name. -func (gce *GCECloud) DeleteTargetHttpProxy(name string) error { +// DeleteTargetHTTPProxy deletes the TargetHttpProxy by name. +func (g *Cloud) DeleteTargetHTTPProxy(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("delete") - return mc.Observe(gce.c.TargetHttpProxies().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.TargetHttpProxies().Delete(ctx, meta.GlobalKey(name))) } -// ListTargetHttpProxies lists all TargetHttpProxies in the project. -func (gce *GCECloud) ListTargetHttpProxies() ([]*compute.TargetHttpProxy, error) { +// ListTargetHTTPProxies lists all TargetHttpProxies in the project. +func (g *Cloud) ListTargetHTTPProxies() ([]*compute.TargetHttpProxy, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("list") - v, err := gce.c.TargetHttpProxies().List(ctx, filter.None) + v, err := g.c.TargetHttpProxies().List(ctx, filter.None) return v, mc.Observe(err) } // TargetHttpsProxy management -// GetTargetHttpsProxy returns the UrlMap by name. -func (gce *GCECloud) GetTargetHttpsProxy(name string) (*compute.TargetHttpsProxy, error) { +// GetTargetHTTPSProxy returns the UrlMap by name. +func (g *Cloud) GetTargetHTTPSProxy(name string) (*compute.TargetHttpsProxy, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("get") - v, err := gce.c.TargetHttpsProxies().Get(ctx, meta.GlobalKey(name)) + v, err := g.c.TargetHttpsProxies().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } -// CreateTargetHttpsProxy creates a TargetHttpsProxy -func (gce *GCECloud) CreateTargetHttpsProxy(proxy *compute.TargetHttpsProxy) error { +// CreateTargetHTTPSProxy creates a TargetHttpsProxy +func (g *Cloud) CreateTargetHTTPSProxy(proxy *compute.TargetHttpsProxy) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("create") - return mc.Observe(gce.c.TargetHttpsProxies().Insert(ctx, meta.GlobalKey(proxy.Name), proxy)) + return mc.Observe(g.c.TargetHttpsProxies().Insert(ctx, meta.GlobalKey(proxy.Name), proxy)) } -// SetUrlMapForTargetHttpsProxy sets the given UrlMap for the given TargetHttpsProxy. -func (gce *GCECloud) SetUrlMapForTargetHttpsProxy(proxy *compute.TargetHttpsProxy, urlMapLink string) error { +// SetURLMapForTargetHTTPSProxy sets the given UrlMap for the given TargetHttpsProxy. +func (g *Cloud) SetURLMapForTargetHTTPSProxy(proxy *compute.TargetHttpsProxy, urlMapLink string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("set_url_map") ref := &compute.UrlMapReference{UrlMap: urlMapLink} - return mc.Observe(gce.c.TargetHttpsProxies().SetUrlMap(ctx, meta.GlobalKey(proxy.Name), ref)) + return mc.Observe(g.c.TargetHttpsProxies().SetUrlMap(ctx, meta.GlobalKey(proxy.Name), ref)) } -// SetSslCertificateForTargetHttpsProxy sets the given SslCertificate for the given TargetHttpsProxy. -func (gce *GCECloud) SetSslCertificateForTargetHttpsProxy(proxy *compute.TargetHttpsProxy, sslCertURLs []string) error { +// SetSslCertificateForTargetHTTPSProxy sets the given SslCertificate for the given TargetHttpsProxy. +func (g *Cloud) SetSslCertificateForTargetHTTPSProxy(proxy *compute.TargetHttpsProxy, sslCertURLs []string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -116,24 +116,24 @@ func (gce *GCECloud) SetSslCertificateForTargetHttpsProxy(proxy *compute.TargetH req := &compute.TargetHttpsProxiesSetSslCertificatesRequest{ SslCertificates: sslCertURLs, } - return mc.Observe(gce.c.TargetHttpsProxies().SetSslCertificates(ctx, meta.GlobalKey(proxy.Name), req)) + return mc.Observe(g.c.TargetHttpsProxies().SetSslCertificates(ctx, meta.GlobalKey(proxy.Name), req)) } -// DeleteTargetHttpsProxy deletes the TargetHttpsProxy by name. -func (gce *GCECloud) DeleteTargetHttpsProxy(name string) error { +// DeleteTargetHTTPSProxy deletes the TargetHttpsProxy by name. +func (g *Cloud) DeleteTargetHTTPSProxy(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("delete") - return mc.Observe(gce.c.TargetHttpsProxies().Delete(ctx, meta.GlobalKey(name))) + return mc.Observe(g.c.TargetHttpsProxies().Delete(ctx, meta.GlobalKey(name))) } -// ListTargetHttpsProxies lists all TargetHttpsProxies in the project. -func (gce *GCECloud) ListTargetHttpsProxies() ([]*compute.TargetHttpsProxy, error) { +// ListTargetHTTPSProxies lists all TargetHttpsProxies in the project. +func (g *Cloud) ListTargetHTTPSProxies() ([]*compute.TargetHttpsProxy, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newTargetProxyMetricContext("list") - v, err := gce.c.TargetHttpsProxies().List(ctx, filter.None) + v, err := g.c.TargetHttpsProxies().List(ctx, filter.None) return v, mc.Observe(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_test.go b/pkg/cloudprovider/providers/gce/gce_test.go index 33b9e35f73c4a..627c3c50dccb8 100644 --- a/pkg/cloudprovider/providers/gce/gce_test.go +++ b/pkg/cloudprovider/providers/gce/gce_test.go @@ -91,7 +91,7 @@ func TestGetRegion(t *testing.T) { if regionName != "us-central1" { t.Errorf("Unexpected region from GetGCERegion: %s", regionName) } - gce := &GCECloud{ + gce := &Cloud{ localZone: zoneName, region: regionName, } @@ -299,7 +299,7 @@ func TestGetZoneByProviderID(t *testing.T) { }, } - gce := &GCECloud{ + gce := &Cloud{ localZone: "us-central1-f", region: "us-central1", } @@ -331,13 +331,13 @@ func TestGenerateCloudConfigs(t *testing.T) { NodeInstancePrefix: "node-prefix", Multizone: false, Regional: false, - ApiEndpoint: "", + APIEndpoint: "", LocalZone: "us-central1-a", AlphaFeatures: []string{}, } cloudBoilerplate := CloudConfig{ - ApiEndpoint: "", + APIEndpoint: "", ProjectID: "project-id", NetworkProjectID: "", Region: "us-central1", @@ -395,12 +395,12 @@ func TestGenerateCloudConfigs(t *testing.T) { name: "Specified API Endpint", config: func() ConfigGlobal { v := configBoilerplate - v.ApiEndpoint = "https://www.googleapis.com/compute/staging_v1/" + v.APIEndpoint = "https://www.googleapis.com/compute/staging_v1/" return v }, cloud: func() CloudConfig { v := cloudBoilerplate - v.ApiEndpoint = "https://www.googleapis.com/compute/staging_v1/" + v.APIEndpoint = "https://www.googleapis.com/compute/staging_v1/" return v }, }, diff --git a/pkg/cloudprovider/providers/gce/gce_tpu.go b/pkg/cloudprovider/providers/gce/gce_tpu.go index 0a78f62cb3ade..fda62851cfb5a 100644 --- a/pkg/cloudprovider/providers/gce/gce_tpu.go +++ b/pkg/cloudprovider/providers/gce/gce_tpu.go @@ -50,20 +50,20 @@ type tpuService struct { // CreateTPU creates the Cloud TPU node with the specified name in the // specified zone. -func (gce *GCECloud) CreateTPU(ctx context.Context, name, zone string, node *tpuapi.Node) (*tpuapi.Node, error) { +func (g *Cloud) CreateTPU(ctx context.Context, name, zone string, node *tpuapi.Node) (*tpuapi.Node, error) { var err error mc := newTPUMetricContext("create", zone) defer mc.Observe(err) var op *tpuapi.Operation - parent := getTPUParentName(gce.projectID, zone) - op, err = gce.tpuService.projects.Locations.Nodes.Create(parent, node).NodeId(name).Do() + parent := getTPUParentName(g.projectID, zone) + op, err = g.tpuService.projects.Locations.Nodes.Create(parent, node).NodeId(name).Do() if err != nil { return nil, err } glog.V(2).Infof("Creating Cloud TPU %q in zone %q with operation %q", name, zone, op.Name) - op, err = gce.waitForTPUOp(ctx, op) + op, err = g.waitForTPUOp(ctx, op) if err != nil { return nil, err } @@ -83,20 +83,20 @@ func (gce *GCECloud) CreateTPU(ctx context.Context, name, zone string, node *tpu // DeleteTPU deletes the Cloud TPU with the specified name in the specified // zone. -func (gce *GCECloud) DeleteTPU(ctx context.Context, name, zone string) error { +func (g *Cloud) DeleteTPU(ctx context.Context, name, zone string) error { var err error mc := newTPUMetricContext("delete", zone) defer mc.Observe(err) var op *tpuapi.Operation - name = getTPUName(gce.projectID, zone, name) - op, err = gce.tpuService.projects.Locations.Nodes.Delete(name).Do() + name = getTPUName(g.projectID, zone, name) + op, err = g.tpuService.projects.Locations.Nodes.Delete(name).Do() if err != nil { return err } glog.V(2).Infof("Deleting Cloud TPU %q in zone %q with operation %q", name, zone, op.Name) - op, err = gce.waitForTPUOp(ctx, op) + op, err = g.waitForTPUOp(ctx, op) if err != nil { return err } @@ -108,11 +108,11 @@ func (gce *GCECloud) DeleteTPU(ctx context.Context, name, zone string) error { } // GetTPU returns the Cloud TPU with the specified name in the specified zone. -func (gce *GCECloud) GetTPU(ctx context.Context, name, zone string) (*tpuapi.Node, error) { +func (g *Cloud) GetTPU(ctx context.Context, name, zone string) (*tpuapi.Node, error) { mc := newTPUMetricContext("get", zone) - name = getTPUName(gce.projectID, zone, name) - node, err := gce.tpuService.projects.Locations.Nodes.Get(name).Do() + name = getTPUName(g.projectID, zone, name) + node, err := g.tpuService.projects.Locations.Nodes.Get(name).Do() if err != nil { return nil, mc.Observe(err) } @@ -120,11 +120,11 @@ func (gce *GCECloud) GetTPU(ctx context.Context, name, zone string) (*tpuapi.Nod } // ListTPUs returns Cloud TPUs in the specified zone. -func (gce *GCECloud) ListTPUs(ctx context.Context, zone string) ([]*tpuapi.Node, error) { +func (g *Cloud) ListTPUs(ctx context.Context, zone string) ([]*tpuapi.Node, error) { mc := newTPUMetricContext("list", zone) - parent := getTPUParentName(gce.projectID, zone) - response, err := gce.tpuService.projects.Locations.Nodes.List(parent).Do() + parent := getTPUParentName(g.projectID, zone) + response, err := g.tpuService.projects.Locations.Nodes.List(parent).Do() if err != nil { return nil, mc.Observe(err) } @@ -132,10 +132,10 @@ func (gce *GCECloud) ListTPUs(ctx context.Context, zone string) ([]*tpuapi.Node, } // ListLocations returns the zones where Cloud TPUs are available. -func (gce *GCECloud) ListLocations(ctx context.Context) ([]*tpuapi.Location, error) { +func (g *Cloud) ListLocations(ctx context.Context) ([]*tpuapi.Location, error) { mc := newTPUMetricContext("list_locations", "") - parent := getTPUProjectURL(gce.projectID) - response, err := gce.tpuService.projects.Locations.List(parent).Do() + parent := getTPUProjectURL(g.projectID) + response, err := g.tpuService.projects.Locations.List(parent).Do() if err != nil { return nil, mc.Observe(err) } @@ -144,7 +144,7 @@ func (gce *GCECloud) ListLocations(ctx context.Context) ([]*tpuapi.Location, err // waitForTPUOp checks whether the op is done every 30 seconds before the ctx // is cancelled. -func (gce *GCECloud) waitForTPUOp(ctx context.Context, op *tpuapi.Operation) (*tpuapi.Operation, error) { +func (g *Cloud) waitForTPUOp(ctx context.Context, op *tpuapi.Operation) (*tpuapi.Operation, error) { if err := wait.PollInfinite(30*time.Second, func() (bool, error) { // Check if context has been cancelled. select { @@ -157,14 +157,14 @@ func (gce *GCECloud) waitForTPUOp(ctx context.Context, op *tpuapi.Operation) (*t glog.V(3).Infof("Waiting for operation %q to complete...", op.Name) start := time.Now() - gce.operationPollRateLimiter.Accept() + g.operationPollRateLimiter.Accept() duration := time.Now().Sub(start) if duration > 5*time.Second { glog.V(2).Infof("Getting operation %q throttled for %v", op.Name, duration) } var err error - op, err = gce.tpuService.projects.Locations.Operations.Get(op.Name).Do() + op, err = g.tpuService.projects.Locations.Operations.Get(op.Name).Do() if err != nil { return true, err } diff --git a/pkg/cloudprovider/providers/gce/gce_urlmap.go b/pkg/cloudprovider/providers/gce/gce_urlmap.go index b0e60093c15b7..7ee8b8213271a 100644 --- a/pkg/cloudprovider/providers/gce/gce_urlmap.go +++ b/pkg/cloudprovider/providers/gce/gce_urlmap.go @@ -24,53 +24,53 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta" ) -func newUrlMapMetricContext(request string) *metricContext { +func newURLMapMetricContext(request string) *metricContext { return newGenericMetricContext("urlmap", request, unusedMetricLabel, unusedMetricLabel, computeV1Version) } -// GetUrlMap returns the UrlMap by name. -func (gce *GCECloud) GetUrlMap(name string) (*compute.UrlMap, error) { +// GetURLMap returns the UrlMap by name. +func (g *Cloud) GetURLMap(name string) (*compute.UrlMap, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() - mc := newUrlMapMetricContext("get") - v, err := gce.c.UrlMaps().Get(ctx, meta.GlobalKey(name)) + mc := newURLMapMetricContext("get") + v, err := g.c.UrlMaps().Get(ctx, meta.GlobalKey(name)) return v, mc.Observe(err) } -// CreateUrlMap creates a url map -func (gce *GCECloud) CreateUrlMap(urlMap *compute.UrlMap) error { +// CreateURLMap creates a url map +func (g *Cloud) CreateURLMap(urlMap *compute.UrlMap) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() - mc := newUrlMapMetricContext("create") - return mc.Observe(gce.c.UrlMaps().Insert(ctx, meta.GlobalKey(urlMap.Name), urlMap)) + mc := newURLMapMetricContext("create") + return mc.Observe(g.c.UrlMaps().Insert(ctx, meta.GlobalKey(urlMap.Name), urlMap)) } -// UpdateUrlMap applies the given UrlMap as an update -func (gce *GCECloud) UpdateUrlMap(urlMap *compute.UrlMap) error { +// UpdateURLMap applies the given UrlMap as an update +func (g *Cloud) UpdateURLMap(urlMap *compute.UrlMap) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() - mc := newUrlMapMetricContext("update") - return mc.Observe(gce.c.UrlMaps().Update(ctx, meta.GlobalKey(urlMap.Name), urlMap)) + mc := newURLMapMetricContext("update") + return mc.Observe(g.c.UrlMaps().Update(ctx, meta.GlobalKey(urlMap.Name), urlMap)) } -// DeleteUrlMap deletes a url map by name. -func (gce *GCECloud) DeleteUrlMap(name string) error { +// DeleteURLMap deletes a url map by name. +func (g *Cloud) DeleteURLMap(name string) error { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() - mc := newUrlMapMetricContext("delete") - return mc.Observe(gce.c.UrlMaps().Delete(ctx, meta.GlobalKey(name))) + mc := newURLMapMetricContext("delete") + return mc.Observe(g.c.UrlMaps().Delete(ctx, meta.GlobalKey(name))) } -// ListUrlMaps lists all UrlMaps in the project. -func (gce *GCECloud) ListUrlMaps() ([]*compute.UrlMap, error) { +// ListURLMaps lists all UrlMaps in the project. +func (g *Cloud) ListURLMaps() ([]*compute.UrlMap, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() - mc := newUrlMapMetricContext("list") - v, err := gce.c.UrlMaps().List(ctx, filter.None) + mc := newURLMapMetricContext("list") + v, err := g.c.UrlMaps().List(ctx, filter.None) return v, mc.Observe(err) } diff --git a/pkg/cloudprovider/providers/gce/gce_util.go b/pkg/cloudprovider/providers/gce/gce_util.go index ffc74bc2d240d..d66029a1df6c9 100644 --- a/pkg/cloudprovider/providers/gce/gce_util.go +++ b/pkg/cloudprovider/providers/gce/gce_util.go @@ -38,8 +38,8 @@ import ( "google.golang.org/api/googleapi" ) -func fakeGCECloud(vals TestClusterValues) (*GCECloud, error) { - gce := simpleFakeGCECloud(vals) +func fakeGCECloud(vals TestClusterValues) (*Cloud, error) { + gce := NewFakeGCECloud(vals) gce.AlphaFeatureGate = NewAlphaFeatureGate([]string{}) gce.nodeInformerSynced = func() bool { return true } @@ -88,7 +88,7 @@ var ( } ) -var providerIdRE = regexp.MustCompile(`^` + ProviderName + `://([^/]+)/([^/]+)/([^/]+)$`) +var providerIDRE = regexp.MustCompile(`^` + ProviderName + `://([^/]+)/([^/]+)/([^/]+)$`) func getProjectAndZone() (string, string, error) { result, err := metadata.Get("instance/zone") @@ -107,10 +107,10 @@ func getProjectAndZone() (string, string, error) { return projectID, zone, nil } -func (gce *GCECloud) raiseFirewallChangeNeededEvent(svc *v1.Service, cmd string) { +func (g *Cloud) raiseFirewallChangeNeededEvent(svc *v1.Service, cmd string) { msg := fmt.Sprintf("Firewall change required by network admin: `%v`", cmd) - if gce.eventRecorder != nil && svc != nil { - gce.eventRecorder.Event(svc, v1.EventTypeNormal, "LoadBalancerManualChange", msg) + if g.eventRecorder != nil && svc != nil { + g.eventRecorder.Event(svc, v1.EventTypeNormal, "LoadBalancerManualChange", msg) } } @@ -120,13 +120,13 @@ func FirewallToGCloudCreateCmd(fw *compute.Firewall, projectID string) string { return fmt.Sprintf("gcloud compute firewall-rules create %v --network %v %v", fw.Name, getNameFromLink(fw.Network), args) } -// FirewallToGCloudCreateCmd generates a gcloud command to update a firewall to specified params +// FirewallToGCloudUpdateCmd generates a gcloud command to update a firewall to specified params func FirewallToGCloudUpdateCmd(fw *compute.Firewall, projectID string) string { args := firewallToGcloudArgs(fw, projectID) return fmt.Sprintf("gcloud compute firewall-rules update %v %v", fw.Name, args) } -// FirewallToGCloudCreateCmd generates a gcloud command to delete a firewall to specified params +// FirewallToGCloudDeleteCmd generates a gcloud command to delete a firewall to specified params func FirewallToGCloudDeleteCmd(fwName, projectID string) string { return fmt.Sprintf("gcloud compute firewall-rules delete %v --project %v", fwName, projectID) } @@ -205,7 +205,7 @@ func isInUsedByError(err error) bool { // A providerID is build out of '${ProviderName}://${project-id}/${zone}/${instance-name}' // See cloudprovider.GetInstanceProviderID. func splitProviderID(providerID string) (project, zone, instance string, err error) { - matches := providerIdRE.FindStringSubmatch(providerID) + matches := providerIDRE.FindStringSubmatch(providerID) if len(matches) != 4 { return "", "", "", errors.New("error splitting providerID") } diff --git a/pkg/cloudprovider/providers/gce/gce_zones.go b/pkg/cloudprovider/providers/gce/gce_zones.go index 09f12b82a81f7..3e4bb059bd648 100644 --- a/pkg/cloudprovider/providers/gce/gce_zones.go +++ b/pkg/cloudprovider/providers/gce/gce_zones.go @@ -33,17 +33,17 @@ func newZonesMetricContext(request, region string) *metricContext { } // GetZone creates a cloudprovider.Zone of the current zone and region -func (gce *GCECloud) GetZone(ctx context.Context) (cloudprovider.Zone, error) { +func (g *Cloud) GetZone(ctx context.Context) (cloudprovider.Zone, error) { return cloudprovider.Zone{ - FailureDomain: gce.localZone, - Region: gce.region, + FailureDomain: g.localZone, + Region: g.region, }, nil } // GetZoneByProviderID implements Zones.GetZoneByProviderID // This is particularly useful in external cloud providers where the kubelet // does not initialize node data. -func (gce *GCECloud) GetZoneByProviderID(ctx context.Context, providerID string) (cloudprovider.Zone, error) { +func (g *Cloud) GetZoneByProviderID(ctx context.Context, providerID string) (cloudprovider.Zone, error) { _, zone, _, err := splitProviderID(providerID) if err != nil { return cloudprovider.Zone{}, err @@ -58,9 +58,9 @@ func (gce *GCECloud) GetZoneByProviderID(ctx context.Context, providerID string) // GetZoneByNodeName implements Zones.GetZoneByNodeName // This is particularly useful in external cloud providers where the kubelet // does not initialize node data. -func (gce *GCECloud) GetZoneByNodeName(ctx context.Context, nodeName types.NodeName) (cloudprovider.Zone, error) { +func (g *Cloud) GetZoneByNodeName(ctx context.Context, nodeName types.NodeName) (cloudprovider.Zone, error) { instanceName := mapNodeNameToInstanceName(nodeName) - instance, err := gce.getInstanceByName(instanceName) + instance, err := g.getInstanceByName(instanceName) if err != nil { return cloudprovider.Zone{}, err } @@ -72,18 +72,18 @@ func (gce *GCECloud) GetZoneByNodeName(ctx context.Context, nodeName types.NodeN } // ListZonesInRegion returns all zones in a GCP region -func (gce *GCECloud) ListZonesInRegion(region string) ([]*compute.Zone, error) { +func (g *Cloud) ListZonesInRegion(region string) ([]*compute.Zone, error) { ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() mc := newZonesMetricContext("list", region) - list, err := gce.c.Zones().List(ctx, filter.Regexp("region", gce.getRegionLink(region))) + list, err := g.c.Zones().List(ctx, filter.Regexp("region", g.getRegionLink(region))) if err != nil { return nil, mc.Observe(err) } return list, mc.Observe(err) } -func (gce *GCECloud) getRegionLink(region string) string { - return gce.service.BasePath + strings.Join([]string{gce.projectID, "regions", region}, "/") +func (g *Cloud) getRegionLink(region string) string { + return g.service.BasePath + strings.Join([]string{g.projectID, "regions", region}, "/") } diff --git a/pkg/cloudprovider/providers/gce/support.go b/pkg/cloudprovider/providers/gce/support.go index 7861e08acbc76..e6c471855fe64 100644 --- a/pkg/cloudprovider/providers/gce/support.go +++ b/pkg/cloudprovider/providers/gce/support.go @@ -25,7 +25,7 @@ import ( // gceProjectRouter sends requests to the appropriate project ID. type gceProjectRouter struct { - gce *GCECloud + gce *Cloud } // ProjectID returns the project ID to be used for the given operation. @@ -40,7 +40,7 @@ func (r *gceProjectRouter) ProjectID(ctx context.Context, version meta.Version, // gceRateLimiter implements cloud.RateLimiter. type gceRateLimiter struct { - gce *GCECloud + gce *Cloud } // Accept blocks until the operation can be performed. @@ -63,10 +63,10 @@ func (l *gceRateLimiter) Accept(ctx context.Context, key *cloud.RateLimitKey) er return nil } -// CreateGCECloudWithCloud is a helper function to create an instance of GCECloud with the +// CreateGCECloudWithCloud is a helper function to create an instance of Cloud with the // given Cloud interface implementation. Typical usage is to use cloud.NewMockGCE to get a // handle to a mock Cloud instance and then use that for testing. -func CreateGCECloudWithCloud(config *CloudConfig, c cloud.Cloud) (*GCECloud, error) { +func CreateGCECloudWithCloud(config *CloudConfig, c cloud.Cloud) (*Cloud, error) { gceCloud, err := CreateGCECloud(config) if err == nil { gceCloud.c = c diff --git a/pkg/cloudprovider/providers/gce/token_source.go b/pkg/cloudprovider/providers/gce/token_source.go index 2f4bb09119ab1..e8434bd2a0c77 100644 --- a/pkg/cloudprovider/providers/gce/token_source.go +++ b/pkg/cloudprovider/providers/gce/token_source.go @@ -57,6 +57,7 @@ func init() { prometheus.MustRegister(getTokenFailCounter) } +// AltTokenSource is the structure holding the data for the functionality needed to generates tokens type AltTokenSource struct { oauthClient *http.Client tokenURL string @@ -64,6 +65,7 @@ type AltTokenSource struct { throttle flowcontrol.RateLimiter } +// Token returns a token which may be used for authentication func (a *AltTokenSource) Token() (*oauth2.Token, error) { a.throttle.Accept() getTokenCounter.Inc() @@ -100,6 +102,7 @@ func (a *AltTokenSource) token() (*oauth2.Token, error) { }, nil } +// NewAltTokenSource constructs a new alternate token source for generating tokens. func NewAltTokenSource(tokenURL, tokenBody string) oauth2.TokenSource { client := oauth2.NewClient(oauth2.NoContext, google.ComputeTokenSource("")) a := &AltTokenSource{ diff --git a/pkg/cloudprovider/providers/openstack/openstack_volumes.go b/pkg/cloudprovider/providers/openstack/openstack_volumes.go index c3a8146530171..d3e5cf1d3b6b7 100644 --- a/pkg/cloudprovider/providers/openstack/openstack_volumes.go +++ b/pkg/cloudprovider/providers/openstack/openstack_volumes.go @@ -697,6 +697,11 @@ func (os *OpenStack) ShouldTrustDevicePath() bool { // GetLabelsForVolume implements PVLabeler.GetLabelsForVolume func (os *OpenStack) GetLabelsForVolume(ctx context.Context, pv *v1.PersistentVolume) (map[string]string, error) { + // Ignore if not Cinder. + if pv.Spec.Cinder == nil { + return nil, nil + } + // Ignore any volumes that are being provisioned if pv.Spec.Cinder.VolumeID == k8s_volume.ProvisionedVolumeName { return nil, nil diff --git a/pkg/controller/.import-restrictions b/pkg/controller/.import-restrictions index c45988ec9b88d..6dd2ce4cc4c6f 100644 --- a/pkg/controller/.import-restrictions +++ b/pkg/controller/.import-restrictions @@ -11,8 +11,357 @@ "ForbiddenPrefixes": [ "k8s.io/kubernetes/pkg/client/unversioned/testclient" ] + }, + { + "SelectorRegexp": "k8s[.]io/(api/|apimachinery/|apiextensions-apiserver/|apiserver/)", + "AllowedPrefixes": [ + "k8s.io/api/apps/v1", + "k8s.io/api/apps/v1beta1", + "k8s.io/api/authentication/v1", + "k8s.io/api/authorization/v1beta1", + "k8s.io/api/autoscaling/v1", + "k8s.io/api/autoscaling/v2beta1", + "k8s.io/api/autoscaling/v2beta2", + "k8s.io/api/batch/v1", + "k8s.io/api/batch/v1beta1", + "k8s.io/api/certificates/v1beta1", + "k8s.io/api/core/v1", + "k8s.io/api/coordination/v1beta1", + "k8s.io/api/extensions/v1beta1", + "k8s.io/api/policy/v1beta1", + "k8s.io/api/rbac/v1", + "k8s.io/api/storage/v1", + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1", + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset", + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake", + "k8s.io/apimachinery/pkg/api/equality", + "k8s.io/apimachinery/pkg/api/errors", + "k8s.io/apimachinery/pkg/api/meta", + "k8s.io/apimachinery/pkg/api/meta/testrestmapper", + "k8s.io/apimachinery/pkg/api/resource", + "k8s.io/apimachinery/pkg/apis/config", + "k8s.io/apimachinery/pkg/apis/config/v1alpha1", + "k8s.io/apimachinery/pkg/apis/meta/v1", + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", + "k8s.io/apimachinery/pkg/conversion", + "k8s.io/apimachinery/pkg/fields", + "k8s.io/apimachinery/pkg/labels", + "k8s.io/apimachinery/pkg/runtime", + "k8s.io/apimachinery/pkg/runtime/schema", + "k8s.io/apimachinery/pkg/runtime/serializer", + "k8s.io/apimachinery/pkg/types", + "k8s.io/apimachinery/pkg/util/clock", + "k8s.io/apimachinery/pkg/util/diff", + "k8s.io/apimachinery/pkg/util/errors", + "k8s.io/apimachinery/pkg/util/intstr", + "k8s.io/apimachinery/pkg/util/json", + "k8s.io/apimachinery/pkg/util/rand", + "k8s.io/apimachinery/pkg/util/runtime", + "k8s.io/apimachinery/pkg/util/sets", + "k8s.io/apimachinery/pkg/util/strategicpatch", + "k8s.io/apimachinery/pkg/util/uuid", + "k8s.io/apimachinery/pkg/util/wait", + "k8s.io/apimachinery/pkg/util/version", + "k8s.io/apimachinery/pkg/watch", + "k8s.io/apiserver/pkg/apis/config", + "k8s.io/apiserver/pkg/apis/config/v1alpha1", + "k8s.io/apiserver/pkg/authentication/serviceaccount", + "k8s.io/apiserver/pkg/storage/names", + "k8s.io/apiserver/pkg/util/feature", + "k8s.io/apiextensions-apiserver/pkg/features", + "k8s.io/apimachinery/pkg/api/validation", + "k8s.io/apimachinery/pkg/apis/meta/internalversion", + "k8s.io/apimachinery/pkg/selection", + "k8s.io/apimachinery/pkg/util/validation", + "k8s.io/apimachinery/pkg/util/validation/field", + "k8s.io/apiserver/pkg/authentication/authenticator", + "k8s.io/apiserver/pkg/authentication/user", + "k8s.io/apiserver/pkg/features", + "k8s.io/apiserver/pkg/registry/generic", + "k8s.io/apimachinery/pkg/version", + "k8s.io/api/imagepolicy/v1alpha1", + "k8s.io/apiserver/pkg/admission", + "k8s.io/apiserver/pkg/storage", + "k8s.io/api/batch/v2alpha1", + "k8s.io/apiserver/pkg/registry/rest", + "k8s.io/apimachinery/pkg/util/initialization", + "k8s.io/api/scheduling/v1alpha1", + "k8s.io/api/admissionregistration/v1beta1", + "k8s.io/api/authorization/v1", + "k8s.io/api/settings/v1alpha1", + "k8s.io/api/admission/v1beta1", + "k8s.io/api/networking/v1", + "k8s.io/api/admissionregistration/v1alpha1" + ] + }, + { + "SelectorRegexp": "github[.]com/", + "AllowedPrefixes": [ + "github.com/Azure/go-autorest/autorest/to", + "github.com/cloudflare/cfssl/config", + "github.com/cloudflare/cfssl/helpers", + "github.com/cloudflare/cfssl/signer", + "github.com/cloudflare/cfssl/signer/local", + "github.com/davecgh/go-spew/spew", + "github.com/evanphx/json-patch", + "github.com/golang/glog", + "github.com/golang/groupcache/lru", + "github.com/prometheus/client_golang/prometheus", + "github.com/robfig/cron", + "github.com/spf13/pflag", + "github.com/stretchr/testify/assert", + "github.com/stretchr/testify/require", + "github.com/docker/distribution/reference", + "github.com/google/gofuzz" + ] + }, + { + "SelectorRegexp": "k8s[.]io/client-go/", + "AllowedPrefixes": [ + "k8s.io/client-go/discovery", + "k8s.io/client-go/dynamic", + "k8s.io/client-go/informers", + "k8s.io/client-go/informers/apps/v1", + "k8s.io/client-go/informers/apps/v1beta1", + "k8s.io/client-go/informers/autoscaling/v1", + "k8s.io/client-go/informers/batch/v1", + "k8s.io/client-go/informers/certificates/v1beta1", + "k8s.io/client-go/informers/core/v1", + "k8s.io/client-go/informers/extensions/v1beta1", + "k8s.io/client-go/informers/policy/v1beta1", + "k8s.io/client-go/informers/rbac/v1", + "k8s.io/client-go/informers/storage/v1", + "k8s.io/client-go/kubernetes", + "k8s.io/client-go/kubernetes/fake", + "k8s.io/client-go/kubernetes/scheme", + "k8s.io/client-go/kubernetes/typed/apps/v1", + "k8s.io/client-go/kubernetes/typed/authentication/v1", + "k8s.io/client-go/kubernetes/typed/autoscaling/v1", + "k8s.io/client-go/kubernetes/typed/certificates/v1beta1", + "k8s.io/client-go/kubernetes/typed/core/v1", + "k8s.io/client-go/kubernetes/typed/policy/v1beta1", + "k8s.io/client-go/kubernetes/typed/rbac/v1", + "k8s.io/client-go/listers/apps/v1", + "k8s.io/client-go/listers/apps/v1beta1", + "k8s.io/client-go/listers/autoscaling/v1", + "k8s.io/client-go/listers/batch/v1", + "k8s.io/client-go/listers/certificates/v1beta1", + "k8s.io/client-go/listers/core/v1", + "k8s.io/client-go/listers/coordination/v1beta1", + "k8s.io/client-go/listers/extensions/v1beta1", + "k8s.io/client-go/listers/policy/v1beta1", + "k8s.io/client-go/listers/rbac/v1", + "k8s.io/client-go/listers/storage/v1", + "k8s.io/client-go/rest", + "k8s.io/client-go/scale", + "k8s.io/client-go/scale/fake", + "k8s.io/client-go/testing", + "k8s.io/client-go/tools/bootstrap/token/api", + "k8s.io/client-go/tools/cache", + "k8s.io/client-go/tools/leaderelection/resourcelock", + "k8s.io/client-go/tools/record", + "k8s.io/client-go/tools/reference", + "k8s.io/client-go/tools/watch", + "k8s.io/client-go/util/cert", + "k8s.io/client-go/util/flowcontrol", + "k8s.io/client-go/util/integer", + "k8s.io/client-go/util/retry", + "k8s.io/client-go/util/testing", + "k8s.io/client-go/util/workqueue" + ] + }, + { + "SelectorRegexp": "k8s[.]io/kubernetes/pkg", + "AllowedPrefixes": [ + "k8s.io/kubernetes/pkg/api/legacyscheme", + "k8s.io/kubernetes/pkg/api/testapi", + "k8s.io/kubernetes/pkg/api/v1/endpoints", + "k8s.io/kubernetes/pkg/api/v1/node", + "k8s.io/kubernetes/pkg/api/v1/pod", + "k8s.io/kubernetes/pkg/apis/apps/install", + "k8s.io/kubernetes/pkg/apis/apps/v1", + "k8s.io/kubernetes/pkg/apis/authentication/install", + "k8s.io/kubernetes/pkg/apis/authorization/install", + "k8s.io/kubernetes/pkg/apis/autoscaling", + "k8s.io/kubernetes/pkg/apis/autoscaling/install", + "k8s.io/kubernetes/pkg/apis/batch/install", + "k8s.io/kubernetes/pkg/apis/certificates/install", + "k8s.io/kubernetes/pkg/apis/certificates/v1beta1", + "k8s.io/kubernetes/pkg/apis/core", + "k8s.io/kubernetes/pkg/apis/core/helper", + "k8s.io/kubernetes/pkg/apis/core/install", + "k8s.io/kubernetes/pkg/apis/core/v1", + "k8s.io/kubernetes/pkg/apis/core/v1/helper", + "k8s.io/kubernetes/pkg/apis/core/validation", + "k8s.io/kubernetes/pkg/apis/extensions", + "k8s.io/kubernetes/pkg/apis/extensions/install", + "k8s.io/kubernetes/pkg/apis/policy/install", + "k8s.io/kubernetes/pkg/apis/rbac/install", + "k8s.io/kubernetes/pkg/apis/settings/install", + "k8s.io/kubernetes/pkg/apis/storage/install", + "k8s.io/kubernetes/pkg/client/unversioned", + "k8s.io/kubernetes/pkg/client/unversioned/testclient", + "k8s.io/kubernetes/pkg/cloudprovider", + "k8s.io/kubernetes/pkg/cloudprovider/providers/fake", + "k8s.io/kubernetes/pkg/cloudprovider/providers/gce", + "k8s.io/kubernetes/pkg/controller", + "k8s.io/kubernetes/pkg/controller/apis/config", + "k8s.io/kubernetes/pkg/controller/apis/config/scheme", + "k8s.io/kubernetes/pkg/controller/apis/config/v1alpha1", + "k8s.io/kubernetes/pkg/controller/bootstrap", + "k8s.io/kubernetes/pkg/controller/certificates", + "k8s.io/kubernetes/pkg/controller/certificates/approver", + "k8s.io/kubernetes/pkg/controller/certificates/cleaner", + "k8s.io/kubernetes/pkg/controller/certificates/signer", + "k8s.io/kubernetes/pkg/controller/cloud", + "k8s.io/kubernetes/pkg/controller/clusterroleaggregation", + "k8s.io/kubernetes/pkg/controller/cronjob", + "k8s.io/kubernetes/pkg/controller/daemon", + "k8s.io/kubernetes/pkg/controller/daemon/util", + "k8s.io/kubernetes/pkg/controller/deployment", + "k8s.io/kubernetes/pkg/controller/deployment/util", + "k8s.io/kubernetes/pkg/controller/disruption", + "k8s.io/kubernetes/pkg/controller/endpoint", + "k8s.io/kubernetes/pkg/controller/garbagecollector", + "k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly", + "k8s.io/kubernetes/pkg/controller/history", + "k8s.io/kubernetes/pkg/controller/job", + "k8s.io/kubernetes/pkg/controller/namespace", + "k8s.io/kubernetes/pkg/controller/namespace/deletion", + "k8s.io/kubernetes/pkg/controller/nodeipam", + "k8s.io/kubernetes/pkg/controller/nodeipam/ipam", + "k8s.io/kubernetes/pkg/controller/nodeipam/ipam/cidrset", + "k8s.io/kubernetes/pkg/controller/nodeipam/ipam/sync", + "k8s.io/kubernetes/pkg/controller/nodeipam/ipam/test", + "k8s.io/kubernetes/pkg/controller/nodelifecycle", + "k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler", + "k8s.io/kubernetes/pkg/controller/podautoscaler", + "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics", + "k8s.io/kubernetes/pkg/controller/podgc", + "k8s.io/kubernetes/pkg/controller/replicaset", + "k8s.io/kubernetes/pkg/controller/replicaset/options", + "k8s.io/kubernetes/pkg/controller/replication", + "k8s.io/kubernetes/pkg/controller/resourcequota", + "k8s.io/kubernetes/pkg/controller/route", + "k8s.io/kubernetes/pkg/controller/service", + "k8s.io/kubernetes/pkg/controller/serviceaccount", + "k8s.io/kubernetes/pkg/controller/statefulset", + "k8s.io/kubernetes/pkg/controller/testutil", + "k8s.io/kubernetes/pkg/controller/ttl", + "k8s.io/kubernetes/pkg/controller/ttlafterfinished", + "k8s.io/kubernetes/pkg/controller/util/node", + "k8s.io/kubernetes/pkg/controller/volume/attachdetach", + "k8s.io/kubernetes/pkg/controller/volume/attachdetach/cache", + "k8s.io/kubernetes/pkg/controller/volume/attachdetach/metrics", + "k8s.io/kubernetes/pkg/controller/volume/attachdetach/populator", + "k8s.io/kubernetes/pkg/controller/volume/attachdetach/reconciler", + "k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater", + "k8s.io/kubernetes/pkg/controller/volume/attachdetach/testing", + "k8s.io/kubernetes/pkg/controller/volume/attachdetach/util", + "k8s.io/kubernetes/pkg/controller/volume/events", + "k8s.io/kubernetes/pkg/controller/volume/expand", + "k8s.io/kubernetes/pkg/controller/volume/expand/cache", + "k8s.io/kubernetes/pkg/controller/volume/persistentvolume", + "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/metrics", + "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/options", + "k8s.io/kubernetes/pkg/controller/volume/pvcprotection", + "k8s.io/kubernetes/pkg/controller/volume/pvprotection", + "k8s.io/kubernetes/pkg/features", + "k8s.io/kubernetes/pkg/kubectl/scheme", + "k8s.io/kubernetes/pkg/kubelet/apis", + "k8s.io/kubernetes/pkg/kubelet/events", + "k8s.io/kubernetes/pkg/kubelet/types", + "k8s.io/kubernetes/pkg/kubelet/util/format", + "k8s.io/kubernetes/pkg/quota", + "k8s.io/kubernetes/pkg/quota/evaluator/core", + "k8s.io/kubernetes/pkg/quota/generic", + "k8s.io/kubernetes/pkg/quota/install", + "k8s.io/kubernetes/pkg/registry/core/secret", + "k8s.io/kubernetes/pkg/scheduler/algorithm", + "k8s.io/kubernetes/pkg/scheduler/algorithm/predicates", + "k8s.io/kubernetes/pkg/scheduler/cache", + "k8s.io/kubernetes/pkg/securitycontext", + "k8s.io/kubernetes/pkg/serviceaccount", + "k8s.io/kubernetes/pkg/util/goroutinemap", + "k8s.io/kubernetes/pkg/util/goroutinemap/exponentialbackoff", + "k8s.io/kubernetes/pkg/util/hash", + "k8s.io/kubernetes/pkg/util/labels", + "k8s.io/kubernetes/pkg/util/metrics", + "k8s.io/kubernetes/pkg/util/mount", + "k8s.io/kubernetes/pkg/util/node", + "k8s.io/kubernetes/pkg/util/reflector/prometheus", + "k8s.io/kubernetes/pkg/util/slice", + "k8s.io/kubernetes/pkg/util/strings", + "k8s.io/kubernetes/pkg/util/system", + "k8s.io/kubernetes/pkg/util/taints", + "k8s.io/kubernetes/pkg/util/workqueue/prometheus", + "k8s.io/kubernetes/pkg/volume", + "k8s.io/kubernetes/pkg/volume/testing", + "k8s.io/kubernetes/pkg/volume/util", + "k8s.io/kubernetes/pkg/volume/util/operationexecutor", + "k8s.io/kubernetes/pkg/volume/util/recyclerclient", + "k8s.io/kubernetes/pkg/volume/util/types", + "k8s.io/kubernetes/pkg/volume/util/volumepathhandler", + "k8s.io/kubernetes/pkg/api/service", + "k8s.io/kubernetes/pkg/api/v1/service", + "k8s.io/kubernetes/pkg/apis/networking", + "k8s.io/kubernetes/pkg/apis/policy", + "k8s.io/kubernetes/pkg/apis/scheduling", + "k8s.io/kubernetes/pkg/capabilities", + "k8s.io/kubernetes/pkg/master/ports", + "k8s.io/kubernetes/pkg/scheduler/api", + "k8s.io/kubernetes/pkg/scheduler/util", + "k8s.io/kubernetes/pkg/security/apparmor", + "k8s.io/kubernetes/pkg/util/file", + "k8s.io/kubernetes/pkg/util/net/sets", + "k8s.io/kubernetes/pkg/util/parsers", + "k8s.io/kubernetes/pkg/fieldpath", + "k8s.io/kubernetes/pkg/kubeapiserver/admission/util", + "k8s.io/kubernetes/pkg/scheduler/volumebinder", + "k8s.io/kubernetes/pkg/scheduler/internal/cache", + "k8s.io/kubernetes/pkg/util/nsenter", + "k8s.io/kubernetes/pkg/util/resizefs", + "k8s.io/kubernetes/pkg/util/version", + "k8s.io/kubernetes/pkg/apis/apps", + "k8s.io/kubernetes/pkg/version", + "k8s.io/kubernetes/pkg/util/io" + ] + }, + { + "SelectorRegexp": "k8s[.]io/(metrics/|utils/|csi-api/|heapster/|kube-controller-manager/)", + "AllowedPrefixes": [ + "k8s.io/csi-api/pkg/apis/csi/v1alpha1", + "k8s.io/csi-api/pkg/client/clientset/versioned", + "k8s.io/heapster/metrics/api/v1/types", + "k8s.io/kube-controller-manager/config/v1alpha1", + "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2", + "k8s.io/metrics/pkg/apis/external_metrics/v1beta1", + "k8s.io/metrics/pkg/apis/metrics/v1alpha1", + "k8s.io/metrics/pkg/apis/metrics/v1beta1", + "k8s.io/metrics/pkg/client/clientset/versioned/fake", + "k8s.io/metrics/pkg/client/clientset/versioned/scheme", + "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1", + "k8s.io/metrics/pkg/client/custom_metrics", + "k8s.io/metrics/pkg/client/custom_metrics/fake", + "k8s.io/metrics/pkg/client/external_metrics", + "k8s.io/metrics/pkg/client/external_metrics/fake", + "k8s.io/utils/pointer", + "k8s.io/utils/exec" + ] + }, + { + "SelectorRegexp": "golang[.]org/", + "AllowedPrefixes": [ + "golang.org/x/time/rate", + "golang.org/x/sys/unix", + "golang.org/x/oauth2", + "google.golang.org/api/compute/v1", + "google.golang.org/api/googleapi", + "google.golang.org/api/compute/v0.alpha", + "google.golang.org/api/container/v1", + "google.golang.org/api/compute/v0.beta", + "google.golang.org/api/tpu/v1" + ] } - ] } - diff --git a/pkg/controller/apis/config/BUILD b/pkg/controller/apis/config/BUILD index 928640e3bca9b..57c9f74fb15f8 100644 --- a/pkg/controller/apis/config/BUILD +++ b/pkg/controller/apis/config/BUILD @@ -30,6 +30,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/controller/apis/config/fuzzer:all-srcs", "//pkg/controller/apis/config/scheme:all-srcs", "//pkg/controller/apis/config/v1alpha1:all-srcs", ], diff --git a/pkg/controller/apis/config/fuzzer/BUILD b/pkg/controller/apis/config/fuzzer/BUILD new file mode 100644 index 0000000000000..2219a63bca3d3 --- /dev/null +++ b/pkg/controller/apis/config/fuzzer/BUILD @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + importpath = "k8s.io/kubernetes/pkg/controller/apis/config/fuzzer", + visibility = ["//visibility:public"], + deps = [ + "//pkg/controller/apis/config:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + "//vendor/github.com/google/gofuzz: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/pkg/controller/apis/config/fuzzer/fuzzer.go b/pkg/controller/apis/config/fuzzer/fuzzer.go new file mode 100644 index 0000000000000..2aaecf6f3f50d --- /dev/null +++ b/pkg/controller/apis/config/fuzzer/fuzzer.go @@ -0,0 +1,48 @@ +/* +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 fuzzer + +import ( + "fmt" + + "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + kubectrlmgrconfig "k8s.io/kubernetes/pkg/controller/apis/config" +) + +// Funcs returns the fuzzer functions for the kube-controller manager apis. +func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(obj *kubectrlmgrconfig.KubeControllerManagerConfiguration, c fuzz.Continue) { + c.FuzzNoCustom(obj) + obj.Generic.Address = fmt.Sprintf("%d.%d.%d.%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256)) + obj.Generic.ClientConnection.ContentType = fmt.Sprintf("%s/%s.%s.%s", c.RandString(), c.RandString(), c.RandString(), c.RandString()) + if obj.Generic.LeaderElection.ResourceLock == "" { + obj.Generic.LeaderElection.ResourceLock = "endpoints" + } + obj.Generic.Controllers = []string{fmt.Sprintf("%s", c.RandString())} + if obj.KubeCloudShared.ClusterName == "" { + obj.KubeCloudShared.ClusterName = "kubernetes" + } + obj.CSRSigningController.ClusterSigningCertFile = fmt.Sprintf("/%s", c.RandString()) + obj.CSRSigningController.ClusterSigningKeyFile = fmt.Sprintf("/%s", c.RandString()) + obj.PersistentVolumeBinderController.VolumeConfiguration.FlexVolumePluginDir = fmt.Sprintf("/%s", c.RandString()) + obj.TTLAfterFinishedController.ConcurrentTTLSyncs = c.Int31() + }, + } +} diff --git a/pkg/controller/apis/config/scheme/BUILD b/pkg/controller/apis/config/scheme/BUILD index a5600c311a51d..e39163350ab3f 100644 --- a/pkg/controller/apis/config/scheme/BUILD +++ b/pkg/controller/apis/config/scheme/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -27,3 +27,13 @@ filegroup( tags = ["automanaged"], visibility = ["//visibility:public"], ) + +go_test( + name = "go_default_test", + srcs = ["scheme_test.go"], + embed = [":go_default_library"], + deps = [ + "//pkg/controller/apis/config/fuzzer:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/apitesting/roundtrip:go_default_library", + ], +) diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_scale.go b/pkg/controller/apis/config/scheme/scheme_test.go similarity index 65% rename from staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_scale.go rename to pkg/controller/apis/config/scheme/scheme_test.go index de71947e5230a..4e951c2ce6892 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_scale.go +++ b/pkg/controller/apis/config/scheme/scheme_test.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +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. @@ -14,12 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. +package scheme -package fake +import ( + "testing" -// FakeScales implements ScaleInterface -type FakeScales struct { - Fake *FakeAppsV1beta1 - ns string + "k8s.io/apimachinery/pkg/api/apitesting/roundtrip" + "k8s.io/kubernetes/pkg/controller/apis/config/fuzzer" +) + +func TestRoundTripTypes(t *testing.T) { + roundtrip.RoundTripTestForScheme(t, Scheme, fuzzer.Funcs) } diff --git a/pkg/controller/certificates/OWNERS b/pkg/controller/certificates/OWNERS index e77a57187c950..470b7a1c92d15 100755 --- a/pkg/controller/certificates/OWNERS +++ b/pkg/controller/certificates/OWNERS @@ -1,4 +1,7 @@ +approvers: +- sig-auth-certificates-approvers reviewers: -- deads2k -- mikedanese -- awly +- sig-auth-certificates-reviewers +labels: +- sig/auth + diff --git a/pkg/controller/daemon/daemon_controller.go b/pkg/controller/daemon/daemon_controller.go index 4faac5d2fe1d0..7f5015e105306 100644 --- a/pkg/controller/daemon/daemon_controller.go +++ b/pkg/controller/daemon/daemon_controller.go @@ -1103,7 +1103,7 @@ func (dsc *DaemonSetsController) syncNodes(ds *apps.DaemonSet, podsToDelete, nod return utilerrors.NewAggregate(errors) } -func storeDaemonSetStatus(dsClient unversionedapps.DaemonSetInterface, ds *apps.DaemonSet, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled, numberReady, updatedNumberScheduled, numberAvailable, numberUnavailable int) error { +func storeDaemonSetStatus(dsClient unversionedapps.DaemonSetInterface, ds *apps.DaemonSet, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled, numberReady, updatedNumberScheduled, numberAvailable, numberUnavailable int, updateObservedGen bool) error { if int(ds.Status.DesiredNumberScheduled) == desiredNumberScheduled && int(ds.Status.CurrentNumberScheduled) == currentNumberScheduled && int(ds.Status.NumberMisscheduled) == numberMisscheduled && @@ -1119,7 +1119,9 @@ func storeDaemonSetStatus(dsClient unversionedapps.DaemonSetInterface, ds *apps. var updateErr, getErr error for i := 0; i < StatusUpdateRetries; i++ { - toUpdate.Status.ObservedGeneration = ds.Generation + if updateObservedGen { + toUpdate.Status.ObservedGeneration = ds.Generation + } toUpdate.Status.DesiredNumberScheduled = int32(desiredNumberScheduled) toUpdate.Status.CurrentNumberScheduled = int32(currentNumberScheduled) toUpdate.Status.NumberMisscheduled = int32(numberMisscheduled) @@ -1142,7 +1144,7 @@ func storeDaemonSetStatus(dsClient unversionedapps.DaemonSetInterface, ds *apps. return updateErr } -func (dsc *DaemonSetsController) updateDaemonSetStatus(ds *apps.DaemonSet, hash string) error { +func (dsc *DaemonSetsController) updateDaemonSetStatus(ds *apps.DaemonSet, hash string, updateObservedGen bool) error { glog.V(4).Infof("Updating daemon set status") nodeToDaemonPods, err := dsc.getNodesToDaemonPods(ds) if err != nil { @@ -1195,7 +1197,7 @@ func (dsc *DaemonSetsController) updateDaemonSetStatus(ds *apps.DaemonSet, hash } numberUnavailable := desiredNumberScheduled - numberAvailable - err = storeDaemonSetStatus(dsc.kubeClient.AppsV1().DaemonSets(ds.Namespace), ds, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled, numberReady, updatedNumberScheduled, numberAvailable, numberUnavailable) + err = storeDaemonSetStatus(dsc.kubeClient.AppsV1().DaemonSets(ds.Namespace), ds, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled, numberReady, updatedNumberScheduled, numberAvailable, numberUnavailable, updateObservedGen) if err != nil { return fmt.Errorf("error storing status for daemon set %#v: %v", ds, err) } @@ -1257,8 +1259,8 @@ func (dsc *DaemonSetsController) syncDaemonSet(key string) error { hash := cur.Labels[apps.DefaultDaemonSetUniqueLabelKey] if !dsc.expectations.SatisfiedExpectations(dsKey) { - // Only update status. - return dsc.updateDaemonSetStatus(ds, hash) + // Only update status. Don't raise observedGeneration since controller didn't process object of that generation. + return dsc.updateDaemonSetStatus(ds, hash, false) } err = dsc.manage(ds, hash) @@ -1283,7 +1285,7 @@ func (dsc *DaemonSetsController) syncDaemonSet(key string) error { return fmt.Errorf("failed to clean up revisions of DaemonSet: %v", err) } - return dsc.updateDaemonSetStatus(ds, hash) + return dsc.updateDaemonSetStatus(ds, hash, true) } func (dsc *DaemonSetsController) simulate(newPod *v1.Pod, node *v1.Node, ds *apps.DaemonSet) ([]algorithm.PredicateFailureReason, *schedulercache.NodeInfo, error) { diff --git a/pkg/controller/disruption/disruption.go b/pkg/controller/disruption/disruption.go index b6ae484a8cf85..12592d2b6274d 100644 --- a/pkg/controller/disruption/disruption.go +++ b/pkg/controller/disruption/disruption.go @@ -379,7 +379,7 @@ func (dc *DisruptionController) deletePod(obj interface{}) { func (dc *DisruptionController) enqueuePdb(pdb *policy.PodDisruptionBudget) { key, err := controller.KeyFunc(pdb) if err != nil { - glog.Errorf("Cound't get key for PodDisruptionBudget object %+v: %v", pdb, err) + glog.Errorf("Couldn't get key for PodDisruptionBudget object %+v: %v", pdb, err) return } dc.queue.Add(key) @@ -388,7 +388,7 @@ func (dc *DisruptionController) enqueuePdb(pdb *policy.PodDisruptionBudget) { func (dc *DisruptionController) enqueuePdbForRecheck(pdb *policy.PodDisruptionBudget, delay time.Duration) { key, err := controller.KeyFunc(pdb) if err != nil { - glog.Errorf("Cound't get key for PodDisruptionBudget object %+v: %v", pdb, err) + glog.Errorf("Couldn't get key for PodDisruptionBudget object %+v: %v", pdb, err) return } dc.recheckQueue.AddAfter(key, delay) diff --git a/pkg/controller/nodeipam/ipam/adapter.go b/pkg/controller/nodeipam/ipam/adapter.go index a834edac30e80..c72e2e5a22c35 100644 --- a/pkg/controller/nodeipam/ipam/adapter.go +++ b/pkg/controller/nodeipam/ipam/adapter.go @@ -36,12 +36,12 @@ import ( type adapter struct { k8s clientset.Interface - cloud *gce.GCECloud + cloud *gce.Cloud recorder record.EventRecorder } -func newAdapter(k8s clientset.Interface, cloud *gce.GCECloud) *adapter { +func newAdapter(k8s clientset.Interface, cloud *gce.Cloud) *adapter { ret := &adapter{ k8s: k8s, cloud: cloud, diff --git a/pkg/controller/nodeipam/ipam/cloud_cidr_allocator.go b/pkg/controller/nodeipam/ipam/cloud_cidr_allocator.go index e3a0a72aa5bad..12bf16f5a289d 100644 --- a/pkg/controller/nodeipam/ipam/cloud_cidr_allocator.go +++ b/pkg/controller/nodeipam/ipam/cloud_cidr_allocator.go @@ -59,7 +59,7 @@ type nodeProcessingInfo struct { // merely takes the assignment and updates the node spec. type cloudCIDRAllocator struct { client clientset.Interface - cloud *gce.GCECloud + cloud *gce.Cloud // nodeLister is able to list/get nodes and is populated by the shared informer passed to // NewCloudCIDRAllocator. @@ -93,7 +93,7 @@ func NewCloudCIDRAllocator(client clientset.Interface, cloud cloudprovider.Inter glog.V(0).Infof("Sending events to api server.") eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: client.CoreV1().Events("")}) - gceCloud, ok := cloud.(*gce.GCECloud) + gceCloud, ok := cloud.(*gce.Cloud) if !ok { err := fmt.Errorf("cloudCIDRAllocator does not support %v provider", cloud.ProviderName()) return nil, err diff --git a/pkg/controller/nodeipam/ipam/controller.go b/pkg/controller/nodeipam/ipam/controller.go index e33d448d6a95e..18d1c2f368f37 100644 --- a/pkg/controller/nodeipam/ipam/controller.go +++ b/pkg/controller/nodeipam/ipam/controller.go @@ -71,7 +71,7 @@ func NewController( return nil, fmt.Errorf("invalid IPAM controller mode %q", config.Mode) } - gceCloud, ok := cloud.(*gce.GCECloud) + gceCloud, ok := cloud.(*gce.Cloud) if !ok { return nil, fmt.Errorf("cloud IPAM controller does not support %q provider", cloud.ProviderName()) } diff --git a/pkg/controller/nodeipam/node_ipam_controller.go b/pkg/controller/nodeipam/node_ipam_controller.go index 4d45845cf8179..4c3f55575d49c 100644 --- a/pkg/controller/nodeipam/node_ipam_controller.go +++ b/pkg/controller/nodeipam/node_ipam_controller.go @@ -96,13 +96,13 @@ func NewNodeIpamController( eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) - glog.V(0).Infof("Sending events to api server.") + glog.Infof("Sending events to api server.") eventBroadcaster.StartRecordingToSink( &v1core.EventSinkImpl{ Interface: kubeClient.CoreV1().Events(""), }) - if kubeClient != nil && kubeClient.CoreV1().RESTClient().GetRateLimiter() != nil { + if kubeClient.CoreV1().RESTClient().GetRateLimiter() != nil { metrics.RegisterMetricAndTrackRateLimiterUsage("node_ipam_controller", kubeClient.CoreV1().RESTClient().GetRateLimiter()) } diff --git a/pkg/controller/nodeipam/node_ipam_controller_test.go b/pkg/controller/nodeipam/node_ipam_controller_test.go index 6f25f7ce3637c..331c19d66462f 100644 --- a/pkg/controller/nodeipam/node_ipam_controller_test.go +++ b/pkg/controller/nodeipam/node_ipam_controller_test.go @@ -48,7 +48,7 @@ func newTestNodeIpamController(clusterCIDR, serviceCIDR *net.IPNet, nodeCIDRMask fakeNodeInformer.Informer().GetStore().Add(node) } - fakeGCE := gce.FakeGCECloud(gce.DefaultTestClusterValues()) + fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) return NewNodeIpamController( fakeNodeInformer, fakeGCE, clientSet, clusterCIDR, serviceCIDR, nodeCIDRMaskSize, allocatorType, diff --git a/pkg/controller/nodelifecycle/node_lifecycle_controller.go b/pkg/controller/nodelifecycle/node_lifecycle_controller.go index 2dbf4973b24cc..431296a50d504 100644 --- a/pkg/controller/nodelifecycle/node_lifecycle_controller.go +++ b/pkg/controller/nodelifecycle/node_lifecycle_controller.go @@ -275,7 +275,7 @@ func NewNodeLifecycleController( Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events(""), }) - if kubeClient != nil && kubeClient.CoreV1().RESTClient().GetRateLimiter() != nil { + if kubeClient.CoreV1().RESTClient().GetRateLimiter() != nil { metrics.RegisterMetricAndTrackRateLimiterUsage("node_lifecycle_controller", kubeClient.CoreV1().RESTClient().GetRateLimiter()) } diff --git a/pkg/controller/replication/BUILD b/pkg/controller/replication/BUILD index 9dd7ce98ae81b..635de92c6e056 100644 --- a/pkg/controller/replication/BUILD +++ b/pkg/controller/replication/BUILD @@ -16,9 +16,9 @@ go_library( ], importpath = "k8s.io/kubernetes/pkg/controller/replication", deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/apps/v1:go_default_library", "//pkg/apis/core/v1:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/controller:go_default_library", "//pkg/controller/replicaset:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", diff --git a/pkg/controller/replication/conversion.go b/pkg/controller/replication/conversion.go index bd0e1bc0a3d0e..1c9ddb0ba16d0 100644 --- a/pkg/controller/replication/conversion.go +++ b/pkg/controller/replication/conversion.go @@ -41,9 +41,9 @@ import ( appslisters "k8s.io/client-go/listers/apps/v1" v1listers "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" + appsinternal "k8s.io/kubernetes/pkg/apis/apps" appsconversion "k8s.io/kubernetes/pkg/apis/apps/v1" apiv1 "k8s.io/kubernetes/pkg/apis/core/v1" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/controller" ) @@ -276,26 +276,26 @@ func convertCall(fn func(*v1.ReplicationController) (*v1.ReplicationController, } func convertRCtoRS(rc *v1.ReplicationController, out *apps.ReplicaSet) (*apps.ReplicaSet, error) { - var rsInternal extensions.ReplicaSet - if err := apiv1.Convert_v1_ReplicationController_To_extensions_ReplicaSet(rc, &rsInternal, nil); err != nil { + var rsInternal appsinternal.ReplicaSet + if err := apiv1.Convert_v1_ReplicationController_To_apps_ReplicaSet(rc, &rsInternal, nil); err != nil { return nil, fmt.Errorf("can't convert ReplicationController %v/%v to ReplicaSet: %v", rc.Namespace, rc.Name, err) } if out == nil { out = new(apps.ReplicaSet) } - if err := appsconversion.Convert_extensions_ReplicaSet_To_v1_ReplicaSet(&rsInternal, out, nil); err != nil { - return nil, fmt.Errorf("can't convert ReplicaSet (converted from ReplicationController %v/%v) from internal to extensions/v1beta1: %v", rc.Namespace, rc.Name, err) + if err := appsconversion.Convert_apps_ReplicaSet_To_v1_ReplicaSet(&rsInternal, out, nil); err != nil { + return nil, fmt.Errorf("can't convert ReplicaSet (converted from ReplicationController %v/%v) from internal to apps/v1: %v", rc.Namespace, rc.Name, err) } return out, nil } func convertRStoRC(rs *apps.ReplicaSet) (*v1.ReplicationController, error) { - var rsInternal extensions.ReplicaSet - if err := appsconversion.Convert_v1_ReplicaSet_To_extensions_ReplicaSet(rs, &rsInternal, nil); err != nil { - return nil, fmt.Errorf("can't convert ReplicaSet (converting to ReplicationController %v/%v) from extensions/v1beta1 to internal: %v", rs.Namespace, rs.Name, err) + var rsInternal appsinternal.ReplicaSet + if err := appsconversion.Convert_v1_ReplicaSet_To_apps_ReplicaSet(rs, &rsInternal, nil); err != nil { + return nil, fmt.Errorf("can't convert ReplicaSet (converting to ReplicationController %v/%v) from apps/v1 to internal: %v", rs.Namespace, rs.Name, err) } var rc v1.ReplicationController - if err := apiv1.Convert_extensions_ReplicaSet_To_v1_ReplicationController(&rsInternal, &rc, nil); err != nil { + if err := apiv1.Convert_apps_ReplicaSet_To_v1_ReplicationController(&rsInternal, &rc, nil); err != nil { return nil, fmt.Errorf("can't convert ReplicaSet to ReplicationController %v/%v: %v", rs.Namespace, rs.Name, err) } return &rc, nil diff --git a/pkg/controller/serviceaccount/OWNERS b/pkg/controller/serviceaccount/OWNERS index a678215e98405..d914c0d7195a7 100755 --- a/pkg/controller/serviceaccount/OWNERS +++ b/pkg/controller/serviceaccount/OWNERS @@ -1,7 +1,7 @@ approvers: -- liggitt -- deads2k +- sig-auth-serviceaccounts-approvers reviewers: -- liggitt -- deads2k -- enj +- sig-auth-serviceaccounts-reviewers +labels: +- sig/auth + diff --git a/pkg/controller/statefulset/stateful_set.go b/pkg/controller/statefulset/stateful_set.go index 2e197c9da6830..e88a6dae255e9 100644 --- a/pkg/controller/statefulset/stateful_set.go +++ b/pkg/controller/statefulset/stateful_set.go @@ -382,7 +382,7 @@ func (ssc *StatefulSetController) resolveControllerRef(namespace string, control func (ssc *StatefulSetController) enqueueStatefulSet(obj interface{}) { key, err := controller.KeyFunc(obj) if err != nil { - utilruntime.HandleError(fmt.Errorf("Cound't get key for object %+v: %v", obj, err)) + utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %+v: %v", obj, err)) return } ssc.queue.Add(key) diff --git a/pkg/controller/volume/attachdetach/attach_detach_controller.go b/pkg/controller/volume/attachdetach/attach_detach_controller.go index c3f9ea09b62e5..e2b1b6632f988 100644 --- a/pkg/controller/volume/attachdetach/attach_detach_controller.go +++ b/pkg/controller/volume/attachdetach/attach_detach_controller.go @@ -729,6 +729,12 @@ func (adc *attachDetachController) GetServiceAccountTokenFunc() func(_, _ string } } +func (adc *attachDetachController) DeleteServiceAccountTokenFunc() func(types.UID) { + return func(types.UID) { + glog.Errorf("DeleteServiceAccountToken unsupported in attachDetachController") + } +} + func (adc *attachDetachController) GetExec(pluginName string) mount.Exec { return mount.NewOsExec() } diff --git a/pkg/controller/volume/attachdetach/cache/actual_state_of_world.go b/pkg/controller/volume/attachdetach/cache/actual_state_of_world.go index 985b29962daea..7dfe739627479 100644 --- a/pkg/controller/volume/attachdetach/cache/actual_state_of_world.go +++ b/pkg/controller/volume/attachdetach/cache/actual_state_of_world.go @@ -559,6 +559,7 @@ func (asw *actualStateOfWorld) GetAttachedVolumesForNode( attachedVolumes = append( attachedVolumes, getAttachedVolume(&volumeObj, &nodeObj)) + break } } } diff --git a/pkg/controller/volume/expand/expand_controller.go b/pkg/controller/volume/expand/expand_controller.go index 601a9b95f7246..f40bf080a8706 100644 --- a/pkg/controller/volume/expand/expand_controller.go +++ b/pkg/controller/volume/expand/expand_controller.go @@ -208,13 +208,16 @@ func (expc *expandController) pvcUpdate(oldObj, newObj interface{}) { return } - // Filter PVCs for which the corresponding volume plugins don't allow expansion. volumeSpec := volume.NewSpecFromPersistentVolume(pv, false) volumePlugin, err := expc.volumePluginMgr.FindExpandablePluginBySpec(volumeSpec) if err != nil || volumePlugin == nil { err = fmt.Errorf("didn't find a plugin capable of expanding the volume; " + "waiting for an external controller to process this PVC") - expc.recorder.Event(newPVC, v1.EventTypeNormal, events.ExternalExpanding, + eventType := v1.EventTypeNormal + if err != nil { + eventType = v1.EventTypeWarning + } + expc.recorder.Event(newPVC, eventType, events.ExternalExpanding, fmt.Sprintf("Ignoring the PVC: %v.", err)) glog.V(3).Infof("Ignoring the PVC %q (uid: %q) : %v.", util.GetPersistentVolumeClaimQualifiedName(newPVC), newPVC.UID, err) @@ -314,6 +317,12 @@ func (expc *expandController) GetServiceAccountTokenFunc() func(_, _ string, _ * } } +func (expc *expandController) DeleteServiceAccountTokenFunc() func(types.UID) { + return func(types.UID) { + glog.Errorf("DeleteServiceAccountToken unsupported in expandController") + } +} + func (expc *expandController) GetNodeLabels() (map[string]string, error) { return nil, fmt.Errorf("GetNodeLabels unsupported in expandController") } diff --git a/pkg/controller/volume/expand/pvc_populator.go b/pkg/controller/volume/expand/pvc_populator.go index a7a06ec1122b4..4f29e2292e222 100644 --- a/pkg/controller/volume/expand/pvc_populator.go +++ b/pkg/controller/volume/expand/pvc_populator.go @@ -104,7 +104,11 @@ func (populator *pvcPopulator) Sync() { if (err != nil || volumePlugin == nil) && pvcStatusSize.Cmp(pvcSize) < 0 { err = fmt.Errorf("didn't find a plugin capable of expanding the volume; " + "waiting for an external controller to process this PVC") - populator.recorder.Event(pvc, v1.EventTypeNormal, events.ExternalExpanding, + eventType := v1.EventTypeNormal + if err != nil { + eventType = v1.EventTypeWarning + } + populator.recorder.Event(pvc, eventType, events.ExternalExpanding, fmt.Sprintf("Ignoring the PVC: %v.", err)) glog.V(3).Infof("Ignoring the PVC %q (uid: %q) : %v.", util.GetPersistentVolumeClaimQualifiedName(pvc), pvc.UID, err) diff --git a/pkg/controller/volume/expand/sync_volume_resize.go b/pkg/controller/volume/expand/sync_volume_resize.go index 17ecba5330f5d..9ad10eb277134 100644 --- a/pkg/controller/volume/expand/sync_volume_resize.go +++ b/pkg/controller/volume/expand/sync_volume_resize.go @@ -77,7 +77,6 @@ func (rc *syncResize) Sync() { glog.V(10).Infof("Operation for PVC %v is already pending", pvcWithResizeRequest.QualifiedName()) continue } - glog.V(5).Infof("Starting opsExecutor.ExpandVolume for volume %s", pvcWithResizeRequest.QualifiedName()) growFuncError := rc.opsExecutor.ExpandVolume(pvcWithResizeRequest, rc.resizeMap) if growFuncError != nil && !exponentialbackoff.IsExponentialBackoff(growFuncError) { glog.Errorf("Error growing pvc %s with %v", pvcWithResizeRequest.QualifiedName(), growFuncError) diff --git a/pkg/controller/volume/persistentvolume/scheduler_binder.go b/pkg/controller/volume/persistentvolume/scheduler_binder.go index 8d981a076e1cf..8ef8b2adc1a07 100644 --- a/pkg/controller/volume/persistentvolume/scheduler_binder.go +++ b/pkg/controller/volume/persistentvolume/scheduler_binder.go @@ -446,23 +446,24 @@ func (b *volumeBinder) isPVCBound(namespace, pvcName string) (bool, *v1.Persiste Namespace: namespace, }, } - pvc, err := b.pvcCache.GetPVC(getPVCName(claim)) + pvcKey := getPVCName(claim) + pvc, err := b.pvcCache.GetPVC(pvcKey) if err != nil || pvc == nil { - return false, nil, fmt.Errorf("error getting PVC %q: %v", pvcName, err) + return false, nil, fmt.Errorf("error getting PVC %q: %v", pvcKey, err) } pvName := pvc.Spec.VolumeName if pvName != "" { if metav1.HasAnnotation(pvc.ObjectMeta, annBindCompleted) { - glog.V(5).Infof("PVC %q is fully bound to PV %q", getPVCName(pvc), pvName) + glog.V(5).Infof("PVC %q is fully bound to PV %q", pvcKey, pvName) return true, pvc, nil } else { - glog.V(5).Infof("PVC %q is not fully bound to PV %q", getPVCName(pvc), pvName) + glog.V(5).Infof("PVC %q is not fully bound to PV %q", pvcKey, pvName) return false, pvc, nil } } - glog.V(5).Infof("PVC %q is not bound", getPVCName(pvc)) + glog.V(5).Infof("PVC %q is not bound", pvcKey) return false, pvc, nil } @@ -522,7 +523,7 @@ func (b *volumeBinder) checkBoundClaims(claims []*v1.PersistentVolumeClaim, node err = volumeutil.CheckNodeAffinity(pv, node.Labels) if err != nil { - glog.V(4).Infof("PersistentVolume %q, Node %q mismatch for Pod %q: %v", pvName, node.Name, err.Error(), podName) + glog.V(4).Infof("PersistentVolume %q, Node %q mismatch for Pod %q: %v", pvName, node.Name, podName, err) return false, nil } glog.V(5).Infof("PersistentVolume %q, Node %q matches for Pod %q", pvName, node.Name, podName) @@ -552,6 +553,7 @@ func (b *volumeBinder) findMatchingVolumes(pod *v1.Pod, claimsToBind []*bindingI storageClassName = *storageClass } allPVs := b.pvCache.ListPVs(storageClassName) + pvcName := getPVCName(bindingInfo.pvc) // Find a matching PV bindingInfo.pv, err = findMatchingVolume(bindingInfo.pvc, allPVs, node, chosenPVs, true) @@ -559,7 +561,7 @@ func (b *volumeBinder) findMatchingVolumes(pod *v1.Pod, claimsToBind []*bindingI return false, nil, err } if bindingInfo.pv == nil { - glog.V(4).Infof("No matching volumes for Pod %q, PVC %q on node %q", podName, getPVCName(bindingInfo.pvc), node.Name) + glog.V(4).Infof("No matching volumes for Pod %q, PVC %q on node %q", podName, pvcName, node.Name) unboundClaims = append(unboundClaims, bindingInfo.pvc) foundMatches = false continue @@ -568,7 +570,7 @@ func (b *volumeBinder) findMatchingVolumes(pod *v1.Pod, claimsToBind []*bindingI // matching PV needs to be excluded so we don't select it again chosenPVs[bindingInfo.pv.Name] = bindingInfo.pv matchedClaims = append(matchedClaims, bindingInfo) - glog.V(5).Infof("Found matching PV %q for PVC %q on node %q for pod %q", bindingInfo.pv.Name, getPVCName(bindingInfo.pvc), node.Name, podName) + glog.V(5).Infof("Found matching PV %q for PVC %q on node %q for pod %q", bindingInfo.pv.Name, pvcName, node.Name, podName) } // Mark cache with all the matches for each PVC for this node @@ -591,9 +593,10 @@ func (b *volumeBinder) checkVolumeProvisions(pod *v1.Pod, claimsToProvision []*v provisionedClaims := []*v1.PersistentVolumeClaim{} for _, claim := range claimsToProvision { + pvcName := getPVCName(claim) className := v1helper.GetPersistentVolumeClaimClass(claim) if className == "" { - return false, fmt.Errorf("no class for claim %q", getPVCName(claim)) + return false, fmt.Errorf("no class for claim %q", pvcName) } class, err := b.ctrl.classLister.Get(className) @@ -602,13 +605,13 @@ func (b *volumeBinder) checkVolumeProvisions(pod *v1.Pod, claimsToProvision []*v } provisioner := class.Provisioner if provisioner == "" || provisioner == notSupportedProvisioner { - glog.V(4).Infof("storage class %q of claim %q does not support dynamic provisioning", className, getPVCName(claim)) + glog.V(4).Infof("storage class %q of claim %q does not support dynamic provisioning", className, pvcName) return false, nil } // Check if the node can satisfy the topology requirement in the class if !v1helper.MatchTopologySelectorTerms(class.AllowedTopologies, labels.Set(node.Labels)) { - glog.V(4).Infof("Node %q cannot satisfy provisioning topology requirements of claim %q", node.Name, getPVCName(claim)) + glog.V(4).Infof("Node %q cannot satisfy provisioning topology requirements of claim %q", node.Name, pvcName) return false, nil } diff --git a/pkg/controller/volume/persistentvolume/volume_host.go b/pkg/controller/volume/persistentvolume/volume_host.go index 43e5c077a41e7..298d5737a6283 100644 --- a/pkg/controller/volume/persistentvolume/volume_host.go +++ b/pkg/controller/volume/persistentvolume/volume_host.go @@ -20,6 +20,7 @@ import ( "fmt" "net" + "github.com/golang/glog" authenticationv1 "k8s.io/api/authentication/v1" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -109,6 +110,12 @@ func (ctrl *PersistentVolumeController) GetServiceAccountTokenFunc() func(_, _ s } } +func (ctrl *PersistentVolumeController) DeleteServiceAccountTokenFunc() func(types.UID) { + return func(types.UID) { + glog.Errorf("DeleteServiceAccountToken unsupported in PersistentVolumeController") + } +} + func (adc *PersistentVolumeController) GetExec(pluginName string) mount.Exec { return mount.NewOsExec() } diff --git a/pkg/credentialprovider/aws/aws_credentials.go b/pkg/credentialprovider/aws/aws_credentials.go index d889cbf1fa8b9..862c2c62c6f09 100644 --- a/pkg/credentialprovider/aws/aws_credentials.go +++ b/pkg/credentialprovider/aws/aws_credentials.go @@ -27,6 +27,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ecr" "github.com/golang/glog" + "k8s.io/kubernetes/pkg/credentialprovider" ) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 52b359864dbcc..7efe0b5d51e22 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -49,6 +49,7 @@ const ( // owner: @vishh // alpha: v1.5 // + // DEPRECATED - This feature is deprecated by Pod Priority and Preemption as of Kubernetes 1.13. // Ensures guaranteed scheduling of pods marked with a special pod annotation `scheduler.alpha.kubernetes.io/critical-pod` // and also prevents them from being evicted from a node. // Note: This feature is not supported for `BestEffort` pods. @@ -139,6 +140,7 @@ const ( // owner: @jsafrane // GA: v1.12 // + // Note: This feature gate is unconditionally enabled in v1.13 and will be removed in v1.14. // Enable mount propagation of volumes. MountPropagation utilfeature.Feature = "MountPropagation" @@ -186,10 +188,9 @@ const ( MountContainers utilfeature.Feature = "MountContainers" // owner: @msau42 - // alpha: v1.9 + // GA: v1.13 // // Extend the default scheduler to be aware of PV topology and handle PV binding - // Before moving to beta, resolve Kubernetes issue #56180 VolumeScheduling utilfeature.Feature = "VolumeScheduling" // owner: @vladimirvivien @@ -413,7 +414,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS CPUCFSQuotaPeriod: {Default: false, PreRelease: utilfeature.Alpha}, ServiceNodeExclusion: {Default: false, PreRelease: utilfeature.Alpha}, MountContainers: {Default: false, PreRelease: utilfeature.Alpha}, - VolumeScheduling: {Default: true, PreRelease: utilfeature.Beta}, + VolumeScheduling: {Default: true, PreRelease: utilfeature.GA}, CSIPersistentVolume: {Default: true, PreRelease: utilfeature.Beta}, CSIDriverRegistry: {Default: false, PreRelease: utilfeature.Alpha}, CSINodeInfo: {Default: false, PreRelease: utilfeature.Alpha}, @@ -455,8 +456,9 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS // inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed // unintentionally on either side: - apiextensionsfeatures.CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta}, - apiextensionsfeatures.CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta}, + apiextensionsfeatures.CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta}, + apiextensionsfeatures.CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta}, + apiextensionsfeatures.CustomResourceWebhookConversion: {Default: false, PreRelease: utilfeature.Alpha}, // features that enable backwards compatibility but are scheduled to be removed // ... diff --git a/pkg/kubeapiserver/BUILD b/pkg/kubeapiserver/BUILD index ef4c4b1e22df3..2e2b390e1f6bc 100644 --- a/pkg/kubeapiserver/BUILD +++ b/pkg/kubeapiserver/BUILD @@ -50,6 +50,7 @@ filegroup( "//pkg/kubeapiserver/authorizer:all-srcs", "//pkg/kubeapiserver/options:all-srcs", "//pkg/kubeapiserver/server:all-srcs", + "//pkg/kubeapiserver/util:all-srcs", ], tags = ["automanaged"], ) diff --git a/pkg/kubeapiserver/admission/BUILD b/pkg/kubeapiserver/admission/BUILD index bfbd57058ccc3..fb9a80a8e924c 100644 --- a/pkg/kubeapiserver/admission/BUILD +++ b/pkg/kubeapiserver/admission/BUILD @@ -1,33 +1,39 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", - "go_test", -) - -go_test( - name = "go_default_test", - srcs = ["initializer_test.go"], - embed = [":go_default_library"], - deps = ["//staging/src/k8s.io/apiserver/pkg/admission:go_default_library"], -) +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", - srcs = ["initializer.go"], + srcs = [ + "config.go", + "initializer.go", + ], importpath = "k8s.io/kubernetes/pkg/kubeapiserver/admission", + visibility = ["//visibility:public"], deps = [ "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", "//pkg/quota/v1:go_default_library", + "//pkg/quota/v1/install:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/server:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", + "//staging/src/k8s.io/client-go/discovery/cached:go_default_library", + "//staging/src/k8s.io/client-go/informers:go_default_library", + "//staging/src/k8s.io/client-go/rest:go_default_library", + "//staging/src/k8s.io/client-go/restmapper:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", ], ) +go_test( + name = "go_default_test", + srcs = ["initializer_test.go"], + embed = [":go_default_library"], + deps = ["//staging/src/k8s.io/apiserver/pkg/admission:go_default_library"], +) + filegroup( name = "package-srcs", srcs = glob(["**"]), @@ -42,4 +48,5 @@ filegroup( "//pkg/kubeapiserver/admission/util:all-srcs", ], tags = ["automanaged"], + visibility = ["//visibility:public"], ) diff --git a/pkg/kubeapiserver/admission/config.go b/pkg/kubeapiserver/admission/config.go new file mode 100644 index 0000000000000..526b2094e799a --- /dev/null +++ b/pkg/kubeapiserver/admission/config.go @@ -0,0 +1,80 @@ +/* +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 admission + +import ( + "io/ioutil" + "net/http" + "time" + + "github.com/golang/glog" + + utilwait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/admission" + webhookinit "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer" + "k8s.io/apiserver/pkg/server" + genericapiserver "k8s.io/apiserver/pkg/server" + "k8s.io/apiserver/pkg/util/webhook" + cacheddiscovery "k8s.io/client-go/discovery/cached" + externalinformers "k8s.io/client-go/informers" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" + "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + quotainstall "k8s.io/kubernetes/pkg/quota/v1/install" +) + +// Config holds the configuration needed to for initialize the admission plugins +type Config struct { + CloudConfigFile string + LoopbackClientConfig *rest.Config + ExternalInformers externalinformers.SharedInformerFactory +} + +// New sets up the plugins and admission start hooks needed for admission +func (c *Config) New(proxyTransport *http.Transport, serviceResolver webhook.ServiceResolver) ([]admission.PluginInitializer, server.PostStartHookFunc, error) { + webhookAuthResolverWrapper := webhook.NewDefaultAuthenticationInfoResolverWrapper(proxyTransport, c.LoopbackClientConfig) + webhookPluginInitializer := webhookinit.NewPluginInitializer(webhookAuthResolverWrapper, serviceResolver) + + var cloudConfig []byte + if c.CloudConfigFile != "" { + var err error + cloudConfig, err = ioutil.ReadFile(c.CloudConfigFile) + if err != nil { + glog.Fatalf("Error reading from cloud configuration file %s: %#v", c.CloudConfigFile, err) + } + } + internalClient, err := internalclientset.NewForConfig(c.LoopbackClientConfig) + if err != nil { + return nil, nil, err + } + + discoveryClient := cacheddiscovery.NewMemCacheClient(internalClient.Discovery()) + discoveryRESTMapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient) + kubePluginInitializer := NewPluginInitializer( + cloudConfig, + discoveryRESTMapper, + quotainstall.NewQuotaConfigurationForAdmission(), + ) + + admissionPostStartHook := func(context genericapiserver.PostStartHookContext) error { + discoveryRESTMapper.Reset() + go utilwait.Until(discoveryRESTMapper.Reset, 30*time.Second, context.StopCh) + return nil + } + + return []admission.PluginInitializer{webhookPluginInitializer, kubePluginInitializer}, admissionPostStartHook, nil +} diff --git a/pkg/kubeapiserver/admission/initializer.go b/pkg/kubeapiserver/admission/initializer.go index d5751c4b61823..731631e824db4 100644 --- a/pkg/kubeapiserver/admission/initializer.go +++ b/pkg/kubeapiserver/admission/initializer.go @@ -21,25 +21,11 @@ import ( "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/util/webhook" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" quota "k8s.io/kubernetes/pkg/quota/v1" ) // TODO add a `WantsToRun` which takes a stopCh. Might make it generic. -// WantsInternalKubeClientSet defines a function which sets ClientSet for admission plugins that need it -type WantsInternalKubeClientSet interface { - SetInternalKubeClientSet(internalclientset.Interface) - admission.InitializationValidator -} - -// WantsInternalKubeInformerFactory defines a function which sets InformerFactory for admission plugins that need it -type WantsInternalKubeInformerFactory interface { - SetInternalKubeInformerFactory(informers.SharedInformerFactory) - admission.InitializationValidator -} - // WantsCloudConfig defines a function which sets CloudConfig for admission plugins that need it. type WantsCloudConfig interface { SetCloudConfig([]byte) @@ -58,8 +44,6 @@ type WantsQuotaConfiguration interface { // PluginInitializer is used for initialization of the Kubernetes specific admission plugins. type PluginInitializer struct { - internalClient internalclientset.Interface - informers informers.SharedInformerFactory authorizer authorizer.Authorizer cloudConfig []byte restMapper meta.RESTMapper @@ -74,15 +58,11 @@ var _ admission.PluginInitializer = &PluginInitializer{} // TODO: switch these parameters to use the builder pattern or just make them // all public, this construction method is pointless boilerplate. func NewPluginInitializer( - internalClient internalclientset.Interface, - sharedInformers informers.SharedInformerFactory, cloudConfig []byte, restMapper meta.RESTMapper, quotaConfiguration quota.Configuration, ) *PluginInitializer { return &PluginInitializer{ - internalClient: internalClient, - informers: sharedInformers, cloudConfig: cloudConfig, restMapper: restMapper, quotaConfiguration: quotaConfiguration, @@ -92,14 +72,6 @@ func NewPluginInitializer( // Initialize checks the initialization interfaces implemented by each plugin // and provide the appropriate initialization data func (i *PluginInitializer) Initialize(plugin admission.Interface) { - if wants, ok := plugin.(WantsInternalKubeClientSet); ok { - wants.SetInternalKubeClientSet(i.internalClient) - } - - if wants, ok := plugin.(WantsInternalKubeInformerFactory); ok { - wants.SetInternalKubeInformerFactory(i.informers) - } - if wants, ok := plugin.(WantsCloudConfig); ok { wants.SetCloudConfig(i.cloudConfig) } diff --git a/pkg/kubeapiserver/admission/initializer_test.go b/pkg/kubeapiserver/admission/initializer_test.go index b88021d8a6975..f5a6b144c6ae2 100644 --- a/pkg/kubeapiserver/admission/initializer_test.go +++ b/pkg/kubeapiserver/admission/initializer_test.go @@ -33,13 +33,13 @@ type WantsCloudConfigAdmissionPlugin struct { cloudConfig []byte } -func (self *WantsCloudConfigAdmissionPlugin) SetCloudConfig(cloudConfig []byte) { - self.cloudConfig = cloudConfig +func (p *WantsCloudConfigAdmissionPlugin) SetCloudConfig(cloudConfig []byte) { + p.cloudConfig = cloudConfig } func TestCloudConfigAdmissionPlugin(t *testing.T) { cloudConfig := []byte("cloud-configuration") - initializer := NewPluginInitializer(nil, nil, cloudConfig, nil, nil) + initializer := NewPluginInitializer(cloudConfig, nil, nil) wantsCloudConfigAdmission := &WantsCloudConfigAdmissionPlugin{} initializer.Initialize(wantsCloudConfigAdmission) diff --git a/pkg/kubeapiserver/authenticator/OWNERS b/pkg/kubeapiserver/authenticator/OWNERS new file mode 100644 index 0000000000000..c607d2aa8c5fe --- /dev/null +++ b/pkg/kubeapiserver/authenticator/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers +reviewers: +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/pkg/kubeapiserver/authenticator/config.go b/pkg/kubeapiserver/authenticator/config.go index a91136599c618..255fa27482958 100644 --- a/pkg/kubeapiserver/authenticator/config.go +++ b/pkg/kubeapiserver/authenticator/config.go @@ -38,14 +38,15 @@ import ( "k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth" "k8s.io/apiserver/plugin/pkg/authenticator/token/oidc" "k8s.io/apiserver/plugin/pkg/authenticator/token/webhook" + // Initialize all known client auth plugins. + _ "k8s.io/client-go/plugin/pkg/client/auth" certutil "k8s.io/client-go/util/cert" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/serviceaccount" - - _ "k8s.io/client-go/plugin/pkg/client/auth" ) -type AuthenticatorConfig struct { +// Config contains the data on how to authenticate a request to the Kube API Server +type Config struct { Anonymous bool BasicAuthFile string BootstrapToken bool @@ -79,7 +80,7 @@ type AuthenticatorConfig struct { // New returns an authenticator.Request or an error that supports the standard // Kubernetes authentication mechanisms. -func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDefinitions, error) { +func (config Config) New() (authenticator.Request, *spec.SecurityDefinitions, error) { var authenticators []authenticator.Request var tokenAuthenticators []authenticator.Token securityDefinitions := spec.SecurityDefinitions{} @@ -97,7 +98,7 @@ func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDe if err != nil { return nil, nil, err } - authenticators = append(authenticators, requestHeaderAuthenticator) + authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, requestHeaderAuthenticator)) } // basic auth @@ -106,7 +107,7 @@ func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDe if err != nil { return nil, nil, err } - authenticators = append(authenticators, basicAuth) + authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, basicAuth)) securityDefinitions["HTTPBasic"] = &spec.SecurityScheme{ SecuritySchemeProps: spec.SecuritySchemeProps{ @@ -131,14 +132,14 @@ func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDe if err != nil { return nil, nil, err } - tokenAuthenticators = append(tokenAuthenticators, tokenAuth) + tokenAuthenticators = append(tokenAuthenticators, authenticator.WrapAudienceAgnosticToken(config.APIAudiences, tokenAuth)) } if len(config.ServiceAccountKeyFiles) > 0 { serviceAccountAuth, err := newLegacyServiceAccountAuthenticator(config.ServiceAccountKeyFiles, config.ServiceAccountLookup, config.ServiceAccountTokenGetter) if err != nil { return nil, nil, err } - tokenAuthenticators = append(tokenAuthenticators, serviceAccountAuth) + tokenAuthenticators = append(tokenAuthenticators, authenticator.WrapAudienceAgnosticToken(config.APIAudiences, serviceAccountAuth)) } if utilfeature.DefaultFeatureGate.Enabled(features.TokenRequest) && config.ServiceAccountIssuer != "" { serviceAccountAuth, err := newServiceAccountAuthenticator(config.ServiceAccountIssuer, config.APIAudiences, config.ServiceAccountKeyFiles, config.ServiceAccountTokenGetter) @@ -150,7 +151,7 @@ func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDe if config.BootstrapToken { if config.BootstrapTokenAuthenticator != nil { // TODO: This can sometimes be nil because of - tokenAuthenticators = append(tokenAuthenticators, config.BootstrapTokenAuthenticator) + tokenAuthenticators = append(tokenAuthenticators, authenticator.WrapAudienceAgnosticToken(config.APIAudiences, config.BootstrapTokenAuthenticator)) } } // NOTE(ericchiang): Keep the OpenID Connect after Service Accounts. @@ -179,7 +180,7 @@ func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDe tokenAuth := tokenunion.New(tokenAuthenticators...) // Optionally cache authentication results if config.TokenSuccessCacheTTL > 0 || config.TokenFailureCacheTTL > 0 { - tokenAuth = tokencache.New(tokenAuth, config.TokenSuccessCacheTTL, config.TokenFailureCacheTTL) + tokenAuth = tokencache.New(tokenAuth, true, config.TokenSuccessCacheTTL, config.TokenFailureCacheTTL) } authenticators = append(authenticators, bearertoken.New(tokenAuth), websocket.NewProtocolAuthenticator(tokenAuth)) securityDefinitions["BearerToken"] = &spec.SecurityScheme{ @@ -317,10 +318,10 @@ func newAuthenticatorFromClientCAFile(clientCAFile string) (authenticator.Reques } func newWebhookTokenAuthenticator(webhookConfigFile string, ttl time.Duration) (authenticator.Token, error) { - webhookTokenAuthenticator, err := webhook.New(webhookConfigFile, ttl) + webhookTokenAuthenticator, err := webhook.New(webhookConfigFile) if err != nil { return nil, err } - return webhookTokenAuthenticator, nil + return tokencache.New(webhookTokenAuthenticator, false, ttl, ttl), nil } diff --git a/pkg/kubeapiserver/authorizer/OWNERS b/pkg/kubeapiserver/authorizer/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/pkg/kubeapiserver/authorizer/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/pkg/kubeapiserver/authorizer/config.go b/pkg/kubeapiserver/authorizer/config.go index 00224fd482524..5a3d88aabbcd2 100644 --- a/pkg/kubeapiserver/authorizer/config.go +++ b/pkg/kubeapiserver/authorizer/config.go @@ -33,7 +33,8 @@ import ( "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy" ) -type AuthorizationConfig struct { +// Config contains the data on how to authorize a request to the Kube API Server +type Config struct { AuthorizationModes []string // Options for ModeABAC @@ -55,7 +56,7 @@ type AuthorizationConfig struct { // New returns the right sort of union of multiple authorizer.Authorizer objects // based on the authorizationMode or an error. -func (config AuthorizationConfig) New() (authorizer.Authorizer, authorizer.RuleResolver, error) { +func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, error) { if len(config.AuthorizationModes) == 0 { return nil, nil, fmt.Errorf("at least one authorization mode must be passed") } diff --git a/pkg/kubeapiserver/authorizer/modes/modes.go b/pkg/kubeapiserver/authorizer/modes/modes.go index 54d0a627701d5..501b98a95c2ab 100644 --- a/pkg/kubeapiserver/authorizer/modes/modes.go +++ b/pkg/kubeapiserver/authorizer/modes/modes.go @@ -19,14 +19,21 @@ package modes import "k8s.io/apimachinery/pkg/util/sets" const ( + // ModeAlwaysAllow is the mode to set all requests as authorized ModeAlwaysAllow string = "AlwaysAllow" - ModeAlwaysDeny string = "AlwaysDeny" - ModeABAC string = "ABAC" - ModeWebhook string = "Webhook" - ModeRBAC string = "RBAC" - ModeNode string = "Node" + // ModeAlwaysDeny is the mode to set no requests as authorized + ModeAlwaysDeny string = "AlwaysDeny" + // ModeABAC is the mode to use Attribute Based Access Control to authorize + ModeABAC string = "ABAC" + // ModeWebhook is the mode to make an external webhook call to authorize + ModeWebhook string = "Webhook" + // ModeRBAC is the mode to use Role Based Access Control to authorize + ModeRBAC string = "RBAC" + // ModeNode is an authorization mode that authorizes API requests made by kubelets. + ModeNode string = "Node" ) +// AuthorizationModeChoices is the list of supported authorization modes var AuthorizationModeChoices = []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC, ModeWebhook, ModeRBAC, ModeNode} // IsValidAuthorizationMode returns true if the given authorization mode is a valid one for the apiserver diff --git a/pkg/kubeapiserver/options/BUILD b/pkg/kubeapiserver/options/BUILD index 1f4ca636a7d8f..0a9373a0ea05d 100644 --- a/pkg/kubeapiserver/options/BUILD +++ b/pkg/kubeapiserver/options/BUILD @@ -61,6 +61,7 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", @@ -99,6 +100,7 @@ go_test( "//pkg/kubeapiserver/authorizer/modes:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library", ], diff --git a/pkg/kubeapiserver/options/authentication.go b/pkg/kubeapiserver/options/authentication.go index c73764626ad21..2c149cbf3202f 100644 --- a/pkg/kubeapiserver/options/authentication.go +++ b/pkg/kubeapiserver/options/authentication.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/authentication/authenticator" genericapiserver "k8s.io/apiserver/pkg/server" genericoptions "k8s.io/apiserver/pkg/server/options" "k8s.io/apiserver/pkg/util/flag" @@ -176,7 +177,9 @@ func (s *BuiltInAuthenticationOptions) Validate() []error { func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) { fs.StringSliceVar(&s.APIAudiences, "api-audiences", s.APIAudiences, ""+ "Identifiers of the API. The service account token authenticator will validate that "+ - "tokens used against the API are bound to at least one of these audiences.") + "tokens used against the API are bound to at least one of these audiences. If the "+ + "--service-account-issuer flag is configured and this flag is not, this field "+ + "defaults to a single element list containing the issuer URL .") if s.Anonymous != nil { fs.BoolVar(&s.Anonymous.Allow, "anonymous-auth", s.Anonymous.Allow, ""+ @@ -289,8 +292,8 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) { } } -func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() kubeauthenticator.AuthenticatorConfig { - ret := kubeauthenticator.AuthenticatorConfig{ +func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() kubeauthenticator.Config { + ret := kubeauthenticator.Config{ TokenSuccessCacheTTL: s.TokenSuccessCacheTTL, TokenFailureCacheTTL: s.TokenFailureCacheTTL, } @@ -327,11 +330,14 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() kubeauthenticato ret.RequestHeaderConfig = s.RequestHeader.ToAuthenticationRequestHeaderConfig() } + ret.APIAudiences = s.APIAudiences if s.ServiceAccounts != nil { + if s.ServiceAccounts.Issuer != "" && len(s.APIAudiences) == 0 { + ret.APIAudiences = authenticator.Audiences{s.ServiceAccounts.Issuer} + } ret.ServiceAccountKeyFiles = s.ServiceAccounts.KeyFiles - ret.ServiceAccountLookup = s.ServiceAccounts.Lookup ret.ServiceAccountIssuer = s.ServiceAccounts.Issuer - ret.APIAudiences = s.APIAudiences + ret.ServiceAccountLookup = s.ServiceAccounts.Lookup } if s.TokenFile != nil { @@ -373,7 +379,11 @@ func (o *BuiltInAuthenticationOptions) ApplyTo(c *genericapiserver.Config) error } c.Authentication.SupportsBasicAuth = o.PasswordFile != nil && len(o.PasswordFile.BasicAuthFile) > 0 + c.Authentication.APIAudiences = o.APIAudiences + if o.ServiceAccounts != nil && o.ServiceAccounts.Issuer != "" && len(o.APIAudiences) == 0 { + c.Authentication.APIAudiences = authenticator.Audiences{o.ServiceAccounts.Issuer} + } return nil } diff --git a/pkg/kubeapiserver/options/authentication_test.go b/pkg/kubeapiserver/options/authentication_test.go index 0de54c79c1caa..ac45c457de196 100644 --- a/pkg/kubeapiserver/options/authentication_test.go +++ b/pkg/kubeapiserver/options/authentication_test.go @@ -23,9 +23,10 @@ import ( "time" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/authenticatorfactory" apiserveroptions "k8s.io/apiserver/pkg/server/options" - "k8s.io/kubernetes/pkg/kubeapiserver/authenticator" + kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator" ) func TestAuthenticationValidate(t *testing.T) { @@ -137,7 +138,8 @@ func TestToAuthenticationConfig(t *testing.T) { TokenFailureCacheTTL: 0, } - expectConfig := authenticator.AuthenticatorConfig{ + expectConfig := kubeauthenticator.Config{ + APIAudiences: authenticator.Audiences{"http://foo.bar.com"}, Anonymous: false, BasicAuthFile: "/testBasicAuthFile", BootstrapToken: false, @@ -167,6 +169,6 @@ func TestToAuthenticationConfig(t *testing.T) { resultConfig := testOptions.ToAuthenticationConfig() if !reflect.DeepEqual(resultConfig, expectConfig) { - t.Errorf("Got AuthenticationConfig: %v, Expected AuthenticationConfig: %v", resultConfig, expectConfig) + t.Errorf("Got AuthenticationConfig:\n\t%v\nExpected AuthenticationConfig:\n\t%v", resultConfig, expectConfig) } } diff --git a/pkg/kubeapiserver/options/authorization.go b/pkg/kubeapiserver/options/authorization.go index 585e3ecfb8fc8..017aa4bfea39d 100644 --- a/pkg/kubeapiserver/options/authorization.go +++ b/pkg/kubeapiserver/options/authorization.go @@ -109,8 +109,8 @@ func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) { "The duration to cache 'unauthorized' responses from the webhook authorizer.") } -func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(versionedInformerFactory versionedinformers.SharedInformerFactory) authorizer.AuthorizationConfig { - return authorizer.AuthorizationConfig{ +func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(versionedInformerFactory versionedinformers.SharedInformerFactory) authorizer.Config { + return authorizer.Config{ AuthorizationModes: s.Modes, PolicyFile: s.PolicyFile, WebhookConfigFile: s.WebhookConfigFile, diff --git a/pkg/kubeapiserver/util/BUILD b/pkg/kubeapiserver/util/BUILD new file mode 100644 index 0000000000000..6df04e38cd754 --- /dev/null +++ b/pkg/kubeapiserver/util/BUILD @@ -0,0 +1,13 @@ +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/pkg/kubectl/BUILD b/pkg/kubectl/BUILD index 123772dcfce86..fbd9e945497eb 100644 --- a/pkg/kubectl/BUILD +++ b/pkg/kubectl/BUILD @@ -31,6 +31,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff: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", @@ -74,6 +75,7 @@ go_library( "//staging/src/k8s.io/api/autoscaling/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/pkg/kubectl/apply.go b/pkg/kubectl/apply.go index 3c82aee808e65..78447d498cf06 100644 --- a/pkg/kubectl/apply.go +++ b/pkg/kubectl/apply.go @@ -135,7 +135,8 @@ func CreateApplyAnnotation(obj runtime.Object, codec runtime.Encoder) error { return setOriginalConfiguration(obj, modified) } -// Create the annotation used by kubectl apply only when createAnnotation is true +// CreateOrUpdateAnnotation creates the annotation used by +// kubectl apply only when createAnnotation is true // Otherwise, only update the annotation when it already exists func CreateOrUpdateAnnotation(createAnnotation bool, obj runtime.Object, codec runtime.Encoder) error { if createAnnotation { diff --git a/pkg/kubectl/apps/kind_visitor_test.go b/pkg/kubectl/apps/kind_visitor_test.go index 10704b65e9ecc..3d96920c6d904 100644 --- a/pkg/kubectl/apps/kind_visitor_test.go +++ b/pkg/kubectl/apps/kind_visitor_test.go @@ -173,7 +173,7 @@ type TestKindVisitor struct { var _ apps.KindVisitor = &TestKindVisitor{} -func (t *TestKindVisitor) Visit(kind apps.GroupKindElement) { t.visits[kind.Kind] += 1 } +func (t *TestKindVisitor) Visit(kind apps.GroupKindElement) { t.visits[kind.Kind]++ } func (t *TestKindVisitor) VisitDaemonSet(kind apps.GroupKindElement) { t.Visit(kind) } func (t *TestKindVisitor) VisitDeployment(kind apps.GroupKindElement) { t.Visit(kind) } diff --git a/pkg/kubectl/cmd/apiresources/apiresources.go b/pkg/kubectl/cmd/apiresources/apiresources.go index b3f84bae973eb..c44b2537ebec8 100644 --- a/pkg/kubectl/cmd/apiresources/apiresources.go +++ b/pkg/kubectl/cmd/apiresources/apiresources.go @@ -77,7 +77,8 @@ func NewAPIResourceOptions(ioStreams genericclioptions.IOStreams) *ApiResourcesO } } -func NewCmdApiResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { +// NewCmdAPIResources creates the `api-resources` command +func NewCmdAPIResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { o := NewAPIResourceOptions(ioStreams) cmd := &cobra.Command{ diff --git a/pkg/kubectl/cmd/apiresources/apiversions.go b/pkg/kubectl/cmd/apiresources/apiversions.go index 5776086075744..7f7b3ecaac8c9 100644 --- a/pkg/kubectl/cmd/apiresources/apiversions.go +++ b/pkg/kubectl/cmd/apiresources/apiversions.go @@ -48,7 +48,8 @@ func NewApiVersionsOptions(ioStreams genericclioptions.IOStreams) *ApiVersionsOp } } -func NewCmdApiVersions(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { +// NewCmdAPIVersions creates the `api-versions` command +func NewCmdAPIVersions(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { o := NewApiVersionsOptions(ioStreams) cmd := &cobra.Command{ Use: "api-versions", diff --git a/pkg/kubectl/cmd/auth/OWNERS b/pkg/kubectl/cmd/auth/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/pkg/kubectl/cmd/auth/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/pkg/kubectl/cmd/autoscale/autoscale.go b/pkg/kubectl/cmd/autoscale/autoscale.go index f51c93be5f4d7..78b641a509e4b 100644 --- a/pkg/kubectl/cmd/autoscale/autoscale.go +++ b/pkg/kubectl/cmd/autoscale/autoscale.go @@ -159,7 +159,7 @@ func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args CPUPercent: o.CpuPercent, ScaleRefName: name, ScaleRefKind: mapping.GroupVersionKind.Kind, - ScaleRefApiVersion: mapping.GroupVersionKind.GroupVersion().String(), + ScaleRefAPIVersion: mapping.GroupVersionKind.GroupVersion().String(), }, nil default: return nil, cmdutil.UsageErrorf(cmd, "Generator %s not supported. ", o.Generator) diff --git a/pkg/kubectl/cmd/certificates/certificates.go b/pkg/kubectl/cmd/certificates/certificates.go index 058796fc8f71e..fabc8d60da7a7 100644 --- a/pkg/kubectl/cmd/certificates/certificates.go +++ b/pkg/kubectl/cmd/certificates/certificates.go @@ -245,7 +245,7 @@ func (options *CertificateOptions) modifyCertificateCondition(builder *resource. } found++ - return options.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), options.Out) + return options.PrintObj(info.Object, options.Out) }) if found == 0 { fmt.Fprintf(options.Out, "No resources found\n") diff --git a/pkg/kubectl/cmd/cmd.go b/pkg/kubectl/cmd/cmd.go index 43a541ecc9fe7..c10116a17f2c1 100644 --- a/pkg/kubectl/cmd/cmd.go +++ b/pkg/kubectl/cmd/cmd.go @@ -284,7 +284,7 @@ __custom_func() { ) var ( - bash_completion_flags = map[string]string{ + bashCompletionFlags = map[string]string{ "namespace": "__kubectl_get_resource_namespace", "context": "__kubectl_config_get_contexts", "cluster": "__kubectl_config_get_clusters", @@ -292,10 +292,12 @@ var ( } ) +// NewDefaultKubectlCommand creates the `kubectl` command with default arguments func NewDefaultKubectlCommand() *cobra.Command { return NewDefaultKubectlCommandWithArgs(&defaultPluginHandler{}, os.Args, os.Stdin, os.Stdout, os.Stderr) } +// NewDefaultKubectlCommandWithArgs creates the `kubectl` command with arguments func NewDefaultKubectlCommandWithArgs(pluginHandler PluginHandler, args []string, in io.Reader, out, errout io.Writer) *cobra.Command { cmd := NewKubectlCommand(in, out, errout) @@ -528,7 +530,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command { templates.ActsAsRootCommand(cmds, filters, groups...) - for name, completion := range bash_completion_flags { + for name, completion := range bashCompletionFlags { if cmds.Flag(name) != nil { if cmds.Flag(name).Annotations == nil { cmds.Flag(name).Annotations = map[string][]string{} @@ -544,8 +546,8 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command { cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams)) cmds.AddCommand(plugin.NewCmdPlugin(f, ioStreams)) cmds.AddCommand(version.NewCmdVersion(f, ioStreams)) - cmds.AddCommand(apiresources.NewCmdApiVersions(f, ioStreams)) - cmds.AddCommand(apiresources.NewCmdApiResources(f, ioStreams)) + cmds.AddCommand(apiresources.NewCmdAPIVersions(f, ioStreams)) + cmds.AddCommand(apiresources.NewCmdAPIResources(f, ioStreams)) cmds.AddCommand(options.NewCmdOptions(ioStreams.Out)) return cmds diff --git a/pkg/kubectl/cmd/drain/drain.go b/pkg/kubectl/cmd/drain/drain.go index 86c8e36f08506..536b3f2a07608 100644 --- a/pkg/kubectl/cmd/drain/drain.go +++ b/pkg/kubectl/cmd/drain/drain.go @@ -160,9 +160,9 @@ var ( Drain node in preparation for maintenance. The given node will be marked unschedulable to prevent new pods from arriving. - 'drain' evicts the pods if the APIServer supports eviction - (http://kubernetes.io/docs/admin/disruptions/). Otherwise, it will use normal DELETE - to delete the pods. + 'drain' evicts the pods if the APIServer supports + [eviction](http://kubernetes.io/docs/admin/disruptions/). Otherwise, it will use normal + DELETE to delete the pods. The 'drain' evicts or deletes all pods except mirror pods (which cannot be deleted through the API server). If there are DaemonSet-managed pods, drain will not proceed without --ignore-daemonsets, and regardless it will not delete any @@ -748,7 +748,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Fprintf(o.ErrOut, "error: %v\n", err) continue } - printObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out) + printObj(nodeInfo.Object, o.Out) } else { if !o.DryRun { helper := resource.NewHelper(o.restClient, nodeInfo.Mapping) @@ -774,7 +774,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Fprintf(o.ErrOut, "%v\n", err) continue } - printObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out) + printObj(nodeInfo.Object, o.Out) } } else { printObj, err := o.ToPrinter("skipped") @@ -782,7 +782,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Fprintf(o.ErrOut, "%v\n", err) continue } - printObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out) + printObj(nodeInfo.Object, o.Out) } } diff --git a/pkg/kubectl/cmd/logs/logs.go b/pkg/kubectl/cmd/logs/logs.go index 8ba240a950d1f..5f8f3162b19b2 100644 --- a/pkg/kubectl/cmd/logs/logs.go +++ b/pkg/kubectl/cmd/logs/logs.go @@ -181,7 +181,7 @@ func (o *LogsOptions) ToLogOptions() (*corev1.PodLogOptions, error) { logOptions.SinceSeconds = &sec } - if len(o.Selector) > 0 && o.Tail != -1 { + if len(o.Selector) > 0 && o.Tail == -1 { logOptions.TailLines = &selectorTail } else if o.Tail != -1 { logOptions.TailLines = &o.Tail diff --git a/pkg/kubectl/cmd/plugin/BUILD b/pkg/kubectl/cmd/plugin/BUILD index 88174ca29aa13..fb6091de39533 100644 --- a/pkg/kubectl/cmd/plugin/BUILD +++ b/pkg/kubectl/cmd/plugin/BUILD @@ -9,7 +9,6 @@ go_library( "//pkg/kubectl/cmd/util:go_default_library", "//pkg/kubectl/util/i18n:go_default_library", "//pkg/kubectl/util/templates:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", ], diff --git a/pkg/kubectl/cmd/plugin/plugin.go b/pkg/kubectl/cmd/plugin/plugin.go index 71b11d697e419..528ede0e70ca6 100644 --- a/pkg/kubectl/cmd/plugin/plugin.go +++ b/pkg/kubectl/cmd/plugin/plugin.go @@ -17,6 +17,7 @@ limitations under the License. package plugin import ( + "bytes" "fmt" "io/ioutil" "os" @@ -26,7 +27,6 @@ import ( "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/util/sets" "k8s.io/cli-runtime/pkg/genericclioptions" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/util/i18n" @@ -108,11 +108,12 @@ func (o *PluginListOptions) Run() error { pluginsFound := false isFirstFile := true + pluginErrors := []error{} pluginWarnings := 0 - paths := sets.NewString(filepath.SplitList(os.Getenv(path))...) - for _, dir := range paths.List() { + for _, dir := range filepath.SplitList(os.Getenv(path)) { files, err := ioutil.ReadDir(dir) if err != nil { + pluginErrors = append(pluginErrors, fmt.Errorf("error: unable to read directory %q in your PATH: %v", dir, err)) continue } @@ -146,15 +147,23 @@ func (o *PluginListOptions) Run() error { } if !pluginsFound { - return fmt.Errorf("error: unable to find any kubectl plugins in your PATH") + pluginErrors = append(pluginErrors, fmt.Errorf("error: unable to find any kubectl plugins in your PATH")) } if pluginWarnings > 0 { - fmt.Fprintln(o.ErrOut) if pluginWarnings == 1 { - return fmt.Errorf("one plugin warning was found") + pluginErrors = append(pluginErrors, fmt.Errorf("error: one plugin warning was found")) + } else { + pluginErrors = append(pluginErrors, fmt.Errorf("error: %v plugin warnings were found", pluginWarnings)) + } + } + if len(pluginErrors) > 0 { + fmt.Fprintln(o.ErrOut) + errs := bytes.NewBuffer(nil) + for _, e := range pluginErrors { + fmt.Fprintln(errs, e) } - return fmt.Errorf("%v plugin warnings were found", pluginWarnings) + return fmt.Errorf("%s", errs.String()) } return nil diff --git a/pkg/kubectl/cmd/rollingupdate/rollingupdate.go b/pkg/kubectl/cmd/rollingupdate/rollingupdate.go index 2ed243f0cd243..4947e72030865 100644 --- a/pkg/kubectl/cmd/rollingupdate/rollingupdate.go +++ b/pkg/kubectl/cmd/rollingupdate/rollingupdate.go @@ -403,10 +403,10 @@ func (o *RollingUpdateOptions) Run() error { if err != nil { return err } - if err := printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(oldRc, nil), oldRcData); err != nil { + if err := printer.PrintObj(oldRc, oldRcData); err != nil { return err } - if err := printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(newRc, nil), newRcData); err != nil { + if err := printer.PrintObj(newRc, newRcData); err != nil { return err } } @@ -455,7 +455,7 @@ func (o *RollingUpdateOptions) Run() error { if err != nil { return err } - return printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(newRc, nil), o.Out) + return printer.PrintObj(newRc, o.Out) } func findNewName(args []string, oldRc *corev1.ReplicationController) string { diff --git a/pkg/kubectl/cmd/rollout/rollout_history.go b/pkg/kubectl/cmd/rollout/rollout_history.go index 0fbe08cced50c..009c8d76ca4e4 100644 --- a/pkg/kubectl/cmd/rollout/rollout_history.go +++ b/pkg/kubectl/cmd/rollout/rollout_history.go @@ -168,6 +168,6 @@ func (o *RolloutHistoryOptions) Run() error { return err } - return printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) + return printer.PrintObj(info.Object, o.Out) }) } diff --git a/pkg/kubectl/cmd/rollout/rollout_pause.go b/pkg/kubectl/cmd/rollout/rollout_pause.go index 0cb82a5d61760..70c5af4a69806 100644 --- a/pkg/kubectl/cmd/rollout/rollout_pause.go +++ b/pkg/kubectl/cmd/rollout/rollout_pause.go @@ -164,7 +164,7 @@ func (o PauseOptions) RunPause() error { allErrs = append(allErrs, err) continue } - if err = printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil { + if err = printer.PrintObj(info.Object, o.Out); err != nil { allErrs = append(allErrs, err) } continue @@ -182,7 +182,7 @@ func (o PauseOptions) RunPause() error { allErrs = append(allErrs, err) continue } - if err = printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil { + if err = printer.PrintObj(info.Object, o.Out); err != nil { allErrs = append(allErrs, err) } } diff --git a/pkg/kubectl/cmd/rollout/rollout_resume.go b/pkg/kubectl/cmd/rollout/rollout_resume.go index 8626d8ec15aeb..e97c807173c0f 100644 --- a/pkg/kubectl/cmd/rollout/rollout_resume.go +++ b/pkg/kubectl/cmd/rollout/rollout_resume.go @@ -167,7 +167,7 @@ func (o ResumeOptions) RunResume() error { allErrs = append(allErrs, err) continue } - if err = printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil { + if err = printer.PrintObj(info.Object, o.Out); err != nil { allErrs = append(allErrs, err) } continue @@ -185,7 +185,7 @@ func (o ResumeOptions) RunResume() error { allErrs = append(allErrs, err) continue } - if err = printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil { + if err = printer.PrintObj(info.Object, o.Out); err != nil { allErrs = append(allErrs, err) } } diff --git a/pkg/kubectl/cmd/rollout/rollout_undo.go b/pkg/kubectl/cmd/rollout/rollout_undo.go index 690a7d340b8f1..2ab7a0288713e 100644 --- a/pkg/kubectl/cmd/rollout/rollout_undo.go +++ b/pkg/kubectl/cmd/rollout/rollout_undo.go @@ -162,7 +162,7 @@ func (o *UndoOptions) RunUndo() error { return err } - return printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) + return printer.PrintObj(info.Object, o.Out) }) return err diff --git a/pkg/kubectl/cmd/run/run.go b/pkg/kubectl/cmd/run/run.go index 87dfc6e5b4ef0..d8da7818361d9 100644 --- a/pkg/kubectl/cmd/run/run.go +++ b/pkg/kubectl/cmd/run/run.go @@ -339,7 +339,7 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e // the only supported on a route to simple kubectl run which should mimic // docker run if generatorName != generateversioned.RunPodV1GeneratorName { - fmt.Fprintf(o.ErrOut, "kubectl run --generator=%s is DEPRECATED and will be removed in a future version. Use kubectl create instead.\n", generatorName) + fmt.Fprintf(o.ErrOut, "kubectl run --generator=%s is DEPRECATED and will be removed in a future version. Use kubectl run --generator=%s or kubectl create instead.\n", generatorName, generateversioned.RunPodV1GeneratorName) } generators := generateversioned.GeneratorFn("run") @@ -691,7 +691,6 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command return nil, err } } - actualObj = cmdutil.AsDefaultVersionedOrOriginal(actualObj, mapping) return &RunObject{ Object: actualObj, diff --git a/pkg/kubectl/cmd/taint/taint.go b/pkg/kubectl/cmd/taint/taint.go index 96ba761dcce7c..13dbcfeed4e53 100644 --- a/pkg/kubectl/cmd/taint/taint.go +++ b/pkg/kubectl/cmd/taint/taint.go @@ -280,7 +280,6 @@ func (o TaintOptions) RunTaint() error { if err != nil { return err } - outputObj = cmdutil.AsDefaultVersionedOrOriginal(outputObj, mapping) printer, err := o.ToPrinter(operation) if err != nil { diff --git a/pkg/kubectl/cmd/top/top_node.go b/pkg/kubectl/cmd/top/top_node.go index 8250c099d05ec..48e7f48e0c74a 100644 --- a/pkg/kubectl/cmd/top/top_node.go +++ b/pkg/kubectl/cmd/top/top_node.go @@ -106,15 +106,9 @@ func NewCmdTopNode(f cmdutil.Factory, o *TopNodeOptions, streams genericclioptio Long: topNodeLong, Example: topNodeExample, Run: func(cmd *cobra.Command, args []string) { - if err := o.Complete(f, cmd, args); err != nil { - cmdutil.CheckErr(err) - } - if err := o.Validate(); err != nil { - cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err)) - } - if err := o.RunTopNode(); err != nil { - cmdutil.CheckErr(err) - } + cmdutil.CheckErr(o.Complete(f, cmd, args)) + cmdutil.CheckErr(o.Validate()) + cmdutil.CheckErr(o.RunTopNode()) }, Aliases: []string{"nodes", "no"}, } diff --git a/pkg/kubectl/cmd/top/top_pod.go b/pkg/kubectl/cmd/top/top_pod.go index 8ffccc1b4c700..c8f87d558ef67 100644 --- a/pkg/kubectl/cmd/top/top_pod.go +++ b/pkg/kubectl/cmd/top/top_pod.go @@ -95,15 +95,9 @@ func NewCmdTopPod(f cmdutil.Factory, o *TopPodOptions, streams genericclioptions Long: topPodLong, Example: topPodExample, Run: func(cmd *cobra.Command, args []string) { - if err := o.Complete(f, cmd, args); err != nil { - cmdutil.CheckErr(err) - } - if err := o.Validate(); err != nil { - cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err)) - } - if err := o.RunTopPod(); err != nil { - cmdutil.CheckErr(err) - } + cmdutil.CheckErr(o.Complete(f, cmd, args)) + cmdutil.CheckErr(o.Validate()) + cmdutil.CheckErr(o.RunTopPod()) }, Aliases: []string{"pods", "po"}, } diff --git a/pkg/kubectl/cmd/util/BUILD b/pkg/kubectl/cmd/util/BUILD index 936a98459c351..bad60cd16c852 100644 --- a/pkg/kubectl/cmd/util/BUILD +++ b/pkg/kubectl/cmd/util/BUILD @@ -3,7 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ - "conversion.go", "crdfinder.go", "factory.go", "factory_client_access.go", @@ -14,9 +13,9 @@ go_library( importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util", visibility = ["//build/visible_to:pkg_kubectl_cmd_util_CONSUMERS"], deps = [ - "//pkg/api/legacyscheme:go_default_library", "//pkg/kubectl/cmd/util/openapi:go_default_library", "//pkg/kubectl/cmd/util/openapi/validation:go_default_library", + "//pkg/kubectl/scheme:go_default_library", "//pkg/kubectl/util/templates:go_default_library", "//pkg/kubectl/validation:go_default_library", "//pkg/version:go_default_library", @@ -27,6 +26,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library", diff --git a/pkg/kubectl/cmd/util/conversion.go b/pkg/kubectl/cmd/util/conversion.go deleted file mode 100644 index 98b02ee712774..0000000000000 --- a/pkg/kubectl/cmd/util/conversion.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -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 util - -import ( - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/kubernetes/pkg/api/legacyscheme" -) - -// AsDefaultVersionedOrOriginal returns the object as a Go object in the external form if possible (matching the -// group version kind of the mapping if provided, a best guess based on serialization if not provided, or obj if it cannot be converted. -// TODO update call sites to specify the scheme they want on their builder. -func AsDefaultVersionedOrOriginal(obj runtime.Object, mapping *meta.RESTMapping) runtime.Object { - converter := runtime.ObjectConvertor(legacyscheme.Scheme) - groupVersioner := runtime.GroupVersioner(schema.GroupVersions(legacyscheme.Scheme.PrioritizedVersionsAllGroups())) - if mapping != nil { - groupVersioner = mapping.GroupVersionKind.GroupVersion() - } - - if obj, err := converter.ConvertToVersion(obj, groupVersioner); err == nil { - return obj - } - return obj -} diff --git a/pkg/kubectl/cmd/util/kubectl_match_version.go b/pkg/kubectl/cmd/util/kubectl_match_version.go index bf5745c2a6c08..99ba2baeec651 100644 --- a/pkg/kubectl/cmd/util/kubectl_match_version.go +++ b/pkg/kubectl/cmd/util/kubectl_match_version.go @@ -23,12 +23,13 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/discovery" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/version" ) @@ -120,7 +121,10 @@ func setKubernetesDefaults(config *rest.Config) error { config.APIPath = "/api" } if config.NegotiatedSerializer == nil { - config.NegotiatedSerializer = legacyscheme.Codecs + // This codec factory ensures the resources are not converted. Therefore, resources + // will not be round-tripped through internal versions. Defaulting does not happen + // on the client. + config.NegotiatedSerializer = &serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} } return rest.SetKubernetesDefaults(config) } diff --git a/pkg/kubectl/cmd/version/BUILD b/pkg/kubectl/cmd/version/BUILD index 64c3e56952580..4f701db55318d 100644 --- a/pkg/kubectl/cmd/version/BUILD +++ b/pkg/kubectl/cmd/version/BUILD @@ -13,6 +13,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/version:go_default_library", "//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library", "//staging/src/k8s.io/client-go/discovery:go_default_library", + "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//vendor/github.com/ghodss/yaml:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", ], diff --git a/pkg/kubectl/cmd/version/version.go b/pkg/kubectl/cmd/version/version.go index 8682063ead1c2..e0e1c42f9e521 100644 --- a/pkg/kubectl/cmd/version/version.go +++ b/pkg/kubectl/cmd/version/version.go @@ -27,6 +27,7 @@ import ( apimachineryversion "k8s.io/apimachinery/pkg/version" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/discovery" + "k8s.io/client-go/tools/clientcmd" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/templates" @@ -83,7 +84,9 @@ func NewCmdVersion(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *co func (o *VersionOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { var err error o.discoveryClient, err = f.ToDiscoveryClient() - if err != nil { + // if we had an empty rest.Config, continue and just print out client information. + // if we had an error other than being unable to build a rest.Config, fail. + if err != nil && !clientcmd.IsEmptyConfig(err) { return err } return nil @@ -107,7 +110,7 @@ func (o *VersionOptions) Run() error { clientVersion := version.Get() versionInfo.ClientVersion = &clientVersion - if !o.ClientOnly { + if !o.ClientOnly && o.discoveryClient != nil { // Always request fresh data from the server o.discoveryClient.Invalidate() serverVersion, serverErr = o.discoveryClient.ServerVersion() diff --git a/pkg/kubectl/cmd/wait/BUILD b/pkg/kubectl/cmd/wait/BUILD index 3fb123806728c..919e4bd95bccd 100644 --- a/pkg/kubectl/cmd/wait/BUILD +++ b/pkg/kubectl/cmd/wait/BUILD @@ -45,6 +45,7 @@ go_test( embed = [":go_default_library"], deps = [ "//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/pkg/kubectl/cmd/wait/wait.go b/pkg/kubectl/cmd/wait/wait.go index c8f6bfb438f35..c338fdec00d23 100644 --- a/pkg/kubectl/cmd/wait/wait.go +++ b/pkg/kubectl/cmd/wait/wait.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "io" "strings" "time" @@ -145,7 +146,7 @@ func (flags *WaitFlags) ToOptions(args []string) (*WaitOptions, error) { if err != nil { return nil, err } - conditionFn, err := conditionFuncFor(flags.ForCondition) + conditionFn, err := conditionFuncFor(flags.ForCondition, flags.ErrOut) if err != nil { return nil, err } @@ -168,7 +169,7 @@ func (flags *WaitFlags) ToOptions(args []string) (*WaitOptions, error) { return o, nil } -func conditionFuncFor(condition string) (ConditionFunc, error) { +func conditionFuncFor(condition string, errOut io.Writer) (ConditionFunc, error) { if strings.ToLower(condition) == "delete" { return IsDeleted, nil } @@ -183,6 +184,7 @@ func conditionFuncFor(condition string) (ConditionFunc, error) { return ConditionalWait{ conditionName: conditionName, conditionStatus: conditionValue, + errOut: errOut, }.IsConditionMet, nil } @@ -281,7 +283,7 @@ func IsDeleted(info *resource.Info, o *WaitOptions) (runtime.Object, bool, error } ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), o.Timeout) - watchEvent, err := watchtools.UntilWithoutRetry(ctx, objWatch, isDeleted) + watchEvent, err := watchtools.UntilWithoutRetry(ctx, objWatch, Wait{errOut: o.ErrOut}.IsDeleted) cancel() switch { case err == nil: @@ -299,14 +301,33 @@ func IsDeleted(info *resource.Info, o *WaitOptions) (runtime.Object, bool, error } } -func isDeleted(event watch.Event) (bool, error) { - return event.Type == watch.Deleted, nil +// Wait has helper methods for handling watches, including error handling. +type Wait struct { + errOut io.Writer +} + +// IsDeleted returns true if the object is deleted. It prints any errors it encounters. +func (w Wait) IsDeleted(event watch.Event) (bool, error) { + switch event.Type { + case watch.Error: + // keep waiting in the event we see an error - we expect the watch to be closed by + // the server if the error is unrecoverable. + err := apierrors.FromObject(event.Object) + fmt.Fprintf(w.errOut, "error: An error occurred while waiting for the object to be deleted: %v", err) + return false, nil + case watch.Deleted: + return true, nil + default: + return false, nil + } } // ConditionalWait hold information to check an API status condition type ConditionalWait struct { conditionName string conditionStatus string + // errOut is written to if an error occurs + errOut io.Writer } // IsConditionMet is a conditionfunc for waiting on an API condition to be met @@ -389,6 +410,13 @@ func (w ConditionalWait) checkCondition(obj *unstructured.Unstructured) (bool, e } func (w ConditionalWait) isConditionMet(event watch.Event) (bool, error) { + if event.Type == watch.Error { + // keep waiting in the event we see an error - we expect the watch to be closed by + // the server + err := apierrors.FromObject(event.Object) + fmt.Fprintf(w.errOut, "error: An error occurred while waiting for the condition to be satisfied: %v", err) + return false, nil + } if event.Type == watch.Deleted { // this will chain back out, result in another get and an return false back up the chain return false, nil diff --git a/pkg/kubectl/cmd/wait/wait_test.go b/pkg/kubectl/cmd/wait/wait_test.go index 01d510f21a237..ef34dec72ac88 100644 --- a/pkg/kubectl/cmd/wait/wait_test.go +++ b/pkg/kubectl/cmd/wait/wait_test.go @@ -17,6 +17,7 @@ limitations under the License. package wait import ( + "io/ioutil" "testing" "time" @@ -26,6 +27,7 @@ import ( "github.com/davecgh/go-spew/spew" "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -53,6 +55,16 @@ func newUnstructured(apiVersion, kind, namespace, name string) *unstructured.Uns } } +func newUnstructuredStatus(status *metav1.Status) runtime.Unstructured { + obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(status) + if err != nil { + panic(err) + } + return &unstructured.Unstructured{ + Object: obj, + } +} + func addCondition(in *unstructured.Unstructured, name, status string) *unstructured.Unstructured { conditions, _, _ := unstructured.NestedSlice(in.Object, "status", "conditions") conditions = append(conditions, map[string]interface{}{ @@ -286,6 +298,61 @@ func TestWaitForDeletion(t *testing.T) { } }, }, + { + name: "ignores watch error", + infos: []*resource.Info{ + { + Mapping: &meta.RESTMapping{ + Resource: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "theresource"}, + }, + Name: "name-foo", + Namespace: "ns-foo", + }, + }, + fakeClient: func() *dynamicfakeclient.FakeDynamicClient { + fakeClient := dynamicfakeclient.NewSimpleDynamicClient(scheme) + fakeClient.PrependReactor("get", "theresource", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) { + return true, newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), nil + }) + count := 0 + fakeClient.PrependWatchReactor("theresource", func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) { + fakeWatch := watch.NewRaceFreeFake() + if count == 0 { + fakeWatch.Error(newUnstructuredStatus(&metav1.Status{ + TypeMeta: metav1.TypeMeta{Kind: "Status", APIVersion: "v1"}, + Status: "Failure", + Code: 500, + Message: "Bad", + })) + fakeWatch.Stop() + } else { + fakeWatch.Action(watch.Deleted, newUnstructured("group/version", "TheKind", "ns-foo", "name-foo")) + } + count++ + return true, fakeWatch, nil + }) + return fakeClient + }, + timeout: 10 * time.Second, + + validateActions: func(t *testing.T, actions []clienttesting.Action) { + if len(actions) != 4 { + t.Fatal(spew.Sdump(actions)) + } + if !actions[0].Matches("get", "theresource") || actions[0].(clienttesting.GetAction).GetName() != "name-foo" { + t.Error(spew.Sdump(actions)) + } + if !actions[1].Matches("watch", "theresource") { + t.Error(spew.Sdump(actions)) + } + if !actions[2].Matches("get", "theresource") || actions[2].(clienttesting.GetAction).GetName() != "name-foo" { + t.Error(spew.Sdump(actions)) + } + if !actions[3].Matches("watch", "theresource") { + t.Error(spew.Sdump(actions)) + } + }, + }, } for _, test := range tests { @@ -544,6 +611,64 @@ func TestWaitForCondition(t *testing.T) { } }, }, + { + name: "ignores watch error", + infos: []*resource.Info{ + { + Mapping: &meta.RESTMapping{ + Resource: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "theresource"}, + }, + Name: "name-foo", + Namespace: "ns-foo", + }, + }, + fakeClient: func() *dynamicfakeclient.FakeDynamicClient { + fakeClient := dynamicfakeclient.NewSimpleDynamicClient(scheme) + fakeClient.PrependReactor("get", "theresource", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) { + return true, newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), nil + }) + count := 0 + fakeClient.PrependWatchReactor("theresource", func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) { + fakeWatch := watch.NewRaceFreeFake() + if count == 0 { + fakeWatch.Error(newUnstructuredStatus(&metav1.Status{ + TypeMeta: metav1.TypeMeta{Kind: "Status", APIVersion: "v1"}, + Status: "Failure", + Code: 500, + Message: "Bad", + })) + fakeWatch.Stop() + } else { + fakeWatch.Action(watch.Modified, addCondition( + newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), + "the-condition", "status-value", + )) + } + count++ + return true, fakeWatch, nil + }) + return fakeClient + }, + timeout: 10 * time.Second, + + validateActions: func(t *testing.T, actions []clienttesting.Action) { + if len(actions) != 4 { + t.Fatal(spew.Sdump(actions)) + } + if !actions[0].Matches("get", "theresource") || actions[0].(clienttesting.GetAction).GetName() != "name-foo" { + t.Error(spew.Sdump(actions)) + } + if !actions[1].Matches("watch", "theresource") { + t.Error(spew.Sdump(actions)) + } + if !actions[2].Matches("get", "theresource") || actions[2].(clienttesting.GetAction).GetName() != "name-foo" { + t.Error(spew.Sdump(actions)) + } + if !actions[3].Matches("watch", "theresource") { + t.Error(spew.Sdump(actions)) + } + }, + }, } for _, test := range tests { @@ -555,7 +680,7 @@ func TestWaitForCondition(t *testing.T) { Timeout: test.timeout, Printer: printers.NewDiscardingPrinter(), - ConditionFn: ConditionalWait{conditionName: "the-condition", conditionStatus: "status-value"}.IsConditionMet, + ConditionFn: ConditionalWait{conditionName: "the-condition", conditionStatus: "status-value", errOut: ioutil.Discard}.IsConditionMet, IOStreams: genericclioptions.NewTestIOStreamsDiscard(), } err := o.RunWait() diff --git a/pkg/kubectl/explain/BUILD b/pkg/kubectl/explain/BUILD index 14815dad96a67..b70f8476cf40b 100644 --- a/pkg/kubectl/explain/BUILD +++ b/pkg/kubectl/explain/BUILD @@ -46,7 +46,10 @@ go_test( "recursive_fields_printer_test.go", "typename_test.go", ], - data = ["test-swagger.json"], + data = [ + "test-recursive-swagger.json", + "test-swagger.json", + ], embed = [":go_default_library"], deps = [ "//pkg/kubectl/cmd/util/openapi/testing:go_default_library", diff --git a/pkg/kubectl/explain/recursive_fields_printer.go b/pkg/kubectl/explain/recursive_fields_printer.go index 95638c85adfe5..6429a73264eb6 100644 --- a/pkg/kubectl/explain/recursive_fields_printer.go +++ b/pkg/kubectl/explain/recursive_fields_printer.go @@ -30,6 +30,7 @@ type recursiveFieldsPrinter struct { var _ proto.SchemaVisitor = &recursiveFieldsPrinter{} var _ fieldsPrinter = &recursiveFieldsPrinter{} +var visitedReferences = map[string]struct{}{} // VisitArray is just a passthrough. func (f *recursiveFieldsPrinter) VisitArray(a *proto.Array) { @@ -64,7 +65,12 @@ func (f *recursiveFieldsPrinter) VisitPrimitive(p *proto.Primitive) { // VisitReference is just a passthrough. func (f *recursiveFieldsPrinter) VisitReference(r proto.Reference) { + if _, ok := visitedReferences[r.Reference()]; ok { + return + } + visitedReferences[r.Reference()] = struct{}{} r.SubSchema().Accept(f) + delete(visitedReferences, r.Reference()) } // PrintFields will recursively print all the fields for the given diff --git a/pkg/kubectl/explain/recursive_fields_printer_test.go b/pkg/kubectl/explain/recursive_fields_printer_test.go index 75571ab4ee5b3..9a93668817448 100644 --- a/pkg/kubectl/explain/recursive_fields_printer_test.go +++ b/pkg/kubectl/explain/recursive_fields_printer_test.go @@ -21,6 +21,7 @@ import ( "testing" "k8s.io/apimachinery/pkg/runtime/schema" + tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing" ) func TestRecursiveFields(t *testing.T) { @@ -59,3 +60,42 @@ field2 <[]map[string]string> t.Errorf("Got:\n%v\nWant:\n%v\n", buf.String(), want) } } + +func TestRecursiveFieldsWithSelfReferenceObjects(t *testing.T) { + var resources = tst.NewFakeResources("test-recursive-swagger.json") + schema := resources.LookupResource(schema.GroupVersionKind{ + Group: "", + Version: "v2", + Kind: "OneKind", + }) + if schema == nil { + t.Fatal("Couldn't find schema v2.OneKind") + } + + want := `field1 + referencefield + referencesarray <[]Object> +field2 + reference + referencefield + referencesarray <[]Object> + string +` + + buf := bytes.Buffer{} + f := Formatter{ + Writer: &buf, + Wrap: 80, + } + s, err := LookupSchemaForField(schema, []string{}) + if err != nil { + t.Fatalf("Invalid path %v: %v", []string{}, err) + } + if err := (fieldsPrinterBuilder{Recursive: true}).BuildFieldsPrinter(&f).PrintFields(s); err != nil { + t.Fatalf("Failed to print fields: %v", err) + } + got := buf.String() + if got != want { + t.Errorf("Got:\n%v\nWant:\n%v\n", buf.String(), want) + } +} diff --git a/pkg/kubectl/explain/test-recursive-swagger.json b/pkg/kubectl/explain/test-recursive-swagger.json new file mode 100644 index 0000000000000..1ae79855d3936 --- /dev/null +++ b/pkg/kubectl/explain/test-recursive-swagger.json @@ -0,0 +1,63 @@ +{ + "swagger": "2.0", + "info": { + "title": "Kubernetes", + "version": "v1.9.0" + }, + "paths": {}, + "definitions": { + "OneKind": { + "description": "OneKind has a short description", + "required": [ + "field1" + ], + "properties": { + "field1": { + "description": "This is first reference field", + "$ref": "#/definitions/ReferenceKind" + }, + "field2": { + "description": "This is other kind field with string and reference", + "$ref": "#/definitions/OtherKind" + } + }, + "x-kubernetes-group-version-kind": [ + { + "group": "", + "kind": "OneKind", + "version": "v2" + } + ] + }, + "ReferenceKind": { + "description": "This is reference Kind", + "properties": { + "referencefield": { + "description": "This is reference to itself.", + "$ref": "#/definitions/ReferenceKind" + }, + "referencesarray": { + "description": "This is an array of references", + "type": "array", + "items": { + "description": "This is reference object", + "$ref": "#/definitions/ReferenceKind" + } + } + } + }, + "OtherKind": { + "description": "This is other kind with string and reference fields", + "properties": { + "string": { + "description": "This string must be a string", + "type": "string" + }, + "reference": { + "description": "This is reference field.", + "$ref": "#/definitions/ReferenceKind" + } + } + } + } +} diff --git a/pkg/kubectl/generate/generate.go b/pkg/kubectl/generate/generate.go index 65abaafd82704..1915be8cb9617 100644 --- a/pkg/kubectl/generate/generate.go +++ b/pkg/kubectl/generate/generate.go @@ -102,7 +102,7 @@ func AnnotateFlags(cmd *cobra.Command, generators map[string]Generator) { } } -// EnsureFlagsValid ensures that no invalid flags are being used against a +// EnsureFlagsValid ensures that no invalid flags are being used against a func EnsureFlagsValid(cmd *cobra.Command, generators map[string]Generator, generatorInUse string) error { AnnotateFlags(cmd, generators) diff --git a/pkg/kubectl/generate/versioned/autoscale.go b/pkg/kubectl/generate/versioned/autoscale.go index 790b07e5819d1..7cb8dbbc50d62 100644 --- a/pkg/kubectl/generate/versioned/autoscale.go +++ b/pkg/kubectl/generate/versioned/autoscale.go @@ -25,12 +25,12 @@ import ( "k8s.io/kubernetes/pkg/kubectl/generate" ) -// HorizontalPodAutoscalerV1Generator supports stable generation of a horizontal pod autoscaler. +// HorizontalPodAutoscalerGeneratorV1 supports stable generation of a horizontal pod autoscaler. type HorizontalPodAutoscalerGeneratorV1 struct { Name string ScaleRefKind string ScaleRefName string - ScaleRefApiVersion string + ScaleRefAPIVersion string MinReplicas int32 MaxReplicas int32 CPUPercent int32 @@ -53,7 +53,7 @@ func (s *HorizontalPodAutoscalerGeneratorV1) StructuredGenerate() (runtime.Objec ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{ Kind: s.ScaleRefKind, Name: s.ScaleRefName, - APIVersion: s.ScaleRefApiVersion, + APIVersion: s.ScaleRefAPIVersion, }, MaxReplicas: s.MaxReplicas, }, diff --git a/pkg/kubectl/generate/versioned/autoscale_test.go b/pkg/kubectl/generate/versioned/autoscale_test.go index 49b76b5b3642b..c5f8ae74d4587 100644 --- a/pkg/kubectl/generate/versioned/autoscale_test.go +++ b/pkg/kubectl/generate/versioned/autoscale_test.go @@ -31,7 +31,7 @@ func TestHPAGenerate(t *testing.T) { HPAName string scaleRefKind string scaleRefName string - scaleRefApiVersion string + scaleRefAPIVersion string minReplicas int32 maxReplicas int32 CPUPercent int32 @@ -46,7 +46,7 @@ func TestHPAGenerate(t *testing.T) { CPUPercent: 80, scaleRefKind: "kind", scaleRefName: "name", - scaleRefApiVersion: "apiVersion", + scaleRefAPIVersion: "apiVersion", expected: &autoscalingv1.HorizontalPodAutoscaler{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", @@ -68,7 +68,7 @@ func TestHPAGenerate(t *testing.T) { name: "'name' is a required parameter", scaleRefKind: "kind", scaleRefName: "name", - scaleRefApiVersion: "apiVersion", + scaleRefAPIVersion: "apiVersion", expectErr: true, }, { @@ -76,7 +76,7 @@ func TestHPAGenerate(t *testing.T) { HPAName: "foo", scaleRefKind: "kind", scaleRefName: "name", - scaleRefApiVersion: "apiVersion", + scaleRefAPIVersion: "apiVersion", expectErr: true, }, { @@ -86,7 +86,7 @@ func TestHPAGenerate(t *testing.T) { maxReplicas: 1, scaleRefKind: "kind", scaleRefName: "name", - scaleRefApiVersion: "apiVersion", + scaleRefAPIVersion: "apiVersion", expectErr: true, }, { @@ -96,7 +96,7 @@ func TestHPAGenerate(t *testing.T) { maxReplicas: -10, scaleRefKind: "kind", scaleRefName: "name", - scaleRefApiVersion: "apiVersion", + scaleRefAPIVersion: "apiVersion", expectErr: true, }, } @@ -107,7 +107,7 @@ func TestHPAGenerate(t *testing.T) { Name: tt.HPAName, ScaleRefKind: tt.scaleRefKind, ScaleRefName: tt.scaleRefName, - ScaleRefApiVersion: tt.scaleRefApiVersion, + ScaleRefAPIVersion: tt.scaleRefAPIVersion, MinReplicas: tt.minReplicas, MaxReplicas: tt.maxReplicas, CPUPercent: tt.CPUPercent, diff --git a/pkg/kubectl/generate/versioned/deployment.go b/pkg/kubectl/generate/versioned/deployment.go index d5b23eba8d320..4b2b24d575dcc 100644 --- a/pkg/kubectl/generate/versioned/deployment.go +++ b/pkg/kubectl/generate/versioned/deployment.go @@ -29,7 +29,7 @@ import ( "k8s.io/kubernetes/pkg/kubectl/generate" ) -// BaseDeploymentGenerator: implement the common functionality of +// BaseDeploymentGenerator implements the common functionality of // DeploymentBasicGeneratorV1, DeploymentBasicAppsGeneratorV1Beta1 and DeploymentBasicAppsGeneratorV1. To reduce // confusion, it's best to keep this struct in the same file as those // generators. diff --git a/pkg/kubectl/generate/versioned/secret.go b/pkg/kubectl/generate/versioned/secret.go index bca194139fc66..02b27519f4560 100644 --- a/pkg/kubectl/generate/versioned/secret.go +++ b/pkg/kubectl/generate/versioned/secret.go @@ -205,7 +205,7 @@ func handleFromFileSources(secret *v1.Secret, fileSources []string) error { } if info.IsDir() { if strings.Contains(fileSource, "=") { - return fmt.Errorf("cannot give a key name for a directory path.") + return fmt.Errorf("cannot give a key name for a directory path") } fileList, err := ioutil.ReadDir(filePath) if err != nil { @@ -265,7 +265,7 @@ func addKeyFromLiteralToSecret(secret *v1.Secret, keyName string, data []byte) e } if _, entryExists := secret.Data[keyName]; entryExists { - return fmt.Errorf("cannot add key %s, another key by that name already exists: %v.", keyName, secret.Data) + return fmt.Errorf("cannot add key %s, another key by that name already exists: %v", keyName, secret.Data) } secret.Data[keyName] = data return nil diff --git a/pkg/kubectl/generate/versioned/secret_for_docker_registry.go b/pkg/kubectl/generate/versioned/secret_for_docker_registry.go index e8996b8f2c662..db9d38448c278 100644 --- a/pkg/kubectl/generate/versioned/secret_for_docker_registry.go +++ b/pkg/kubectl/generate/versioned/secret_for_docker_registry.go @@ -97,11 +97,11 @@ func (s SecretForDockerRegistryGeneratorV1) StructuredGenerate() (runtime.Object } } if len(s.FileSources) == 0 { - dockercfgJsonContent, err := handleDockerCfgJsonContent(s.Username, s.Password, s.Email, s.Server) + dockercfgJSONContent, err := handleDockerCfgJSONContent(s.Username, s.Password, s.Email, s.Server) if err != nil { return nil, err } - secret.Data[v1.DockerConfigJsonKey] = dockercfgJsonContent + secret.Data[v1.DockerConfigJsonKey] = dockercfgJSONContent } if s.AppendHash { h, err := hash.SecretHash(secret) @@ -146,24 +146,24 @@ func (s SecretForDockerRegistryGeneratorV1) validate() error { return nil } -// handleDockerCfgJsonContent serializes a ~/.docker/config.json file -func handleDockerCfgJsonContent(username, password, email, server string) ([]byte, error) { +// handleDockerCfgJSONContent serializes a ~/.docker/config.json file +func handleDockerCfgJSONContent(username, password, email, server string) ([]byte, error) { dockercfgAuth := DockerConfigEntry{ Username: username, Password: password, Email: email, } - dockerCfgJson := DockerConfigJson{ + dockerCfgJSON := DockerConfigJSON{ Auths: map[string]DockerConfigEntry{server: dockercfgAuth}, } - return json.Marshal(dockerCfgJson) + return json.Marshal(dockerCfgJSON) } -// DockerConfigJson represents a local docker auth config file +// DockerConfigJSON represents a local docker auth config file // for pulling images. -type DockerConfigJson struct { +type DockerConfigJSON struct { Auths DockerConfig `json:"auths"` // +optional HttpHeaders map[string]string `json:"HttpHeaders,omitempty"` diff --git a/pkg/kubectl/generate/versioned/secret_for_docker_registry_test.go b/pkg/kubectl/generate/versioned/secret_for_docker_registry_test.go index 3cb73f68f49c8..2b90e186ef902 100644 --- a/pkg/kubectl/generate/versioned/secret_for_docker_registry_test.go +++ b/pkg/kubectl/generate/versioned/secret_for_docker_registry_test.go @@ -26,11 +26,11 @@ import ( func TestSecretForDockerRegistryGenerate(t *testing.T) { username, password, email, server := "test-user", "test-password", "test-user@example.org", "https://index.docker.io/v1/" - secretData, err := handleDockerCfgJsonContent(username, password, email, server) + secretData, err := handleDockerCfgJSONContent(username, password, email, server) if err != nil { t.Errorf("unexpected error: %v", err) } - secretDataNoEmail, err := handleDockerCfgJsonContent(username, password, "", server) + secretDataNoEmail, err := handleDockerCfgJSONContent(username, password, "", server) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/pkg/kubectl/generate/versioned/service.go b/pkg/kubectl/generate/versioned/service.go index bea484098e6fc..39d084bf9ff83 100644 --- a/pkg/kubectl/generate/versioned/service.go +++ b/pkg/kubectl/generate/versioned/service.go @@ -88,7 +88,7 @@ func generateService(genericParams map[string]interface{}) (runtime.Object, erro } selectorString, found := params["selector"] if !found || len(selectorString) == 0 { - return nil, fmt.Errorf("'selector' is a required parameter.") + return nil, fmt.Errorf("'selector' is a required parameter") } selector, err := generate.ParseLabels(selectorString) if err != nil { @@ -108,7 +108,7 @@ func generateService(genericParams map[string]interface{}) (runtime.Object, erro if !found || len(name) == 0 { name, found = params["default-name"] if !found || len(name) == 0 { - return nil, fmt.Errorf("'name' is a required parameter.") + return nil, fmt.Errorf("'name' is a required parameter") } } @@ -136,7 +136,7 @@ func generateService(genericParams map[string]interface{}) (runtime.Object, erro if portString, found = params["ports"]; !found { portString, found = params["port"] if !found && !isHeadlessService { - return nil, fmt.Errorf("'ports' or 'port' is a required parameter.") + return nil, fmt.Errorf("'ports' or 'port' is a required parameter") } } diff --git a/pkg/kubectl/metricsutil/metrics_client.go b/pkg/kubectl/metricsutil/metrics_client.go index 7b7c13d0b88a6..73399b233b0fb 100644 --- a/pkg/kubectl/metricsutil/metrics_client.go +++ b/pkg/kubectl/metricsutil/metrics_client.go @@ -64,7 +64,7 @@ func NewHeapsterMetricsClient(svcClient corev1client.ServicesGetter, namespace, } } -func podMetricsUrl(namespace string, name string) (string, error) { +func podMetricsURL(namespace string, name string) (string, error) { if namespace == metav1.NamespaceAll { return fmt.Sprintf("%s/pods", metricsRoot), nil } @@ -83,7 +83,7 @@ func podMetricsUrl(namespace string, name string) (string, error) { return fmt.Sprintf("%s/namespaces/%s/pods/%s", metricsRoot, namespace, name), nil } -func nodeMetricsUrl(name string) (string, error) { +func nodeMetricsURL(name string) (string, error) { if len(name) > 0 { errs := validation.NameIsDNSSubdomain(name, false) if len(errs) > 0 { @@ -96,7 +96,7 @@ func nodeMetricsUrl(name string) (string, error) { func (cli *HeapsterMetricsClient) GetNodeMetrics(nodeName string, selector string) (*metricsapi.NodeMetricsList, error) { params := map[string]string{"labelSelector": selector} - path, err := nodeMetricsUrl(nodeName) + path, err := nodeMetricsURL(nodeName) if err != nil { return nil, err } @@ -130,7 +130,7 @@ func (cli *HeapsterMetricsClient) GetPodMetrics(namespace string, podName string if allNamespaces { namespace = metav1.NamespaceAll } - path, err := podMetricsUrl(namespace, podName) + path, err := podMetricsURL(namespace, podName) if err != nil { return nil, err } diff --git a/pkg/kubectl/polymorphichelpers/mapbasedselectorforobject.go b/pkg/kubectl/polymorphichelpers/mapbasedselectorforobject.go index 422302629e5ef..3548edf23908c 100644 --- a/pkg/kubectl/polymorphichelpers/mapbasedselectorforobject.go +++ b/pkg/kubectl/polymorphichelpers/mapbasedselectorforobject.go @@ -50,27 +50,52 @@ func mapBasedSelectorForObject(object runtime.Object) (string, error) { return generate.MakeLabels(t.Spec.Selector), nil case *extensionsv1beta1.Deployment: - // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals - // operator, DoubleEquals operator and In operator with only one element in the set. - if len(t.Spec.Selector.MatchExpressions) > 0 { - return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions) + // "extensions" deployments use pod template labels if selector is not set. + var labels map[string]string + if t.Spec.Selector != nil { + // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals + // operator, DoubleEquals operator and In operator with only one element in the set. + if len(t.Spec.Selector.MatchExpressions) > 0 { + return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions) + } + labels = t.Spec.Selector.MatchLabels + } else { + labels = t.Spec.Template.Labels } - return generate.MakeLabels(t.Spec.Selector.MatchLabels), nil + if len(labels) == 0 { + return "", fmt.Errorf("the deployment has no labels or selectors and cannot be exposed") + } + return generate.MakeLabels(labels), nil + case *appsv1.Deployment: + // "apps" deployments must have the selector set. + if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 { + return "", fmt.Errorf("invalid deployment: no selectors, therefore cannot be exposed") + } // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals // operator, DoubleEquals operator and In operator with only one element in the set. if len(t.Spec.Selector.MatchExpressions) > 0 { return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions) } return generate.MakeLabels(t.Spec.Selector.MatchLabels), nil + case *appsv1beta2.Deployment: + // "apps" deployments must have the selector set. + if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 { + return "", fmt.Errorf("invalid deployment: no selectors, therefore cannot be exposed") + } // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals // operator, DoubleEquals operator and In operator with only one element in the set. if len(t.Spec.Selector.MatchExpressions) > 0 { return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions) } return generate.MakeLabels(t.Spec.Selector.MatchLabels), nil + case *appsv1beta1.Deployment: + // "apps" deployments must have the selector set. + if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 { + return "", fmt.Errorf("invalid deployment: no selectors, therefore cannot be exposed") + } // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals // operator, DoubleEquals operator and In operator with only one element in the set. if len(t.Spec.Selector.MatchExpressions) > 0 { @@ -79,20 +104,40 @@ func mapBasedSelectorForObject(object runtime.Object) (string, error) { return generate.MakeLabels(t.Spec.Selector.MatchLabels), nil case *extensionsv1beta1.ReplicaSet: - // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals - // operator, DoubleEquals operator and In operator with only one element in the set. - if len(t.Spec.Selector.MatchExpressions) > 0 { - return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions) + // "extensions" replicasets use pod template labels if selector is not set. + var labels map[string]string + if t.Spec.Selector != nil { + // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals + // operator, DoubleEquals operator and In operator with only one element in the set. + if len(t.Spec.Selector.MatchExpressions) > 0 { + return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions) + } + labels = t.Spec.Selector.MatchLabels + } else { + labels = t.Spec.Template.Labels } - return generate.MakeLabels(t.Spec.Selector.MatchLabels), nil + if len(labels) == 0 { + return "", fmt.Errorf("the replica set has no labels or selectors and cannot be exposed") + } + return generate.MakeLabels(labels), nil + case *appsv1.ReplicaSet: + // "apps" replicasets must have the selector set. + if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 { + return "", fmt.Errorf("invalid replicaset: no selectors, therefore cannot be exposed") + } // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals // operator, DoubleEquals operator and In operator with only one element in the set. if len(t.Spec.Selector.MatchExpressions) > 0 { return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions) } return generate.MakeLabels(t.Spec.Selector.MatchLabels), nil + case *appsv1beta2.ReplicaSet: + // "apps" replicasets must have the selector set. + if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 { + return "", fmt.Errorf("invalid replicaset: no selectors, therefore cannot be exposed") + } // TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals // operator, DoubleEquals operator and In operator with only one element in the set. if len(t.Spec.Selector.MatchExpressions) > 0 { @@ -103,4 +148,5 @@ func mapBasedSelectorForObject(object runtime.Object) (string, error) { default: return "", fmt.Errorf("cannot extract pod selector from %T", object) } + } diff --git a/pkg/kubectl/polymorphichelpers/mapbasedselectorforobject_test.go b/pkg/kubectl/polymorphichelpers/mapbasedselectorforobject_test.go index 8734f0c557890..1ca8d1c7a941a 100644 --- a/pkg/kubectl/polymorphichelpers/mapbasedselectorforobject_test.go +++ b/pkg/kubectl/polymorphichelpers/mapbasedselectorforobject_test.go @@ -19,6 +19,9 @@ package polymorphichelpers import ( "testing" + appsv1 "k8s.io/api/apps/v1" + appsv1beta1 "k8s.io/api/apps/v1beta1" + appsv1beta2 "k8s.io/api/apps/v1beta2" corev1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -69,6 +72,7 @@ func TestMapBasedSelectorForObject(t *testing.T) { object: &corev1.Service{}, expectErr: true, }, + // extensions/v1beta1 Deployment with labels and selectors { object: &extensionsv1beta1.Deployment{ Spec: extensionsv1beta1.DeploymentSpec{ @@ -77,10 +81,33 @@ func TestMapBasedSelectorForObject(t *testing.T) { "foo": "bar", }, }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, }, }, expectSelector: "foo=bar", }, + // extensions/v1beta1 Deployment with only labels (no selectors) -- use labels + { + object: &extensionsv1beta1.Deployment{ + Spec: extensionsv1beta1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectSelector: "foo=bar", + }, + // extensions/v1beta1 Deployment with bad selector { object: &extensionsv1beta1.Deployment{ Spec: extensionsv1beta1.DeploymentSpec{ @@ -95,9 +122,156 @@ func TestMapBasedSelectorForObject(t *testing.T) { }, expectErr: true, }, + // apps/v1 Deployment with labels and selectors + { + object: &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + expectSelector: "foo=bar", + }, + // apps/v1 Deployment with only labels (no selectors) -- error + { + object: &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectErr: true, + }, + // apps/v1 Deployment with no labels or selectors -- error + { + object: &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{}, + }, + expectErr: true, + }, + // apps/v1 Deployment with empty labels -- error + { + object: &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{}, // Empty labels map + }, + }, + }, + }, + expectErr: true, + }, + // apps/v1beta2 Deployment with labels and selectors + { + object: &appsv1beta2.Deployment{ + Spec: appsv1beta2.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + expectSelector: "foo=bar", + }, + // apps/v1beta2 Deployment with only labels (no selectors) -- error + { + object: &appsv1beta2.Deployment{ + Spec: appsv1beta2.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectErr: true, + }, + // apps/v1beta2 Deployment with no labels or selectors -- error + { + object: &appsv1beta2.Deployment{ + Spec: appsv1beta2.DeploymentSpec{}, + }, + expectErr: true, + }, + // apps/v1beta1 Deployment with labels and selectors + { + object: &appsv1beta1.Deployment{ + Spec: appsv1beta1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + expectSelector: "foo=bar", + }, + // apps/v1beta1 Deployment with only labels (no selectors) -- error + { + object: &appsv1beta1.Deployment{ + Spec: appsv1beta1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectErr: true, + }, + // apps/v1beta1 Deployment with no labels or selectors -- error + { + object: &appsv1beta1.Deployment{ + Spec: appsv1beta1.DeploymentSpec{}, + }, + expectErr: true, + }, + // extensions/v1beta1 ReplicaSet with labels and selectors { object: &extensionsv1beta1.ReplicaSet{ Spec: extensionsv1beta1.ReplicaSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "foo": "bar", @@ -107,6 +281,22 @@ func TestMapBasedSelectorForObject(t *testing.T) { }, expectSelector: "foo=bar", }, + // extensions/v1beta1 ReplicaSet with only labels -- no selectors; use labels + { + object: &extensionsv1beta1.ReplicaSet{ + Spec: extensionsv1beta1.ReplicaSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectSelector: "foo=bar", + }, + // extensions/v1beta1 ReplicaSet with bad label selector -- error { object: &extensionsv1beta1.ReplicaSet{ Spec: extensionsv1beta1.ReplicaSetSpec{ @@ -121,6 +311,77 @@ func TestMapBasedSelectorForObject(t *testing.T) { }, expectErr: true, }, + // apps/v1 ReplicaSet with labels and selectors + { + object: &appsv1.ReplicaSet{ + Spec: appsv1.ReplicaSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + expectSelector: "foo=bar", + }, + // apps/v1 ReplicaSet with only labels (no selectors) -- error + { + object: &appsv1.ReplicaSet{ + Spec: appsv1.ReplicaSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectErr: true, + }, + // apps/v1beta2 ReplicaSet with labels and selectors + { + object: &appsv1beta2.ReplicaSet{ + Spec: appsv1beta2.ReplicaSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + expectSelector: "foo=bar", + }, + // apps/v1beta2 ReplicaSet with only labels (no selectors) -- error + { + object: &appsv1beta2.ReplicaSet{ + Spec: appsv1beta2.ReplicaSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectErr: true, + }, + // Node can not be exposed -- error { object: &corev1.Node{}, expectErr: true, diff --git a/pkg/kubectl/polymorphichelpers/protocolsforobject.go b/pkg/kubectl/polymorphichelpers/protocolsforobject.go index c1d09da9b372c..2e5e5a2086dd5 100644 --- a/pkg/kubectl/polymorphichelpers/protocolsforobject.go +++ b/pkg/kubectl/polymorphichelpers/protocolsforobject.go @@ -65,6 +65,10 @@ func getProtocols(spec corev1.PodSpec) map[string]string { result := make(map[string]string) for _, container := range spec.Containers { for _, port := range container.Ports { + // Empty protocol must be defaulted (TCP) + if len(port.Protocol) == 0 { + port.Protocol = corev1.ProtocolTCP + } result[strconv.Itoa(int(port.ContainerPort))] = string(port.Protocol) } } @@ -75,6 +79,10 @@ func getProtocols(spec corev1.PodSpec) map[string]string { func getServiceProtocols(spec corev1.ServiceSpec) map[string]string { result := make(map[string]string) for _, servicePort := range spec.Ports { + // Empty protocol must be defaulted (TCP) + if len(servicePort.Protocol) == 0 { + servicePort.Protocol = corev1.ProtocolTCP + } result[strconv.Itoa(int(servicePort.Port))] = string(servicePort.Protocol) } return result diff --git a/pkg/kubectl/polymorphichelpers/protocolsforobject_test.go b/pkg/kubectl/polymorphichelpers/protocolsforobject_test.go index 6a94cef76b9e7..d31da061485fb 100644 --- a/pkg/kubectl/polymorphichelpers/protocolsforobject_test.go +++ b/pkg/kubectl/polymorphichelpers/protocolsforobject_test.go @@ -39,7 +39,23 @@ func TestProtocolsForObject(t *testing.T) { Ports: []corev1.ContainerPort{ { ContainerPort: 101, - Protocol: "tcp", + Protocol: "TCP", + }, + }, + }, + }, + }, + }, + }, + // No protocol--should default to TCP. + { + object: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Ports: []corev1.ContainerPort{ + { + ContainerPort: 101, }, }, }, @@ -53,7 +69,19 @@ func TestProtocolsForObject(t *testing.T) { Ports: []corev1.ServicePort{ { Port: 101, - Protocol: "tcp", + Protocol: "TCP", + }, + }, + }, + }, + }, + // No protocol for service port--default to TCP + { + object: &corev1.Service{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Port: 101, }, }, }, @@ -69,7 +97,7 @@ func TestProtocolsForObject(t *testing.T) { Ports: []corev1.ContainerPort{ { ContainerPort: 101, - Protocol: "tcp", + Protocol: "TCP", }, }, }, @@ -89,7 +117,7 @@ func TestProtocolsForObject(t *testing.T) { Ports: []corev1.ContainerPort{ { ContainerPort: 101, - Protocol: "tcp", + Protocol: "TCP", }, }, }, @@ -109,7 +137,7 @@ func TestProtocolsForObject(t *testing.T) { Ports: []corev1.ContainerPort{ { ContainerPort: 101, - Protocol: "tcp", + Protocol: "TCP", }, }, }, @@ -124,7 +152,7 @@ func TestProtocolsForObject(t *testing.T) { expectErr: true, }, } - expectedPorts := map[string]string{"101": "tcp"} + expectedPorts := map[string]string{"101": "TCP"} for _, test := range tests { actual, err := protocolsForObject(test.object) diff --git a/pkg/kubectl/rollback.go b/pkg/kubectl/rollback.go index bec725f6f9495..8851d5741051d 100644 --- a/pkg/kubectl/rollback.go +++ b/pkg/kubectl/rollback.go @@ -19,14 +19,11 @@ package kubectl import ( "bytes" "fmt" - "os" - "os/signal" "sort" - "syscall" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -34,12 +31,10 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/strategicpatch" - "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" kapps "k8s.io/kubernetes/pkg/kubectl/apps" "k8s.io/kubernetes/pkg/kubectl/scheme" deploymentutil "k8s.io/kubernetes/pkg/kubectl/util/deployment" - sliceutil "k8s.io/kubernetes/pkg/kubectl/util/slice" ) const ( @@ -119,124 +114,140 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m return "", fmt.Errorf("failed to retrieve Deployment %s: %v", name, err) } + rsForRevision, err := deploymentRevision(deployment, r.c, toRevision) + if err != nil { + return "", err + } if dryRun { - return simpleDryRun(deployment, r.c, toRevision) + return printTemplate(&rsForRevision.Spec.Template) } if deployment.Spec.Paused { return "", fmt.Errorf("you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume deployment/%s' and try again", name) } - deploymentRollback := &extensionsv1beta1.DeploymentRollback{ - Name: name, - UpdatedAnnotations: updatedAnnotations, - RollbackTo: extensionsv1beta1.RollbackConfig{ - Revision: toRevision, - }, + + // Skip if the revision already matches current Deployment + if equalIgnoreHash(&rsForRevision.Spec.Template, &deployment.Spec.Template) { + return fmt.Sprintf("%s (current template already matches revision %d)", rollbackSkipped, toRevision), nil } - result := "" - // Get current events - events, err := r.c.CoreV1().Events(namespace).List(metav1.ListOptions{}) - if err != nil { - return result, err + // remove hash label before patching back into the deployment + delete(rsForRevision.Spec.Template.Labels, appsv1.DefaultDeploymentUniqueLabelKey) + + // compute deployment annotations + annotations := map[string]string{} + for k := range annotationsToSkip { + if v, ok := deployment.Annotations[k]; ok { + annotations[k] = v + } } - // Do the rollback - // TODO: This is DEPRECATED. It should be updated. DaemonSets and StatefulSets implement rollback by - // patching using history (ControllerRevision data). Deployments should probably also implement - // rollback using a patch. - if err := r.c.ExtensionsV1beta1().Deployments(namespace).Rollback(deploymentRollback); err != nil { - return result, err + for k, v := range rsForRevision.Annotations { + if !annotationsToSkip[k] { + annotations[k] = v + } } - // Watch for the changes of events - watch, err := r.c.CoreV1().Events(namespace).Watch(metav1.ListOptions{Watch: true, ResourceVersion: events.ResourceVersion}) + + // make patch to restore + patchType, patch, err := getDeploymentPatch(&rsForRevision.Spec.Template, annotations) if err != nil { - return result, err + return "", fmt.Errorf("failed restoring revision %d: %v", toRevision, err) } - result = watchRollbackEvent(watch) - return result, err -} -// watchRollbackEvent watches for rollback events and returns rollback result -func watchRollbackEvent(w watch.Interface) string { - signals := make(chan os.Signal, 1) - signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGTERM) - for { - select { - case event, ok := <-w.ResultChan(): - if !ok { - return "" - } - obj, ok := event.Object.(*corev1.Event) - if !ok { - w.Stop() - return "" - } - isRollback, result := isRollbackEvent(obj) - if isRollback { - w.Stop() - return result - } - case <-signals: - w.Stop() - } + // Restore revision + if _, err = r.c.AppsV1().Deployments(namespace).Patch(name, patchType, patch); err != nil { + return "", fmt.Errorf("failed restoring revision %d: %v", toRevision, err) } + return rollbackSuccess, nil } -// isRollbackEvent checks if the input event is about rollback, and returns true and -// related result string back if it is. -func isRollbackEvent(e *corev1.Event) (bool, string) { - rollbackEventReasons := []string{deploymentutil.RollbackRevisionNotFound, deploymentutil.RollbackTemplateUnchanged, deploymentutil.RollbackDone} - for _, reason := range rollbackEventReasons { - if e.Reason == reason { - if reason == deploymentutil.RollbackDone { - return true, rollbackSuccess - } - return true, fmt.Sprintf("%s (%s: %s)", rollbackSkipped, e.Reason, e.Message) - } - } - return false, "" +// equalIgnoreHash returns true if two given podTemplateSpec are equal, ignoring the diff in value of Labels[pod-template-hash] +// We ignore pod-template-hash because: +// 1. The hash result would be different upon podTemplateSpec API changes +// (e.g. the addition of a new field will cause the hash code to change) +// 2. The deployment template won't have hash labels +func equalIgnoreHash(template1, template2 *corev1.PodTemplateSpec) bool { + t1Copy := template1.DeepCopy() + t2Copy := template2.DeepCopy() + // Remove hash labels from template.Labels before comparing + delete(t1Copy.Labels, appsv1.DefaultDeploymentUniqueLabelKey) + delete(t2Copy.Labels, appsv1.DefaultDeploymentUniqueLabelKey) + return apiequality.Semantic.DeepEqual(t1Copy, t2Copy) } -func simpleDryRun(deployment *appsv1.Deployment, c kubernetes.Interface, toRevision int64) (string, error) { +// annotationsToSkip lists the annotations that should be preserved from the deployment and not +// copied from the replicaset when rolling a deployment back +var annotationsToSkip = map[string]bool{ + corev1.LastAppliedConfigAnnotation: true, + deploymentutil.RevisionAnnotation: true, + deploymentutil.RevisionHistoryAnnotation: true, + deploymentutil.DesiredReplicasAnnotation: true, + deploymentutil.MaxReplicasAnnotation: true, + appsv1.DeprecatedRollbackTo: true, +} + +// getPatch returns a patch that can be applied to restore a Deployment to a +// previous version. If the returned error is nil the patch is valid. +func getDeploymentPatch(podTemplate *corev1.PodTemplateSpec, annotations map[string]string) (types.PatchType, []byte, error) { + // Create a patch of the Deployment that replaces spec.template + patch, err := json.Marshal([]interface{}{ + map[string]interface{}{ + "op": "replace", + "path": "/spec/template", + "value": podTemplate, + }, + map[string]interface{}{ + "op": "replace", + "path": "/metadata/annotations", + "value": annotations, + }, + }) + return types.JSONPatchType, patch, err +} + +func deploymentRevision(deployment *appsv1.Deployment, c kubernetes.Interface, toRevision int64) (revision *appsv1.ReplicaSet, err error) { _, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(deployment, c.AppsV1()) if err != nil { - return "", fmt.Errorf("failed to retrieve replica sets from deployment %s: %v", deployment.Name, err) + return nil, fmt.Errorf("failed to retrieve replica sets from deployment %s: %v", deployment.Name, err) } allRSs := allOldRSs if newRS != nil { allRSs = append(allRSs, newRS) } - revisionToSpec := make(map[int64]*corev1.PodTemplateSpec) + var ( + latestReplicaSet *appsv1.ReplicaSet + latestRevision = int64(-1) + previousReplicaSet *appsv1.ReplicaSet + previousRevision = int64(-1) + ) for _, rs := range allRSs { - v, err := deploymentutil.Revision(rs) - if err != nil { - continue + if v, err := deploymentutil.Revision(rs); err == nil { + if toRevision == 0 { + if latestRevision < v { + // newest one we've seen so far + previousRevision = latestRevision + previousReplicaSet = latestReplicaSet + latestRevision = v + latestReplicaSet = rs + } else if previousRevision < v { + // second newest one we've seen so far + previousRevision = v + previousReplicaSet = rs + } + } else if toRevision == v { + return rs, nil + } } - revisionToSpec[v] = &rs.Spec.Template - } - - if len(revisionToSpec) < 2 { - return "", fmt.Errorf("no rollout history found for deployment %q", deployment.Name) } if toRevision > 0 { - template, ok := revisionToSpec[toRevision] - if !ok { - return "", revisionNotFoundErr(toRevision) - } - return printTemplate(template) + return nil, revisionNotFoundErr(toRevision) } - // Sort the revisionToSpec map by revision - revisions := make([]int64, 0, len(revisionToSpec)) - for r := range revisionToSpec { - revisions = append(revisions, r) + if previousReplicaSet == nil { + return nil, fmt.Errorf("no rollout history found for deployment %q", deployment.Name) } - sliceutil.SortInts64(revisions) - - template, _ := revisionToSpec[revisions[len(revisions)-2]] - return printTemplate(template) + return previousReplicaSet, nil } type DaemonSetRollbacker struct { diff --git a/pkg/kubectl/rollback_test.go b/pkg/kubectl/rollback_test.go index 1d41650ba3967..14166dedacc90 100644 --- a/pkg/kubectl/rollback_test.go +++ b/pkg/kubectl/rollback_test.go @@ -20,7 +20,9 @@ import ( "reflect" "testing" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes/fake" ) @@ -44,3 +46,22 @@ func TestRollbackerFor(t *testing.T) { } } } + +func TestGetDeploymentPatch(t *testing.T) { + patchType, patchBytes, err := getDeploymentPatch(&corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{Image: "foo"}}}}, map[string]string{"a": "true"}) + if err != nil { + t.Error(err) + } + if patchType != types.JSONPatchType { + t.Errorf("expected strategic merge patch, got %v", patchType) + } + expectedPatch := `[` + + `{"op":"replace","path":"/spec/template","value":{"metadata":{"creationTimestamp":null},"spec":{"containers":[{"name":"","image":"foo","resources":{}}]}}},` + + `{"op":"replace","path":"/metadata/annotations","value":{"a":"true"}}` + + `]` + if string(patchBytes) != expectedPatch { + t.Errorf("expected:\n%s\ngot\n%s", expectedPatch, string(patchBytes)) + } +} diff --git a/pkg/kubectl/rolling_updater.go b/pkg/kubectl/rolling_updater.go index 58741483805c6..b6df08c412073 100644 --- a/pkg/kubectl/rolling_updater.go +++ b/pkg/kubectl/rolling_updater.go @@ -54,7 +54,7 @@ func valOrZero(val *int32) int32 { const ( kubectlAnnotationPrefix = "kubectl.kubernetes.io/" - sourceIdAnnotation = kubectlAnnotationPrefix + "update-source-id" + sourceIDAnnotation = kubectlAnnotationPrefix + "update-source-id" desiredReplicasAnnotation = kubectlAnnotationPrefix + "desired-replicas" originalReplicasAnnotation = kubectlAnnotationPrefix + "original-replicas" nextControllerAnnotation = kubectlAnnotationPrefix + "next-controller-id" @@ -135,7 +135,7 @@ type RollingUpdater struct { scaleAndWait func(rc *corev1.ReplicationController, retry *RetryParams, wait *RetryParams) (*corev1.ReplicationController, error) //getOrCreateTargetController gets and validates an existing controller or //makes a new one. - getOrCreateTargetController func(controller *corev1.ReplicationController, sourceId string) (*corev1.ReplicationController, bool, error) + getOrCreateTargetController func(controller *corev1.ReplicationController, sourceID string) (*corev1.ReplicationController, bool, error) // cleanup performs post deployment cleanup tasks for newRc and oldRc. cleanup func(oldRc, newRc *corev1.ReplicationController, config *RollingUpdaterConfig) error // getReadyPods returns the amount of old and new ready pods. @@ -188,8 +188,8 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error { // Find an existing controller (for continuing an interrupted update) or // create a new one if necessary. - sourceId := fmt.Sprintf("%s:%s", oldRc.Name, oldRc.UID) - newRc, existed, err := r.getOrCreateTargetController(config.NewRc, sourceId) + sourceID := fmt.Sprintf("%s:%s", oldRc.Name, oldRc.UID) + newRc, existed, err := r.getOrCreateTargetController(config.NewRc, sourceID) if err != nil { return err } @@ -458,14 +458,14 @@ func (r *RollingUpdater) readyPods(oldRc, newRc *corev1.ReplicationController, m } // getOrCreateTargetControllerWithClient looks for an existing controller with -// sourceId. If found, the existing controller is returned with true +// sourceID. If found, the existing controller is returned with true // indicating that the controller already exists. If the controller isn't // found, a new one is created and returned along with false indicating the // controller was created. // -// Existing controllers are validated to ensure their sourceIdAnnotation -// matches sourceId; if there's a mismatch, an error is returned. -func (r *RollingUpdater) getOrCreateTargetControllerWithClient(controller *corev1.ReplicationController, sourceId string) (*corev1.ReplicationController, bool, error) { +// Existing controllers are validated to ensure their sourceIDAnnotation +// matches sourceID; if there's a mismatch, an error is returned. +func (r *RollingUpdater) getOrCreateTargetControllerWithClient(controller *corev1.ReplicationController, sourceID string) (*corev1.ReplicationController, bool, error) { existingRc, err := r.existingController(controller) if err != nil { if !errors.IsNotFound(err) { @@ -474,24 +474,24 @@ func (r *RollingUpdater) getOrCreateTargetControllerWithClient(controller *corev return nil, false, err } if valOrZero(controller.Spec.Replicas) <= 0 { - return nil, false, fmt.Errorf("Invalid controller spec for %s; required: > 0 replicas, actual: %d\n", controller.Name, valOrZero(controller.Spec.Replicas)) + return nil, false, fmt.Errorf("Invalid controller spec for %s; required: > 0 replicas, actual: %d", controller.Name, valOrZero(controller.Spec.Replicas)) } // The controller wasn't found, so create it. if controller.Annotations == nil { controller.Annotations = map[string]string{} } controller.Annotations[desiredReplicasAnnotation] = fmt.Sprintf("%d", valOrZero(controller.Spec.Replicas)) - controller.Annotations[sourceIdAnnotation] = sourceId + controller.Annotations[sourceIDAnnotation] = sourceID controller.Spec.Replicas = newInt32Ptr(0) newRc, err := r.rcClient.ReplicationControllers(r.ns).Create(controller) return newRc, false, err } // Validate and use the existing controller. annotations := existingRc.Annotations - source := annotations[sourceIdAnnotation] + source := annotations[sourceIDAnnotation] _, ok := annotations[desiredReplicasAnnotation] - if source != sourceId || !ok { - return nil, false, fmt.Errorf("Missing/unexpected annotations for controller %s, expected %s : %s", controller.Name, sourceId, annotations) + if source != sourceID || !ok { + return nil, false, fmt.Errorf("Missing/unexpected annotations for controller %s, expected %s : %s", controller.Name, sourceID, annotations) } return existingRc, true, nil } @@ -517,7 +517,7 @@ func (r *RollingUpdater) cleanupWithClients(oldRc, newRc *corev1.ReplicationCont return err } applyUpdate := func(rc *corev1.ReplicationController) { - delete(rc.Annotations, sourceIdAnnotation) + delete(rc.Annotations, sourceIDAnnotation) delete(rc.Annotations, desiredReplicasAnnotation) } if newRc, err = updateRcWithRetries(r.rcClient, r.ns, newRc, applyUpdate); err != nil { @@ -662,7 +662,7 @@ func AbortRollingUpdate(c *RollingUpdaterConfig) error { if c.NewRc.Annotations == nil { c.NewRc.Annotations = map[string]string{} } - c.NewRc.Annotations[sourceIdAnnotation] = fmt.Sprintf("%s:%s", c.OldRc.Name, c.OldRc.UID) + c.NewRc.Annotations[sourceIDAnnotation] = fmt.Sprintf("%s:%s", c.OldRc.Name, c.OldRc.UID) // Use the original value since the replica count change from old to new // could be asymmetric. If we don't know the original count, we can't safely @@ -841,7 +841,7 @@ func FindSourceController(r corev1client.ReplicationControllersGetter, namespace } for ix := range list.Items { rc := &list.Items[ix] - if rc.Annotations != nil && strings.HasPrefix(rc.Annotations[sourceIdAnnotation], name) { + if rc.Annotations != nil && strings.HasPrefix(rc.Annotations[sourceIDAnnotation], name) { return rc, nil } } diff --git a/pkg/kubectl/rolling_updater_test.go b/pkg/kubectl/rolling_updater_test.go index be61b20bd04d9..824f2ac82c1a5 100644 --- a/pkg/kubectl/rolling_updater_test.go +++ b/pkg/kubectl/rolling_updater_test.go @@ -86,7 +86,7 @@ func newRc(replicas int, desired int) *corev1.ReplicationController { Name: "foo-v2", Annotations: map[string]string{ desiredReplicasAnnotation: fmt.Sprintf("%d", desired), - sourceIdAnnotation: "foo-v1:7764ae47-9092-11e4-8393-42010af018ff", + sourceIDAnnotation: "foo-v1:7764ae47-9092-11e4-8393-42010af018ff", }, } return rc @@ -812,7 +812,7 @@ Scaling foo-v2 up to 2 rc.Status.Replicas = *rc.Spec.Replicas return rc, nil }, - getOrCreateTargetController: func(controller *corev1.ReplicationController, sourceId string) (*corev1.ReplicationController, bool, error) { + getOrCreateTargetController: func(controller *corev1.ReplicationController, sourceID string) (*corev1.ReplicationController, bool, error) { // Simulate a create vs. update of an existing controller. return tt.newRc, tt.newRcExists, nil }, @@ -865,7 +865,7 @@ func TestUpdate_progressTimeout(t *testing.T) { // Do nothing. return rc, nil }, - getOrCreateTargetController: func(controller *corev1.ReplicationController, sourceId string) (*corev1.ReplicationController, bool, error) { + getOrCreateTargetController: func(controller *corev1.ReplicationController, sourceID string) (*corev1.ReplicationController, bool, error) { return newRc, false, nil }, cleanup: func(oldRc, newRc *corev1.ReplicationController, config *RollingUpdaterConfig) error { @@ -909,7 +909,7 @@ func TestUpdate_assignOriginalAnnotation(t *testing.T) { scaleAndWait: func(rc *corev1.ReplicationController, retry *RetryParams, wait *RetryParams) (*corev1.ReplicationController, error) { return rc, nil }, - getOrCreateTargetController: func(controller *corev1.ReplicationController, sourceId string) (*corev1.ReplicationController, bool, error) { + getOrCreateTargetController: func(controller *corev1.ReplicationController, sourceID string) (*corev1.ReplicationController, bool, error) { return newRc, false, nil }, cleanup: func(oldRc, newRc *corev1.ReplicationController, config *RollingUpdaterConfig) error { @@ -1244,7 +1244,7 @@ func TestFindSourceController(t *testing.T) { Namespace: metav1.NamespaceDefault, Name: "foo", Annotations: map[string]string{ - sourceIdAnnotation: "bar:1234", + sourceIDAnnotation: "bar:1234", }, }, } @@ -1253,7 +1253,7 @@ func TestFindSourceController(t *testing.T) { Namespace: metav1.NamespaceDefault, Name: "bar", Annotations: map[string]string{ - sourceIdAnnotation: "foo:12345", + sourceIDAnnotation: "foo:12345", }, }, } @@ -1262,7 +1262,7 @@ func TestFindSourceController(t *testing.T) { Namespace: metav1.NamespaceDefault, Name: "baz", Annotations: map[string]string{ - sourceIdAnnotation: "baz:45667", + sourceIDAnnotation: "baz:45667", }, }, } diff --git a/pkg/kubectl/scale.go b/pkg/kubectl/scale.go index f1d46b7a110b2..54f96fd2c3407 100644 --- a/pkg/kubectl/scale.go +++ b/pkg/kubectl/scale.go @@ -175,7 +175,7 @@ func scaleHasDesiredReplicas(sClient scaleclient.ScalesGetter, gr schema.GroupRe // or returns error when timeout happens func WaitForScaleHasDesiredReplicas(sClient scaleclient.ScalesGetter, gr schema.GroupResource, resourceName string, namespace string, newSize uint, waitForReplicas *RetryParams) error { if waitForReplicas == nil { - return fmt.Errorf("waitForReplicas parameter cannot be nil!") + return fmt.Errorf("waitForReplicas parameter cannot be nil") } err := wait.PollImmediate( waitForReplicas.Interval, diff --git a/pkg/kubectl/sorter.go b/pkg/kubectl/sorter.go index b7c339dfb2bbf..d2d33acf92b55 100644 --- a/pkg/kubectl/sorter.go +++ b/pkg/kubectl/sorter.go @@ -37,7 +37,7 @@ import ( "vbom.ml/util/sortorder" ) -// Sorting printer sorts list types before delegating to another printer. +// SortingPrinter sorts list types before delegating to another printer. // Non-list types are simply passed through type SortingPrinter struct { SortField string @@ -296,7 +296,8 @@ func (r *RuntimeSort) Less(i, j int) bool { return less } -// Returns the starting (original) position of a particular index. e.g. If OriginalPosition(0) returns 5 than the +// OriginalPosition returns the starting (original) position of a particular index. +// e.g. If OriginalPosition(0) returns 5 than the // the item currently at position 0 was at position 5 in the original unsorted array. func (r *RuntimeSort) OriginalPosition(ix int) int { if ix < 0 || ix > len(r.origPosition) { @@ -306,8 +307,9 @@ func (r *RuntimeSort) OriginalPosition(ix int) int { } type TableSorter struct { - field string - obj *metav1beta1.Table + field string + obj *metav1beta1.Table + parsedRows [][][]reflect.Value } func (t *TableSorter) Len() int { @@ -319,32 +321,8 @@ func (t *TableSorter) Swap(i, j int) { } func (t *TableSorter) Less(i, j int) bool { - iObj := t.obj.Rows[i].Object.Object - jObj := t.obj.Rows[j].Object.Object - - var iValues [][]reflect.Value - var jValues [][]reflect.Value - var err error - - parser := jsonpath.New("sorting").AllowMissingKeys(true) - err = parser.Parse(t.field) - if err != nil { - glog.Fatalf("sorting error: %v\n", err) - } - - // TODO(juanvallejo): this is expensive for very large sets. - // To improve runtime complexity, build an array which contains all - // resolved fields, and sort that instead. - iValues, err = findJSONPathResults(parser, iObj) - if err != nil { - glog.Fatalf("Failed to get i values for %#v using %s (%#v)", iObj, t.field, err) - } - - jValues, err = findJSONPathResults(parser, jObj) - if err != nil { - glog.Fatalf("Failed to get j values for %#v using %s (%v)", jObj, t.field, err) - } - + iValues := t.parsedRows[i] + jValues := t.parsedRows[j] if len(iValues) == 0 || len(iValues[0]) == 0 || len(jValues) == 0 || len(jValues[0]) == 0 { glog.Fatalf("couldn't find any field with path %q in the list of objects", t.field) } @@ -354,7 +332,7 @@ func (t *TableSorter) Less(i, j int) bool { less, err := isLess(iField, jField) if err != nil { - glog.Fatalf("Field %s in %T is an unsortable type: %s, err: %v", t.field, iObj, iField.Kind().String(), err) + glog.Fatalf("Field %s in %T is an unsortable type: %s, err: %v", t.field, t.parsedRows, iField.Kind().String(), err) } return less } @@ -365,16 +343,31 @@ func (t *TableSorter) Sort() error { } func NewTableSorter(table *metav1beta1.Table, field string) *TableSorter { + var parsedRows [][][]reflect.Value + + parser := jsonpath.New("sorting").AllowMissingKeys(true) + err := parser.Parse(field) + if err != nil { + glog.Fatalf("sorting error: %v\n", err) + } + + for i := range table.Rows { + parsedRow, err := findJSONPathResults(parser, table.Rows[i].Object.Object) + if err != nil { + glog.Fatalf("Failed to get values for %#v using %s (%#v)", parsedRow, field, err) + } + parsedRows = append(parsedRows, parsedRow) + } + return &TableSorter{ - obj: table, - field: field, + obj: table, + field: field, + parsedRows: parsedRows, } } - func findJSONPathResults(parser *jsonpath.JSONPath, from runtime.Object) ([][]reflect.Value, error) { if unstructuredObj, ok := from.(*unstructured.Unstructured); ok { return parser.FindResults(unstructuredObj.Object) } - return parser.FindResults(reflect.ValueOf(from).Elem().Interface()) } diff --git a/pkg/kubectl/util/deployment/deployment.go b/pkg/kubectl/util/deployment/deployment.go index 88e7edd168230..72f99f7f2ee45 100644 --- a/pkg/kubectl/util/deployment/deployment.go +++ b/pkg/kubectl/util/deployment/deployment.go @@ -33,6 +33,16 @@ import ( const ( // RevisionAnnotation is the revision annotation of a deployment's replica sets which records its rollout sequence RevisionAnnotation = "deployment.kubernetes.io/revision" + // RevisionHistoryAnnotation maintains the history of all old revisions that a replica set has served for a deployment. + RevisionHistoryAnnotation = "deployment.kubernetes.io/revision-history" + // DesiredReplicasAnnotation is the desired replicas for a deployment recorded as an annotation + // in its replica sets. Helps in separating scaling events from the rollout process and for + // determining if the new replica set for a deployment is really saturated. + DesiredReplicasAnnotation = "deployment.kubernetes.io/desired-replicas" + // MaxReplicasAnnotation is the maximum replicas a deployment can have at a given point, which + // is deployment.spec.replicas + maxSurge. Used by the underlying replica sets to estimate their + // proportions in case the deployment has surge replicas. + MaxReplicasAnnotation = "deployment.kubernetes.io/max-replicas" // RollbackRevisionNotFound is not found rollback event reason RollbackRevisionNotFound = "DeploymentRollbackRevisionNotFound" // RollbackTemplateUnchanged is the template unchanged rollback event reason diff --git a/pkg/kubectl/util/service_port.go b/pkg/kubectl/util/service_port.go index 18960b1486464..bc56ab7d6a909 100644 --- a/pkg/kubectl/util/service_port.go +++ b/pkg/kubectl/util/service_port.go @@ -23,8 +23,8 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) -// Lookup containerPort number from Service port number -// It implements the handling of resolving container named port, as well as ignoring targetPort when clusterIP=None +// LookupContainerPortNumberByServicePort implements +// the handling of resolving container named port, as well as ignoring targetPort when clusterIP=None // It returns an error when a named port can't find a match (with -1 returned), or when the service does not // declare such port (with the input port number returned). func LookupContainerPortNumberByServicePort(svc v1.Service, pod v1.Pod, port int32) (int32, error) { @@ -39,12 +39,10 @@ func LookupContainerPortNumberByServicePort(svc v1.Service, pod v1.Pod, port int if svcportspec.TargetPort.IntValue() == 0 { // targetPort is omitted, and the IntValue() would be zero return svcportspec.Port, nil - } else { - return int32(svcportspec.TargetPort.IntValue()), nil } - } else { - return LookupContainerPortNumberByName(pod, svcportspec.TargetPort.String()) + return int32(svcportspec.TargetPort.IntValue()), nil } + return LookupContainerPortNumberByName(pod, svcportspec.TargetPort.String()) } return port, fmt.Errorf("Service %s does not have a service port %d", svc.Name, port) } diff --git a/pkg/kubectl/util/slice/slice.go b/pkg/kubectl/util/slice/slice.go index 8130753c300f9..0eef7db1a30cf 100644 --- a/pkg/kubectl/util/slice/slice.go +++ b/pkg/kubectl/util/slice/slice.go @@ -20,5 +20,5 @@ import ( "sort" ) -// Sorts []int64 in increasing order +// SortInts64 sorts []int64 in increasing order func SortInts64(a []int64) { sort.Slice(a, func(i, j int) bool { return a[i] < a[j] }) } diff --git a/pkg/kubectl/util/umask.go b/pkg/kubectl/util/umask.go index 93e14473c225a..67add4e9140a1 100644 --- a/pkg/kubectl/util/umask.go +++ b/pkg/kubectl/util/umask.go @@ -22,6 +22,7 @@ import ( "golang.org/x/sys/unix" ) +// Umask is a wrapper for `unix.Umask()` on non-Windows platforms func Umask(mask int) (old int, err error) { return unix.Umask(mask), nil } diff --git a/pkg/kubectl/util/umask_windows.go b/pkg/kubectl/util/umask_windows.go index 7a1ba15386f8a..5b4f54bb795b3 100644 --- a/pkg/kubectl/util/umask_windows.go +++ b/pkg/kubectl/util/umask_windows.go @@ -22,6 +22,7 @@ import ( "errors" ) +// Umask returns an error on Windows func Umask(mask int) (int, error) { return 0, errors.New("platform and architecture is not supported") } diff --git a/pkg/kubectl/util/util.go b/pkg/kubectl/util/util.go index 41427780c71d5..0c1973dfb8ed3 100644 --- a/pkg/kubectl/util/util.go +++ b/pkg/kubectl/util/util.go @@ -41,6 +41,7 @@ func ParseRFC3339(s string, nowFn func() metav1.Time) (metav1.Time, error) { return metav1.Time{Time: t}, nil } +// HashObject returns the hash of a Object hash by a Codec func HashObject(obj runtime.Object, codec runtime.Codec) (string, error) { data, err := runtime.Encode(codec, obj) if err != nil { @@ -63,11 +64,11 @@ func ParseFileSource(source string) (keyName, filePath string, err error) { case numSeparators == 0: return path.Base(filepath.ToSlash(source)), source, nil case numSeparators == 1 && strings.HasPrefix(source, "="): - return "", "", fmt.Errorf("key name for file path %v missing.", strings.TrimPrefix(source, "=")) + return "", "", fmt.Errorf("key name for file path %v missing", strings.TrimPrefix(source, "=")) case numSeparators == 1 && strings.HasSuffix(source, "="): - return "", "", fmt.Errorf("file path for key name %v missing.", strings.TrimSuffix(source, "=")) + return "", "", fmt.Errorf("file path for key name %v missing", strings.TrimSuffix(source, "=")) case numSeparators > 1: - return "", "", errors.New("Key names or file paths cannot contain '='.") + return "", "", errors.New("Key names or file paths cannot contain '='") default: components := strings.Split(source, "=") return components[0], components[1], nil diff --git a/pkg/kubelet/cadvisor/util.go b/pkg/kubelet/cadvisor/util.go index 16596daa9d9a8..9a7e8746436ba 100644 --- a/pkg/kubelet/cadvisor/util.go +++ b/pkg/kubelet/cadvisor/util.go @@ -76,5 +76,5 @@ func EphemeralStorageCapacityFromFsInfo(info cadvisorapi2.FsInfo) v1.ResourceLis // UsingLegacyCadvisorStats returns true if container stats are provided by cadvisor instead of through the CRI func UsingLegacyCadvisorStats(runtime, runtimeEndpoint string) bool { return (runtime == kubetypes.DockerContainerRuntime && goruntime.GOOS == "linux") || - runtimeEndpoint == CrioSocket + runtimeEndpoint == CrioSocket || runtimeEndpoint == "unix://"+CrioSocket } diff --git a/pkg/kubelet/certificate/OWNERS b/pkg/kubelet/certificate/OWNERS index dcb32d2b8c879..470b7a1c92d15 100644 --- a/pkg/kubelet/certificate/OWNERS +++ b/pkg/kubelet/certificate/OWNERS @@ -1,7 +1,7 @@ -reviewers: -- mikedanese -- liggitt -- awly approvers: -- mikedanese -- liggitt +- sig-auth-certificates-approvers +reviewers: +- sig-auth-certificates-reviewers +labels: +- sig/auth + diff --git a/pkg/kubelet/cm/BUILD b/pkg/kubelet/cm/BUILD index 12c9d2f2895b8..dca92c084e766 100644 --- a/pkg/kubelet/cm/BUILD +++ b/pkg/kubelet/cm/BUILD @@ -11,10 +11,11 @@ go_library( "container_manager_unsupported.go", "container_manager_windows.go", "fake_internal_container_lifecycle.go", + "helpers.go", "helpers_linux.go", "helpers_unsupported.go", "internal_container_lifecycle.go", - "node_container_manager.go", + "node_container_manager_linux.go", "pod_container_manager_linux.go", "pod_container_manager_stub.go", "pod_container_manager_unsupported.go", @@ -128,7 +129,7 @@ go_test( "cgroup_manager_test.go", "container_manager_linux_test.go", "helpers_linux_test.go", - "node_container_manager_test.go", + "node_container_manager_linux_test.go", "pod_container_manager_linux_test.go", ], embed = [":go_default_library"], diff --git a/pkg/kubelet/cm/cgroup_manager_linux.go b/pkg/kubelet/cm/cgroup_manager_linux.go index d0eb6b6d27bbf..a66b9cc58901b 100644 --- a/pkg/kubelet/cm/cgroup_manager_linux.go +++ b/pkg/kubelet/cm/cgroup_manager_linux.go @@ -67,7 +67,10 @@ func NewCgroupName(base CgroupName, components ...string) CgroupName { panic(fmt.Errorf("invalid character in component [%q] of CgroupName", component)) } } - return CgroupName(append(base, components...)) + // copy data from the base cgroup to eliminate cases where CgroupNames share underlying slices. See #68416 + baseCopy := make([]string, len(base)) + copy(baseCopy, base) + return CgroupName(append(baseCopy, components...)) } func escapeSystemdCgroupName(part string) string { diff --git a/pkg/kubelet/cm/cgroup_manager_linux_test.go b/pkg/kubelet/cm/cgroup_manager_linux_test.go index eb71014c5a3f9..dcadae2677017 100644 --- a/pkg/kubelet/cm/cgroup_manager_linux_test.go +++ b/pkg/kubelet/cm/cgroup_manager_linux_test.go @@ -20,9 +20,34 @@ package cm import ( "path" + "reflect" "testing" ) +// TestNewCgroupName tests confirms that #68416 is fixed +func TestNewCgroupName(t *testing.T) { + a := ParseCgroupfsToCgroupName("/a/") + ab := NewCgroupName(a, "b") + + expectedAB := CgroupName([]string{"a", "", "b"}) + if !reflect.DeepEqual(ab, expectedAB) { + t.Errorf("Expected %d%+v; got %d%+v", len(expectedAB), expectedAB, len(ab), ab) + } + + abc := NewCgroupName(ab, "c") + + expectedABC := CgroupName([]string{"a", "", "b", "c"}) + if !reflect.DeepEqual(abc, expectedABC) { + t.Errorf("Expected %d%+v; got %d%+v", len(expectedABC), expectedABC, len(abc), abc) + } + + _ = NewCgroupName(ab, "d") + + if !reflect.DeepEqual(abc, expectedABC) { + t.Errorf("Expected %d%+v; got %d%+v", len(expectedABC), expectedABC, len(abc), abc) + } +} + func TestCgroupNameToSystemdBasename(t *testing.T) { testCases := []struct { input CgroupName diff --git a/pkg/kubelet/cm/container_manager_windows.go b/pkg/kubelet/cm/container_manager_windows.go index 56bdbb9d36369..aadc51d0f4637 100644 --- a/pkg/kubelet/cm/container_manager_windows.go +++ b/pkg/kubelet/cm/container_manager_windows.go @@ -16,31 +16,153 @@ See the License for the specific language governing permissions and limitations under the License. */ +// containerManagerImpl implements container manager on Windows. +// Only GetNodeAllocatableReservation() and GetCapacity() are implemented now. + package cm import ( - "github.com/golang/glog" + "fmt" + "github.com/golang/glog" "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/record" + kubefeatures "k8s.io/kubernetes/pkg/features" internalapi "k8s.io/kubernetes/pkg/kubelet/apis/cri" "k8s.io/kubernetes/pkg/kubelet/cadvisor" + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" "k8s.io/kubernetes/pkg/kubelet/config" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/lifecycle" "k8s.io/kubernetes/pkg/kubelet/status" + "k8s.io/kubernetes/pkg/kubelet/util/pluginwatcher" + schedulercache "k8s.io/kubernetes/pkg/scheduler/cache" "k8s.io/kubernetes/pkg/util/mount" ) type containerManagerImpl struct { - containerManagerStub + // Capacity of this node. + capacity v1.ResourceList + // Interface for cadvisor. + cadvisorInterface cadvisor.Interface + // Config of this node. + nodeConfig NodeConfig } -var _ ContainerManager = &containerManagerImpl{} +func (cm *containerManagerImpl) Start(node *v1.Node, + activePods ActivePodsFunc, + sourcesReady config.SourcesReady, + podStatusProvider status.PodStatusProvider, + runtimeService internalapi.RuntimeService) error { + glog.V(2).Infof("Starting Windows container manager") + + if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.LocalStorageCapacityIsolation) { + rootfs, err := cm.cadvisorInterface.RootFsInfo() + if err != nil { + return fmt.Errorf("failed to get rootfs info: %v", err) + } + for rName, rCap := range cadvisor.EphemeralStorageCapacityFromFsInfo(rootfs) { + cm.capacity[rName] = rCap + } + } -func (cm *containerManagerImpl) Start(_ *v1.Node, _ ActivePodsFunc, _ config.SourcesReady, _ status.PodStatusProvider, _ internalapi.RuntimeService) error { - glog.V(2).Infof("Starting Windows stub container manager") return nil } +// NewContainerManager creates windows container manager. func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.Interface, nodeConfig NodeConfig, failSwapOn bool, devicePluginEnabled bool, recorder record.EventRecorder) (ContainerManager, error) { - return &containerManagerImpl{}, nil + var capacity = v1.ResourceList{} + // It is safe to invoke `MachineInfo` on cAdvisor before logically initializing cAdvisor here because + // machine info is computed and cached once as part of cAdvisor object creation. + // But `RootFsInfo` and `ImagesFsInfo` are not available at this moment so they will be called later during manager starts + machineInfo, err := cadvisorInterface.MachineInfo() + if err != nil { + return nil, err + } + capacity = cadvisor.CapacityFromMachineInfo(machineInfo) + + return &containerManagerImpl{ + capacity: capacity, + nodeConfig: nodeConfig, + cadvisorInterface: cadvisorInterface, + }, nil +} + +func (cm *containerManagerImpl) SystemCgroupsLimit() v1.ResourceList { + return v1.ResourceList{} +} + +func (cm *containerManagerImpl) GetNodeConfig() NodeConfig { + return NodeConfig{} +} + +func (cm *containerManagerImpl) GetMountedSubsystems() *CgroupSubsystems { + return &CgroupSubsystems{} +} + +func (cm *containerManagerImpl) GetQOSContainersInfo() QOSContainersInfo { + return QOSContainersInfo{} +} + +func (cm *containerManagerImpl) UpdateQOSCgroups() error { + return nil +} + +func (cm *containerManagerImpl) Status() Status { + return Status{} +} + +func (cm *containerManagerImpl) GetNodeAllocatableReservation() v1.ResourceList { + evictionReservation := hardEvictionReservation(cm.nodeConfig.HardEvictionThresholds, cm.capacity) + result := make(v1.ResourceList) + for k := range cm.capacity { + value := resource.NewQuantity(0, resource.DecimalSI) + if cm.nodeConfig.SystemReserved != nil { + value.Add(cm.nodeConfig.SystemReserved[k]) + } + if cm.nodeConfig.KubeReserved != nil { + value.Add(cm.nodeConfig.KubeReserved[k]) + } + if evictionReservation != nil { + value.Add(evictionReservation[k]) + } + if !value.IsZero() { + result[k] = *value + } + } + return result +} + +func (cm *containerManagerImpl) GetCapacity() v1.ResourceList { + return cm.capacity +} + +func (cm *containerManagerImpl) GetPluginRegistrationHandler() pluginwatcher.PluginHandler { + return nil +} + +func (cm *containerManagerImpl) GetDevicePluginResourceCapacity() (v1.ResourceList, v1.ResourceList, []string) { + return nil, nil, []string{} +} + +func (cm *containerManagerImpl) NewPodContainerManager() PodContainerManager { + return &podContainerManagerStub{} +} + +func (cm *containerManagerImpl) GetResources(pod *v1.Pod, container *v1.Container) (*kubecontainer.RunContainerOptions, error) { + return &kubecontainer.RunContainerOptions{}, nil +} + +func (cm *containerManagerImpl) UpdatePluginResources(*schedulercache.NodeInfo, *lifecycle.PodAdmitAttributes) error { + return nil +} + +func (cm *containerManagerImpl) InternalContainerLifecycle() InternalContainerLifecycle { + return &internalContainerLifecycleImpl{cpumanager.NewFakeManager()} +} + +func (cm *containerManagerImpl) GetPodCgroupRoot() string { + return "" } diff --git a/pkg/kubelet/cm/helpers.go b/pkg/kubelet/cm/helpers.go new file mode 100644 index 0000000000000..dbbea4a804041 --- /dev/null +++ b/pkg/kubelet/cm/helpers.go @@ -0,0 +1,46 @@ +/* +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 cm + +import ( + "k8s.io/api/core/v1" + evictionapi "k8s.io/kubernetes/pkg/kubelet/eviction/api" +) + +// hardEvictionReservation returns a resourcelist that includes reservation of resources based on hard eviction thresholds. +func hardEvictionReservation(thresholds []evictionapi.Threshold, capacity v1.ResourceList) v1.ResourceList { + if len(thresholds) == 0 { + return nil + } + ret := v1.ResourceList{} + for _, threshold := range thresholds { + if threshold.Operator != evictionapi.OpLessThan { + continue + } + switch threshold.Signal { + case evictionapi.SignalMemoryAvailable: + memoryCapacity := capacity[v1.ResourceMemory] + value := evictionapi.GetThresholdQuantity(threshold.Value, &memoryCapacity) + ret[v1.ResourceMemory] = *value + case evictionapi.SignalNodeFsAvailable: + storageCapacity := capacity[v1.ResourceEphemeralStorage] + value := evictionapi.GetThresholdQuantity(threshold.Value, &storageCapacity) + ret[v1.ResourceEphemeralStorage] = *value + } + } + return ret +} diff --git a/pkg/kubelet/cm/node_container_manager.go b/pkg/kubelet/cm/node_container_manager_linux.go similarity index 90% rename from pkg/kubelet/cm/node_container_manager.go rename to pkg/kubelet/cm/node_container_manager_linux.go index 1267b3f7d6e4a..52fb19983396b 100644 --- a/pkg/kubelet/cm/node_container_manager.go +++ b/pkg/kubelet/cm/node_container_manager_linux.go @@ -24,14 +24,12 @@ import ( "time" "github.com/golang/glog" - "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/types" utilfeature "k8s.io/apiserver/pkg/util/feature" kubefeatures "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/events" - evictionapi "k8s.io/kubernetes/pkg/kubelet/eviction/api" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) @@ -213,30 +211,6 @@ func (cm *containerManagerImpl) GetNodeAllocatableReservation() v1.ResourceList return result } -// hardEvictionReservation returns a resourcelist that includes reservation of resources based on hard eviction thresholds. -func hardEvictionReservation(thresholds []evictionapi.Threshold, capacity v1.ResourceList) v1.ResourceList { - if len(thresholds) == 0 { - return nil - } - ret := v1.ResourceList{} - for _, threshold := range thresholds { - if threshold.Operator != evictionapi.OpLessThan { - continue - } - switch threshold.Signal { - case evictionapi.SignalMemoryAvailable: - memoryCapacity := capacity[v1.ResourceMemory] - value := evictionapi.GetThresholdQuantity(threshold.Value, &memoryCapacity) - ret[v1.ResourceMemory] = *value - case evictionapi.SignalNodeFsAvailable: - storageCapacity := capacity[v1.ResourceEphemeralStorage] - value := evictionapi.GetThresholdQuantity(threshold.Value, &storageCapacity) - ret[v1.ResourceEphemeralStorage] = *value - } - } - return ret -} - // validateNodeAllocatable ensures that the user specified Node Allocatable Configuration doesn't reserve more than the node capacity. // Returns error if the configuration is invalid, nil otherwise. func (cm *containerManagerImpl) validateNodeAllocatable() error { diff --git a/pkg/kubelet/cm/node_container_manager_test.go b/pkg/kubelet/cm/node_container_manager_linux_test.go similarity index 100% rename from pkg/kubelet/cm/node_container_manager_test.go rename to pkg/kubelet/cm/node_container_manager_linux_test.go diff --git a/pkg/kubelet/dockershim/docker_sandbox.go b/pkg/kubelet/dockershim/docker_sandbox.go index b114bf052b468..744ebdf1c8e25 100644 --- a/pkg/kubelet/dockershim/docker_sandbox.go +++ b/pkg/kubelet/dockershim/docker_sandbox.go @@ -18,6 +18,7 @@ package dockershim import ( "context" + "encoding/json" "fmt" "os" "strings" @@ -27,7 +28,6 @@ import ( dockercontainer "github.com/docker/docker/api/types/container" dockerfilters "github.com/docker/docker/api/types/filters" "github.com/golang/glog" - utilerrors "k8s.io/apimachinery/pkg/util/errors" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" @@ -165,7 +165,16 @@ func (ds *dockerService) RunPodSandbox(ctx context.Context, r *runtimeapi.RunPod // on the host as well, to satisfy parts of the pod spec that aren't // recognized by the CNI standard yet. cID := kubecontainer.BuildContainerID(runtimeName, createResp.ID) - err = ds.network.SetUpPod(config.GetMetadata().Namespace, config.GetMetadata().Name, cID, config.Annotations) + networkOptions := make(map[string]string) + if dnsConfig := config.GetDnsConfig(); dnsConfig != nil { + // Build DNS options. + dnsOption, err := json.Marshal(dnsConfig) + if err != nil { + return nil, fmt.Errorf("failed to marshal dns config for pod %q: %v", config.Metadata.Name, err) + } + networkOptions["dns"] = string(dnsOption) + } + err = ds.network.SetUpPod(config.GetMetadata().Namespace, config.GetMetadata().Name, cID, config.Annotations, networkOptions) if err != nil { errList := []error{fmt.Errorf("failed to set up sandbox container %q network for pod %q: %v", createResp.ID, config.Metadata.Name, err)} diff --git a/pkg/kubelet/dockershim/docker_service_test.go b/pkg/kubelet/dockershim/docker_service_test.go index cc42ef5cabb4b..a1a0ee3e479b0 100644 --- a/pkg/kubelet/dockershim/docker_service_test.go +++ b/pkg/kubelet/dockershim/docker_service_test.go @@ -27,7 +27,6 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/util/clock" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" diff --git a/pkg/kubelet/dockershim/network/cni/BUILD b/pkg/kubelet/dockershim/network/cni/BUILD index 9396ba84e0345..6f9b6cfee9140 100644 --- a/pkg/kubelet/dockershim/network/cni/BUILD +++ b/pkg/kubelet/dockershim/network/cni/BUILD @@ -16,6 +16,7 @@ go_library( importpath = "k8s.io/kubernetes/pkg/kubelet/dockershim/network/cni", deps = [ "//pkg/kubelet/apis/config:go_default_library", + "//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library", "//pkg/kubelet/container:go_default_library", "//pkg/kubelet/dockershim/network:go_default_library", "//pkg/util/bandwidth:go_default_library", diff --git a/pkg/kubelet/dockershim/network/cni/cni.go b/pkg/kubelet/dockershim/network/cni/cni.go index c8fbdbb315f3e..86df39dd87b75 100644 --- a/pkg/kubelet/dockershim/network/cni/cni.go +++ b/pkg/kubelet/dockershim/network/cni/cni.go @@ -17,8 +17,10 @@ limitations under the License. package cni import ( + "encoding/json" "errors" "fmt" + "math" "sort" "strings" "sync" @@ -27,6 +29,7 @@ import ( cnitypes "github.com/containernetworking/cni/pkg/types" "github.com/golang/glog" kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/dockershim/network" "k8s.io/kubernetes/pkg/util/bandwidth" @@ -89,6 +92,18 @@ type cniIpRange struct { Subnet string `json:"subnet"` } +// cniDNSConfig maps to the windows CNI dns Capability. +// see: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md +// Note that dns capability is only used for Windows containers. +type cniDNSConfig struct { + // List of DNS servers of the cluster. + Servers []string `json:"servers,omitempty"` + // List of DNS search domains of the cluster. + Searches []string `json:"searches,omitempty"` + // List of DNS options. + Options []string `json:"options,omitempty"` +} + func SplitDirs(dirs string) []string { // Use comma rather than colon to work better with Windows too return strings.Split(dirs, ",") @@ -256,7 +271,7 @@ func (plugin *cniNetworkPlugin) Status() error { return plugin.checkInitialized() } -func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error { +func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error { if err := plugin.checkInitialized(); err != nil { return err } @@ -267,12 +282,12 @@ func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubec // Windows doesn't have loNetwork. It comes only with Linux if plugin.loNetwork != nil { - if _, err = plugin.addToNetwork(plugin.loNetwork, name, namespace, id, netnsPath, annotations); err != nil { + if _, err = plugin.addToNetwork(plugin.loNetwork, name, namespace, id, netnsPath, annotations, options); err != nil { return err } } - _, err = plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath, annotations) + _, err = plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath, annotations, options) return err } @@ -294,8 +309,8 @@ func podDesc(namespace, name string, id kubecontainer.ContainerID) string { return fmt.Sprintf("%s_%s/%s", namespace, name, id.ID) } -func (plugin *cniNetworkPlugin) addToNetwork(network *cniNetwork, podName string, podNamespace string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations map[string]string) (cnitypes.Result, error) { - rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podSandboxID, podNetnsPath, annotations) +func (plugin *cniNetworkPlugin) addToNetwork(network *cniNetwork, podName string, podNamespace string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations, options map[string]string) (cnitypes.Result, error) { + rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podSandboxID, podNetnsPath, annotations, options) if err != nil { glog.Errorf("Error adding network when building cni runtime conf: %v", err) return nil, err @@ -314,7 +329,7 @@ func (plugin *cniNetworkPlugin) addToNetwork(network *cniNetwork, podName string } func (plugin *cniNetworkPlugin) deleteFromNetwork(network *cniNetwork, podName string, podNamespace string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations map[string]string) error { - rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podSandboxID, podNetnsPath, annotations) + rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podSandboxID, podNetnsPath, annotations, nil) if err != nil { glog.Errorf("Error deleting network when building cni runtime conf: %v", err) return err @@ -334,7 +349,7 @@ func (plugin *cniNetworkPlugin) deleteFromNetwork(network *cniNetwork, podName s return nil } -func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations map[string]string) (*libcni.RuntimeConf, error) { +func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations, options map[string]string) (*libcni.RuntimeConf, error) { rt := &libcni.RuntimeConf{ ContainerID: podSandboxID.ID, NetNS: podNetnsPath, @@ -377,11 +392,11 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string bandwidthParam := cniBandwidthEntry{} if ingress != nil { bandwidthParam.IngressRate = int(ingress.Value() / 1000) - bandwidthParam.IngressBurst = 0 // default to no limit + bandwidthParam.IngressBurst = math.MaxInt32 // no limit } if egress != nil { bandwidthParam.EgressRate = int(egress.Value() / 1000) - bandwidthParam.EgressBurst = 0 // default to no limit + bandwidthParam.EgressBurst = math.MaxInt32 // no limit } rt.CapabilityArgs["bandwidth"] = bandwidthParam } @@ -389,5 +404,17 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string // Set the PodCIDR rt.CapabilityArgs["ipRanges"] = [][]cniIpRange{{{Subnet: plugin.podCidr}}} + // Set dns capability args. + if dnsOptions, ok := options["dns"]; ok { + dnsConfig := runtimeapi.DNSConfig{} + err := json.Unmarshal([]byte(dnsOptions), &dnsConfig) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal dns config %q: %v", dnsOptions, err) + } + if dnsParam := buildDNSCapabilities(&dnsConfig); dnsParam != nil { + rt.CapabilityArgs["dns"] = *dnsParam + } + } + return rt, nil } diff --git a/pkg/kubelet/dockershim/network/cni/cni_others.go b/pkg/kubelet/dockershim/network/cni/cni_others.go index 56f75ca3a960c..1712f8abe3c49 100644 --- a/pkg/kubelet/dockershim/network/cni/cni_others.go +++ b/pkg/kubelet/dockershim/network/cni/cni_others.go @@ -22,6 +22,7 @@ import ( "fmt" "github.com/containernetworking/cni/libcni" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/dockershim/network" ) @@ -75,3 +76,8 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name strin return &network.PodNetworkStatus{IP: ip}, nil } + +// buildDNSCapabilities builds cniDNSConfig from runtimeapi.DNSConfig. +func buildDNSCapabilities(dnsConfig *runtimeapi.DNSConfig) *cniDNSConfig { + return nil +} diff --git a/pkg/kubelet/dockershim/network/cni/cni_test.go b/pkg/kubelet/dockershim/network/cni/cni_test.go index 5d83d991e3bc6..0fbe58ad715b3 100644 --- a/pkg/kubelet/dockershim/network/cni/cni_test.go +++ b/pkg/kubelet/dockershim/network/cni/cni_test.go @@ -254,7 +254,7 @@ func TestCNIPlugin(t *testing.T) { bandwidthAnnotation["kubernetes.io/egress-bandwidth"] = "1M" // Set up the pod - err = plug.SetUpPod("podNamespace", "podName", containerID, bandwidthAnnotation) + err = plug.SetUpPod("podNamespace", "podName", containerID, bandwidthAnnotation, nil) if err != nil { t.Errorf("Expected nil: %v", err) } @@ -291,6 +291,7 @@ func TestCNIPlugin(t *testing.T) { } expectedBandwidth := map[string]interface{}{ "ingressRate": 1000.0, "egressRate": 1000.0, + "ingressBurst": 2147483647.0, "egressBurst": 2147483647.0, } if !reflect.DeepEqual(inputConfig.RuntimeConfig.Bandwidth, expectedBandwidth) { t.Errorf("mismatch in expected bandwidth. expected %v got %v", expectedBandwidth, inputConfig.RuntimeConfig.Bandwidth) diff --git a/pkg/kubelet/dockershim/network/cni/cni_windows.go b/pkg/kubelet/dockershim/network/cni/cni_windows.go index 0c90444550185..29f8f31ee5f86 100644 --- a/pkg/kubelet/dockershim/network/cni/cni_windows.go +++ b/pkg/kubelet/dockershim/network/cni/cni_windows.go @@ -23,6 +23,7 @@ import ( cniTypes020 "github.com/containernetworking/cni/pkg/types/020" "github.com/golang/glog" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/dockershim/network" ) @@ -42,7 +43,7 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name strin return nil, fmt.Errorf("CNI failed to retrieve network namespace path: %v", err) } - result, err := plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath, nil) + result, err := plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath, nil, nil) glog.V(5).Infof("GetPodNetworkStatus result %+v", result) if err != nil { @@ -59,3 +60,16 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name strin } return &network.PodNetworkStatus{IP: result020.IP4.IP.IP}, nil } + +// buildDNSCapabilities builds cniDNSConfig from runtimeapi.DNSConfig. +func buildDNSCapabilities(dnsConfig *runtimeapi.DNSConfig) *cniDNSConfig { + if dnsConfig != nil { + return &cniDNSConfig{ + Servers: dnsConfig.Servers, + Searches: dnsConfig.Searches, + Options: dnsConfig.Options, + } + } + + return nil +} diff --git a/pkg/kubelet/dockershim/network/kubenet/kubenet_linux.go b/pkg/kubelet/dockershim/network/kubenet/kubenet_linux.go index 0aec8c38cf76e..3611a84aec374 100644 --- a/pkg/kubelet/dockershim/network/kubenet/kubenet_linux.go +++ b/pkg/kubelet/dockershim/network/kubenet/kubenet_linux.go @@ -379,7 +379,7 @@ func (plugin *kubenetNetworkPlugin) setup(namespace string, name string, id kube return nil } -func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error { +func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error { plugin.mu.Lock() defer plugin.mu.Unlock() diff --git a/pkg/kubelet/dockershim/network/kubenet/kubenet_unsupported.go b/pkg/kubelet/dockershim/network/kubenet/kubenet_unsupported.go index ebb56e40ec3a8..d2a59126b3e82 100644 --- a/pkg/kubelet/dockershim/network/kubenet/kubenet_unsupported.go +++ b/pkg/kubelet/dockershim/network/kubenet/kubenet_unsupported.go @@ -42,7 +42,7 @@ func (plugin *kubenetNetworkPlugin) Name() string { return "kubenet" } -func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error { +func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error { return fmt.Errorf("Kubenet is not supported in this build") } diff --git a/pkg/kubelet/dockershim/network/plugins.go b/pkg/kubelet/dockershim/network/plugins.go index bcef49f77c58d..139d237e652a5 100644 --- a/pkg/kubelet/dockershim/network/plugins.go +++ b/pkg/kubelet/dockershim/network/plugins.go @@ -63,7 +63,7 @@ type NetworkPlugin interface { // SetUpPod is the method called after the infra container of // the pod has been created but before the other containers of the // pod are launched. - SetUpPod(namespace string, name string, podSandboxID kubecontainer.ContainerID, annotations map[string]string) error + SetUpPod(namespace string, name string, podSandboxID kubecontainer.ContainerID, annotations, options map[string]string) error // TearDownPod is the method called before a pod's infra container will be deleted TearDownPod(namespace string, name string, podSandboxID kubecontainer.ContainerID) error @@ -207,7 +207,7 @@ func (plugin *NoopNetworkPlugin) Capabilities() utilsets.Int { return utilsets.NewInt() } -func (plugin *NoopNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error { +func (plugin *NoopNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error { return nil } @@ -368,14 +368,14 @@ func (pm *PluginManager) GetPodNetworkStatus(podNamespace, podName string, id ku return netStatus, nil } -func (pm *PluginManager) SetUpPod(podNamespace, podName string, id kubecontainer.ContainerID, annotations map[string]string) error { +func (pm *PluginManager) SetUpPod(podNamespace, podName string, id kubecontainer.ContainerID, annotations, options map[string]string) error { defer recordOperation("set_up_pod", time.Now()) fullPodName := kubecontainer.BuildPodFullName(podName, podNamespace) pm.podLock(fullPodName).Lock() defer pm.podUnlock(fullPodName) glog.V(3).Infof("Calling network plugin %s to set up pod %q", pm.plugin.Name(), fullPodName) - if err := pm.plugin.SetUpPod(podNamespace, podName, id, annotations); err != nil { + if err := pm.plugin.SetUpPod(podNamespace, podName, id, annotations, options); err != nil { return fmt.Errorf("NetworkPlugin %s failed to set up pod %q network: %v", pm.plugin.Name(), fullPodName, err) } diff --git a/pkg/kubelet/dockershim/network/testing/mock_network_plugin.go b/pkg/kubelet/dockershim/network/testing/mock_network_plugin.go index 43e6d74490371..afb0752e1df09 100644 --- a/pkg/kubelet/dockershim/network/testing/mock_network_plugin.go +++ b/pkg/kubelet/dockershim/network/testing/mock_network_plugin.go @@ -102,7 +102,7 @@ func (_mr *_MockNetworkPluginRecorder) Name() *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Name") } -func (_m *MockNetworkPlugin) SetUpPod(_param0 string, _param1 string, _param2 container.ContainerID, annotations map[string]string) error { +func (_m *MockNetworkPlugin) SetUpPod(_param0 string, _param1 string, _param2 container.ContainerID, annotations, options map[string]string) error { ret := _m.ctrl.Call(_m, "SetUpPod", _param0, _param1, _param2) ret0, _ := ret[0].(error) return ret0 diff --git a/pkg/kubelet/dockershim/network/testing/plugins_test.go b/pkg/kubelet/dockershim/network/testing/plugins_test.go index 29ae5b148f51b..42c6ba9e8e1ef 100644 --- a/pkg/kubelet/dockershim/network/testing/plugins_test.go +++ b/pkg/kubelet/dockershim/network/testing/plugins_test.go @@ -108,7 +108,7 @@ func TestPluginManager(t *testing.T) { // concurrently. allCreatedWg.Wait() - if err := pm.SetUpPod("", name, id, nil); err != nil { + if err := pm.SetUpPod("", name, id, nil, nil); err != nil { t.Errorf("Failed to set up pod %q: %v", name, err) return } @@ -159,7 +159,7 @@ func (p *hookableFakeNetworkPlugin) Capabilities() utilsets.Int { return utilsets.NewInt() } -func (p *hookableFakeNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error { +func (p *hookableFakeNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error { if p.setupHook != nil { p.setupHook(namespace, name, id) } @@ -210,7 +210,7 @@ func TestMultiPodParallelNetworkOps(t *testing.T) { // Setup will block on the runner pod completing. If network // operations locking isn't correct (eg pod network operations // block other pods) setUpPod() will never return. - if err := pm.SetUpPod("", podName, containerID, nil); err != nil { + if err := pm.SetUpPod("", podName, containerID, nil, nil); err != nil { t.Errorf("Failed to set up waiter pod: %v", err) return } @@ -230,7 +230,7 @@ func TestMultiPodParallelNetworkOps(t *testing.T) { podName := "runner" containerID := kubecontainer.ContainerID{ID: podName} - if err := pm.SetUpPod("", podName, containerID, nil); err != nil { + if err := pm.SetUpPod("", podName, containerID, nil, nil); err != nil { t.Errorf("Failed to set up runner pod: %v", err) return } diff --git a/pkg/kubelet/dockershim/security_context_test.go b/pkg/kubelet/dockershim/security_context_test.go index 3fe3646906de0..0c1360226fa68 100644 --- a/pkg/kubelet/dockershim/security_context_test.go +++ b/pkg/kubelet/dockershim/security_context_test.go @@ -59,6 +59,18 @@ func TestModifyContainerConfig(t *testing.T) { }, isErr: false, }, + { + name: "container.SecurityContext.RunAsUsername and container.SecurityContext.RunAsUser set", + sc: &runtimeapi.LinuxContainerSecurityContext{ + RunAsUsername: username, + RunAsUser: &runtimeapi.Int64Value{Value: uid}, + }, + expected: &dockercontainer.Config{ + User: username, + }, + isErr: false, + }, + { name: "no RunAsUser value set", sc: &runtimeapi.LinuxContainerSecurityContext{}, @@ -94,6 +106,18 @@ func TestModifyContainerConfig(t *testing.T) { }, isErr: true, }, + { + name: "RunAsUser/RunAsUsername both set, RunAsGroup set", + sc: &runtimeapi.LinuxContainerSecurityContext{ + RunAsUser: &runtimeapi.Int64Value{Value: uid}, + RunAsUsername: username, + RunAsGroup: &runtimeapi.Int64Value{Value: gid}, + }, + expected: &dockercontainer.Config{ + User: "testuser:423", + }, + isErr: false, + }, } for _, tc := range cases { diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 9fe867519209b..fe7352f07c2d3 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -32,7 +32,6 @@ import ( "time" "github.com/golang/glog" - cadvisorapi "github.com/google/cadvisor/info/v1" cadvisorapiv2 "github.com/google/cadvisor/info/v2" "k8s.io/api/core/v1" @@ -777,7 +776,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, tokenManager := token.NewManager(kubeDeps.KubeClient) if !utilfeature.DefaultFeatureGate.Enabled(features.MountPropagation) { - glog.Warning("Mount propagation feature gate has been deprecated and will be removed in the next release") + return nil, fmt.Errorf("mount propagation feature gate has been deprecated and will be removed in 1.14") } klet.volumePluginMgr, err = @@ -1802,7 +1801,7 @@ func (kl *Kubelet) canRunPod(pod *v1.Pod) lifecycle.PodAdmitResult { // state every sync-frequency seconds. Never returns. func (kl *Kubelet) syncLoop(updates <-chan kubetypes.PodUpdate, handler SyncHandler) { glog.Info("Starting kubelet main sync loop.") - // The resyncTicker wakes up kubelet to checks if there are any pod workers + // The syncTicker wakes up kubelet to checks if there are any pod workers // that need to be sync'd. A one-second period is sufficient because the // sync interval is defaulted to 10s. syncTicker := time.NewTicker(time.Second) diff --git a/pkg/kubelet/kubelet_node_status.go b/pkg/kubelet/kubelet_node_status.go index 6b2fc07d7e3c5..7e5dac7964d9d 100644 --- a/pkg/kubelet/kubelet_node_status.go +++ b/pkg/kubelet/kubelet_node_status.go @@ -502,7 +502,6 @@ func (kl *Kubelet) defaultNodeStatusFuncs() []func(*v1.Node) error { setters = append(setters, nodestatus.VolumeLimits(kl.volumePluginMgr.ListVolumePluginWithLimits)) } setters = append(setters, - nodestatus.OutOfDiskCondition(kl.clock.Now, kl.recordNodeStatusEvent), nodestatus.MemoryPressureCondition(kl.clock.Now, kl.evictionManager.IsUnderMemoryPressure, kl.recordNodeStatusEvent), nodestatus.DiskPressureCondition(kl.clock.Now, kl.evictionManager.IsUnderDiskPressure, kl.recordNodeStatusEvent), nodestatus.PIDPressureCondition(kl.clock.Now, kl.evictionManager.IsUnderPIDPressure, kl.recordNodeStatusEvent), diff --git a/pkg/kubelet/kubelet_node_status_test.go b/pkg/kubelet/kubelet_node_status_test.go index a7085409405e5..af73cd5f378f8 100644 --- a/pkg/kubelet/kubelet_node_status_test.go +++ b/pkg/kubelet/kubelet_node_status_test.go @@ -233,14 +233,6 @@ func TestUpdateNewNodeStatus(t *testing.T) { Spec: v1.NodeSpec{}, Status: v1.NodeStatus{ Conditions: []v1.NodeCondition{ - { - Type: v1.NodeOutOfDisk, - Status: v1.ConditionFalse, - Reason: "KubeletHasSufficientDisk", - Message: fmt.Sprintf("kubelet has sufficient disk space available"), - LastHeartbeatTime: metav1.Time{}, - LastTransitionTime: metav1.Time{}, - }, { Type: v1.NodeMemoryPressure, Status: v1.ConditionFalse, @@ -317,7 +309,7 @@ func TestUpdateNewNodeStatus(t *testing.T) { assert.NoError(t, err) for i, cond := range updatedNode.Status.Conditions { assert.False(t, cond.LastHeartbeatTime.IsZero(), "LastHeartbeatTime for %v condition is zero", cond.Type) - assert.False(t, cond.LastTransitionTime.IsZero(), "LastTransitionTime for %v condition is zero", cond.Type) + assert.False(t, cond.LastTransitionTime.IsZero(), "LastTransitionTime for %v condition is zero", cond.Type) updatedNode.Status.Conditions[i].LastHeartbeatTime = metav1.Time{} updatedNode.Status.Conditions[i].LastTransitionTime = metav1.Time{} } @@ -359,14 +351,6 @@ func TestUpdateExistingNodeStatus(t *testing.T) { Spec: v1.NodeSpec{}, Status: v1.NodeStatus{ Conditions: []v1.NodeCondition{ - { - Type: v1.NodeOutOfDisk, - Status: v1.ConditionFalse, - Reason: "KubeletHasSufficientDisk", - Message: fmt.Sprintf("kubelet has sufficient disk space available"), - LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - LastTransitionTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - }, { Type: v1.NodeMemoryPressure, Status: v1.ConditionFalse, @@ -427,14 +411,6 @@ func TestUpdateExistingNodeStatus(t *testing.T) { Spec: v1.NodeSpec{}, Status: v1.NodeStatus{ Conditions: []v1.NodeCondition{ - { - Type: v1.NodeOutOfDisk, - Status: v1.ConditionFalse, - Reason: "KubeletHasSufficientDisk", - Message: fmt.Sprintf("kubelet has sufficient disk space available"), - LastHeartbeatTime: metav1.Time{}, - LastTransitionTime: metav1.Time{}, - }, { Type: v1.NodeMemoryPressure, Status: v1.ConditionFalse, @@ -640,14 +616,6 @@ func TestUpdateNodeStatusWithRuntimeStateError(t *testing.T) { Spec: v1.NodeSpec{}, Status: v1.NodeStatus{ Conditions: []v1.NodeCondition{ - { - Type: v1.NodeOutOfDisk, - Status: v1.ConditionFalse, - Reason: "KubeletHasSufficientDisk", - Message: fmt.Sprintf("kubelet has sufficient disk space available"), - LastHeartbeatTime: metav1.Time{}, - LastTransitionTime: metav1.Time{}, - }, { Type: v1.NodeMemoryPressure, Status: v1.ConditionFalse, diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 6703e3e8b019b..5216a7b2f42f2 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -128,7 +128,6 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol // makeMounts determines the mount points for the given container. func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap, mounter mountutil.Interface, expandEnvs []kubecontainer.EnvVar) ([]kubecontainer.Mount, func(), error) { - // Kubernetes only mounts on /etc/hosts if: // - container is not an infrastructure (pause) container // - container is not already mounting on /etc/hosts @@ -216,13 +215,13 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h } // Docker Volume Mounts fail on Windows if it is not of the form C:/ - containerPath := mount.MountPath - if runtime.GOOS == "windows" { - if (strings.HasPrefix(hostPath, "/") || strings.HasPrefix(hostPath, "\\")) && !strings.Contains(hostPath, ":") { - hostPath = "c:" + hostPath - } + if volumeutil.IsWindowsLocalPath(runtime.GOOS, hostPath) { + hostPath = volumeutil.MakeAbsolutePath(runtime.GOOS, hostPath) } - if !filepath.IsAbs(containerPath) { + + containerPath := mount.MountPath + // IsAbs returns false for UNC path/SMB shares/named pipes in Windows. So check for those specifically and skip MakeAbsolutePath + if !volumeutil.IsWindowsUNCPath(runtime.GOOS, containerPath) && !filepath.IsAbs(containerPath) { containerPath = volumeutil.MakeAbsolutePath(runtime.GOOS, containerPath) } @@ -263,10 +262,6 @@ func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.M return runtimeapi.MountPropagation_PROPAGATION_PRIVATE, nil } - if !utilfeature.DefaultFeatureGate.Enabled(features.MountPropagation) { - // mount propagation is disabled, use private as in the old versions - return runtimeapi.MountPropagation_PROPAGATION_PRIVATE, nil - } switch { case mountMode == nil: // PRIVATE is the default diff --git a/pkg/kubelet/kubelet_pods_linux_test.go b/pkg/kubelet/kubelet_pods_linux_test.go index 673a192ca32bb..f854c5093a719 100644 --- a/pkg/kubelet/kubelet_pods_linux_test.go +++ b/pkg/kubelet/kubelet_pods_linux_test.go @@ -23,7 +23,6 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" - utilfeature "k8s.io/apiserver/pkg/util/feature" _ "k8s.io/kubernetes/pkg/apis/core/install" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" @@ -247,12 +246,6 @@ func TestMakeMounts(t *testing.T) { HostNetwork: true, }, } - // test makeMounts with enabled mount propagation - err := utilfeature.DefaultFeatureGate.Set("MountPropagation=true") - if err != nil { - t.Errorf("Failed to enable feature gate for MountPropagation: %v", err) - return - } mounts, _, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes, fm, nil) @@ -270,24 +263,6 @@ func TestMakeMounts(t *testing.T) { } assert.Equal(t, tc.expectedMounts, mounts, "mounts of container %+v", tc.container) - - // test makeMounts with disabled mount propagation - err = utilfeature.DefaultFeatureGate.Set("MountPropagation=false") - if err != nil { - t.Errorf("Failed to enable feature gate for MountPropagation: %v", err) - return - } - mounts, _, err = makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes, fm, nil) - if !tc.expectErr { - expectedPrivateMounts := []kubecontainer.Mount{} - for _, mount := range tc.expectedMounts { - // all mounts are expected to be private when mount - // propagation is disabled - mount.Propagation = runtimeapi.MountPropagation_PROPAGATION_PRIVATE - expectedPrivateMounts = append(expectedPrivateMounts, mount) - } - assert.Equal(t, expectedPrivateMounts, mounts, "mounts of container %+v", tc.container) - } }) } } diff --git a/pkg/kubelet/kubelet_pods_windows_test.go b/pkg/kubelet/kubelet_pods_windows_test.go index 628c2ecdd7ae0..41a2cf6dc09aa 100644 --- a/pkg/kubelet/kubelet_pods_windows_test.go +++ b/pkg/kubelet/kubelet_pods_windows_test.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright 2017 The Kubernetes Authors. @@ -50,6 +48,21 @@ func TestMakeMountsWindows(t *testing.T) { Name: "disk5", ReadOnly: false, }, + { + MountPath: `\mnt\path6`, + Name: "disk6", + ReadOnly: false, + }, + { + MountPath: `/mnt/path7`, + Name: "disk7", + ReadOnly: false, + }, + { + MountPath: `\\.\pipe\pipe1`, + Name: "pipe1", + ReadOnly: false, + }, }, } @@ -57,6 +70,9 @@ func TestMakeMountsWindows(t *testing.T) { "disk": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/mnt/disk"}}, "disk4": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/mnt/host"}}, "disk5": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/var/lib/kubelet/podID/volumes/empty/disk5"}}, + "disk6": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `/mnt/disk6`}}, + "disk7": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `\mnt\disk7`}}, + "pipe1": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `\\.\pipe\pipe1`}}, } pod := v1.Pod{ @@ -97,6 +113,27 @@ func TestMakeMountsWindows(t *testing.T) { ReadOnly: false, SELinuxRelabel: false, }, + { + Name: "disk6", + ContainerPath: `c:\mnt\path6`, + HostPath: `c:/mnt/disk6`, + ReadOnly: false, + SELinuxRelabel: false, + }, + { + Name: "disk7", + ContainerPath: `c:/mnt/path7`, + HostPath: `c:\mnt\disk7`, + ReadOnly: false, + SELinuxRelabel: false, + }, + { + Name: "pipe1", + ContainerPath: `\\.\pipe\pipe1`, + HostPath: `\\.\pipe\pipe1`, + ReadOnly: false, + SELinuxRelabel: false, + }, } assert.Equal(t, expectedMounts, mounts, "mounts of container %+v", container) } diff --git a/pkg/kubelet/nodestatus/setters.go b/pkg/kubelet/nodestatus/setters.go index df557b25d7c31..bf049c4824b05 100644 --- a/pkg/kubelet/nodestatus/setters.go +++ b/pkg/kubelet/nodestatus/setters.go @@ -705,45 +705,6 @@ func DiskPressureCondition(nowFunc func() time.Time, // typically Kubelet.clock. } } -// OutOfDiskCondition returns a Setter that updates the v1.NodeOutOfDisk condition on the node. -// TODO(#65658): remove this condition -func OutOfDiskCondition(nowFunc func() time.Time, // typically Kubelet.clock.Now - recordEventFunc func(eventType, event string), // typically Kubelet.recordNodeStatusEvent -) Setter { - return func(node *v1.Node) error { - currentTime := metav1.NewTime(nowFunc()) - var nodeOODCondition *v1.NodeCondition - - // Check if NodeOutOfDisk condition already exists and if it does, just pick it up for update. - for i := range node.Status.Conditions { - if node.Status.Conditions[i].Type == v1.NodeOutOfDisk { - nodeOODCondition = &node.Status.Conditions[i] - } - } - - newOODCondition := nodeOODCondition == nil - if newOODCondition { - nodeOODCondition = &v1.NodeCondition{} - } - if nodeOODCondition.Status != v1.ConditionFalse { - nodeOODCondition.Type = v1.NodeOutOfDisk - nodeOODCondition.Status = v1.ConditionFalse - nodeOODCondition.Reason = "KubeletHasSufficientDisk" - nodeOODCondition.Message = "kubelet has sufficient disk space available" - nodeOODCondition.LastTransitionTime = currentTime - recordEventFunc(v1.EventTypeNormal, "NodeHasSufficientDisk") - } - - // Update the heartbeat time irrespective of all the conditions. - nodeOODCondition.LastHeartbeatTime = currentTime - - if newOODCondition { - node.Status.Conditions = append(node.Status.Conditions, *nodeOODCondition) - } - return nil - } -} - // VolumesInUse returns a Setter that updates the volumes in use on the node. func VolumesInUse(syncedFunc func() bool, // typically Kubelet.volumeManager.ReconcilerStatesHasBeenSynced volumesInUseFunc func() []v1.UniqueVolumeName, // typically Kubelet.volumeManager.GetVolumesInUse diff --git a/pkg/kubelet/pleg/generic.go b/pkg/kubelet/pleg/generic.go index 2befde16b97ed..bbe9a91365ecd 100644 --- a/pkg/kubelet/pleg/generic.go +++ b/pkg/kubelet/pleg/generic.go @@ -135,6 +135,9 @@ func (g *GenericPLEG) Start() { // relistThreshold is the maximum interval between two relist. func (g *GenericPLEG) Healthy() (bool, error) { relistTime := g.getRelistTime() + if relistTime.IsZero() { + return false, fmt.Errorf("pleg has yet to be successful") + } elapsed := g.clock.Since(relistTime) if elapsed > relistThreshold { return false, fmt.Errorf("pleg was last seen active %v ago; threshold is %v", elapsed, relistThreshold) diff --git a/pkg/kubelet/pleg/generic_test.go b/pkg/kubelet/pleg/generic_test.go index 468f98bffaeef..2e972ed45218c 100644 --- a/pkg/kubelet/pleg/generic_test.go +++ b/pkg/kubelet/pleg/generic_test.go @@ -346,9 +346,11 @@ func TestRemoveCacheEntry(t *testing.T) { func TestHealthy(t *testing.T) { testPleg := newTestGenericPLEG() + + // pleg should initially be unhealthy pleg, _, clock := testPleg.pleg, testPleg.runtime, testPleg.clock ok, _ := pleg.Healthy() - assert.True(t, ok, "pleg should be healthy") + assert.False(t, ok, "pleg should be unhealthy") // Advance the clock without any relisting. clock.Step(time.Minute * 10) @@ -361,6 +363,12 @@ func TestHealthy(t *testing.T) { clock.Step(time.Minute * 1) ok, _ = pleg.Healthy() assert.True(t, ok, "pleg should be healthy") + + // Advance by relistThreshold without any relisting. pleg should be unhealthy + // because it has been longer than relistThreshold since a relist occurred. + clock.Step(relistThreshold) + ok, _ = pleg.Healthy() + assert.False(t, ok, "pleg should be unhealthy") } func TestRelistWithReinspection(t *testing.T) { diff --git a/pkg/kubelet/token/BUILD b/pkg/kubelet/token/BUILD index df60c72f5246f..2591a4ec27522 100644 --- a/pkg/kubelet/token/BUILD +++ b/pkg/kubelet/token/BUILD @@ -21,6 +21,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//staging/src/k8s.io/api/authentication/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types: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", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", @@ -35,6 +36,7 @@ go_test( deps = [ "//staging/src/k8s.io/api/authentication/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", ], ) diff --git a/pkg/kubelet/token/OWNERS b/pkg/kubelet/token/OWNERS index 33904f77888e1..d914c0d7195a7 100644 --- a/pkg/kubelet/token/OWNERS +++ b/pkg/kubelet/token/OWNERS @@ -1,6 +1,7 @@ approvers: -- mikedanese +- sig-auth-serviceaccounts-approvers reviewers: -- mikedanese -- awly -- tallclair +- sig-auth-serviceaccounts-reviewers +labels: +- sig/auth + diff --git a/pkg/kubelet/token/token_manager.go b/pkg/kubelet/token/token_manager.go index ec755faa393ff..75086c86b976e 100644 --- a/pkg/kubelet/token/token_manager.go +++ b/pkg/kubelet/token/token_manager.go @@ -26,6 +26,7 @@ import ( "github.com/golang/glog" authenticationv1 "k8s.io/api/authentication/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/clock" "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" @@ -98,6 +99,18 @@ func (m *Manager) GetServiceAccountToken(namespace, name string, tr *authenticat return tr, nil } +// DeleteServiceAccountToken should be invoked when pod got deleted. It simply +// clean token manager cache. +func (m *Manager) DeleteServiceAccountToken(podUID types.UID) { + m.cacheMutex.Lock() + defer m.cacheMutex.Unlock() + for k, tr := range m.cache { + if tr.Spec.BoundObjectRef.UID == podUID { + delete(m.cache, k) + } + } +} + func (m *Manager) cleanup() { m.cacheMutex.Lock() defer m.cacheMutex.Unlock() diff --git a/pkg/kubelet/token/token_manager_test.go b/pkg/kubelet/token/token_manager_test.go index 2cc2766808f15..3bf7724cd9a64 100644 --- a/pkg/kubelet/token/token_manager_test.go +++ b/pkg/kubelet/token/token_manager_test.go @@ -23,6 +23,7 @@ import ( authenticationv1 "k8s.io/api/authentication/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/clock" ) @@ -175,6 +176,189 @@ func TestRequiresRefresh(t *testing.T) { } } +func TestDeleteServiceAccountToken(t *testing.T) { + type request struct { + name, namespace string + tr authenticationv1.TokenRequest + shouldFail bool + } + + cases := []struct { + name string + requestIndex []int + deletePodUID []types.UID + expLeftIndex []int + }{ + { + name: "delete none with all success requests", + requestIndex: []int{0, 1, 2}, + expLeftIndex: []int{0, 1, 2}, + }, + { + name: "delete one with all success requests", + requestIndex: []int{0, 1, 2}, + deletePodUID: []types.UID{"fake-uid-1"}, + expLeftIndex: []int{1, 2}, + }, + { + name: "delete two with all success requests", + requestIndex: []int{0, 1, 2}, + deletePodUID: []types.UID{"fake-uid-1", "fake-uid-3"}, + expLeftIndex: []int{1}, + }, + { + name: "delete all with all suceess requests", + requestIndex: []int{0, 1, 2}, + deletePodUID: []types.UID{"fake-uid-1", "fake-uid-2", "fake-uid-3"}, + }, + { + name: "delete no pod with failed requests", + requestIndex: []int{0, 1, 2, 3}, + deletePodUID: []types.UID{}, + expLeftIndex: []int{0, 1, 2}, + }, + { + name: "delete other pod with failed requests", + requestIndex: []int{0, 1, 2, 3}, + deletePodUID: []types.UID{"fake-uid-2"}, + expLeftIndex: []int{0, 2}, + }, + { + name: "delete no pod with request which success after failure", + requestIndex: []int{0, 1, 2, 3, 4}, + deletePodUID: []types.UID{}, + expLeftIndex: []int{0, 1, 2, 4}, + }, + { + name: "delete the pod which success after failure", + requestIndex: []int{0, 1, 2, 3, 4}, + deletePodUID: []types.UID{"fake-uid-4"}, + expLeftIndex: []int{0, 1, 2}, + }, + { + name: "delete other pod with request which success after failure", + requestIndex: []int{0, 1, 2, 3, 4}, + deletePodUID: []types.UID{"fake-uid-1"}, + expLeftIndex: []int{1, 2, 4}, + }, + { + name: "delete some pod not in the set", + requestIndex: []int{0, 1, 2}, + deletePodUID: []types.UID{"fake-uid-100", "fake-uid-200"}, + expLeftIndex: []int{0, 1, 2}, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + requests := []request{ + { + name: "fake-name-1", + namespace: "fake-namespace-1", + tr: authenticationv1.TokenRequest{ + Spec: authenticationv1.TokenRequestSpec{ + BoundObjectRef: &authenticationv1.BoundObjectReference{ + UID: "fake-uid-1", + Name: "fake-name-1", + }, + }, + }, + shouldFail: false, + }, + { + name: "fake-name-2", + namespace: "fake-namespace-2", + tr: authenticationv1.TokenRequest{ + Spec: authenticationv1.TokenRequestSpec{ + BoundObjectRef: &authenticationv1.BoundObjectReference{ + UID: "fake-uid-2", + Name: "fake-name-2", + }, + }, + }, + shouldFail: false, + }, + { + name: "fake-name-3", + namespace: "fake-namespace-3", + tr: authenticationv1.TokenRequest{ + Spec: authenticationv1.TokenRequestSpec{ + BoundObjectRef: &authenticationv1.BoundObjectReference{ + UID: "fake-uid-3", + Name: "fake-name-3", + }, + }, + }, + shouldFail: false, + }, + { + name: "fake-name-4", + namespace: "fake-namespace-4", + tr: authenticationv1.TokenRequest{ + Spec: authenticationv1.TokenRequestSpec{ + BoundObjectRef: &authenticationv1.BoundObjectReference{ + UID: "fake-uid-4", + Name: "fake-name-4", + }, + }, + }, + shouldFail: true, + }, + { + //exactly the same with last one, besides it will success + name: "fake-name-4", + namespace: "fake-namespace-4", + tr: authenticationv1.TokenRequest{ + Spec: authenticationv1.TokenRequestSpec{ + BoundObjectRef: &authenticationv1.BoundObjectReference{ + UID: "fake-uid-4", + Name: "fake-name-4", + }, + }, + }, + shouldFail: false, + }, + } + testMgr := NewManager(nil) + testMgr.clock = clock.NewFakeClock(time.Time{}.Add(30 * 24 * time.Hour)) + + successGetToken := func(_, _ string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) { + tr.Status = authenticationv1.TokenRequestStatus{ + ExpirationTimestamp: metav1.Time{Time: testMgr.clock.Now().Add(10 * time.Hour)}, + } + return tr, nil + } + failGetToken := func(_, _ string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) { + return nil, fmt.Errorf("fail tr") + } + + for _, index := range c.requestIndex { + req := requests[index] + if req.shouldFail { + testMgr.getToken = failGetToken + } else { + testMgr.getToken = successGetToken + } + testMgr.GetServiceAccountToken(req.namespace, req.name, &req.tr) + } + + for _, uid := range c.deletePodUID { + testMgr.DeleteServiceAccountToken(uid) + } + if len(c.expLeftIndex) != len(testMgr.cache) { + t.Errorf("%s got unexpected result: expected left cache size is %d, got %d", c.name, len(c.expLeftIndex), len(testMgr.cache)) + } + for _, leftIndex := range c.expLeftIndex { + r := requests[leftIndex] + _, ok := testMgr.get(keyFunc(r.name, r.namespace, &r.tr)) + if !ok { + t.Errorf("%s got unexpected result: expected token request %v exist in cache, but not", c.name, r) + } + } + }) + } +} + type fakeTokenGetter struct { count int tr *authenticationv1.TokenRequest diff --git a/pkg/kubelet/util/pluginwatcher/README b/pkg/kubelet/util/pluginwatcher/README deleted file mode 100644 index c8b6cc284401f..0000000000000 --- a/pkg/kubelet/util/pluginwatcher/README +++ /dev/null @@ -1,34 +0,0 @@ -This folder contains a utility, pluginwatcher, for Kubelet to register -different types of node-level plugins such as device plugins or CSI plugins. -It discovers plugins by monitoring inotify events under the directory returned by -kubelet.getPluginsDir(). Lets refer this directory as PluginsSockDir. -For any discovered plugin, pluginwatcher issues Registration.GetInfo grpc call -to get plugin type, name and supported service API versions. For any registered plugin type, -pluginwatcher calls the registered callback function with the received plugin -name, supported service API versions, and the full socket path. The Kubelet -component that receives this callback can acknowledge or reject the plugin -according to its own logic, and use the socket path to establish its service -communication with any API version supported by the plugin. - -Here are the general rules that Kubelet plugin developers should follow: -- Run as 'root' user. Currently creating socket under PluginsSockDir, a root owned directory, requires - plugin process to be running as 'root'. - -- Implements the Registration service specified in - pkg/kubelet/apis/pluginregistration/v*/api.proto. - -- The plugin name sent during Registration.GetInfo grpc should be unique - for the given plugin type (CSIPlugin or DevicePlugin). - -- The socket path needs to be unique within one directory, in normal case, - each plugin type has its own sub directory, but the design does support socket file - under any sub directory of PluginSockDir. - -- A plugin should clean up its own socket upon exiting or when a new instance - comes up. A plugin should NOT remove any sockets belonging to other plugins. - -- A plugin should make sure it has service ready for any supported service API - version listed in the PluginInfo. - -- For an example plugin implementation, take a look at example_plugin.go - included in this directory. diff --git a/pkg/kubelet/util/pluginwatcher/README.md b/pkg/kubelet/util/pluginwatcher/README.md new file mode 100644 index 0000000000000..1b68c9c50799c --- /dev/null +++ b/pkg/kubelet/util/pluginwatcher/README.md @@ -0,0 +1,79 @@ +# Plugin Registration Service + +This folder contains a utility, pluginwatcher, for Kubelet to register +different types of node-level plugins such as device plugins or CSI plugins. +It discovers plugins by monitoring inotify events under the directory returned by +kubelet.getPluginsDir(). We will refer to this directory as PluginsDir. + +Plugins are expected to implement the gRPC registration service specified in +pkg/kubelet/apis/pluginregistration/v*/api.proto. + +## Plugin Discovery + +The pluginwatcher service will discover plugins in the PluginDir when they +place a socket in that directory or, at Kubelet start if the socket is already +there. + +This socket filename should not start with a '.' as it will be ignored. + + +## gRPC Service Lifecycle + +For any discovered plugin, kubelet will issue a Registration.GetInfo gRPC call +to get plugin type, name, endpoint and supported service API versions. + +Kubelet will then go through a plugin initialization phase where it will issue +Plugin specific calls (e.g: DevicePlugin::GetDevicePluginOptions). + +Once Kubelet determines that it is ready to use your plugin it will issue a +Registration.NotifyRegistrationStatus gRPC call. + +If the plugin removes its socket from the PluginDir this will be interpreted +as a plugin Deregistration + + +## gRPC Service Overview + +Here are the general rules that Kubelet plugin developers should follow: +- Run plugin as 'root' user. Currently creating socket under PluginsDir, a root owned + directory, requires plugin process to be running as 'root'. + +- The plugin name sent during Registration.GetInfo grpc should be unique + for the given plugin type (CSIPlugin or DevicePlugin). + +- The socket path needs to be unique within one directory, in normal case, + each plugin type has its own sub directory, but the design does support socket file + under any sub directory of PluginSockDir. + +- A plugin should clean up its own socket upon exiting or when a new instance + comes up. A plugin should NOT remove any sockets belonging to other plugins. + +- A plugin should make sure it has service ready for any supported service API + version listed in the PluginInfo. + +- For an example plugin implementation, take a look at example_plugin.go + included in this directory. + + +# Kubelet Interface + +For any kubelet components using the pluginwatcher module, you will need to +implement the PluginHandler interface defined in the types.go file. + +The interface is documented and the implementations are registered with the +pluginwatcher module in kubelet.go by calling AddHandler(pluginType, handler). + + +The lifecycle follows a simple state machine: + + Validate -> Register -> DeRegister + ^ + + | | + +--------- + + +The pluginwatcher calls the functions with the received plugin name, supported +service API versions and the endpoint to call the plugin on. + +The Kubelet component that receives this callback can acknowledge or reject +the plugin according to its own logic, and use the socket path to establish +its service communication with any API version supported by the plugin. diff --git a/pkg/kubelet/volume_host.go b/pkg/kubelet/volume_host.go index 7c1b9c7f03aec..35b7d78460109 100644 --- a/pkg/kubelet/volume_host.go +++ b/pkg/kubelet/volume_host.go @@ -200,6 +200,10 @@ func (kvh *kubeletVolumeHost) GetServiceAccountTokenFunc() func(namespace, name return kvh.tokenManager.GetServiceAccountToken } +func (kvh *kubeletVolumeHost) DeleteServiceAccountTokenFunc() func(podUID types.UID) { + return kvh.tokenManager.DeleteServiceAccountToken +} + func (kvh *kubeletVolumeHost) GetNodeLabels() (map[string]string, error) { node, err := kvh.kubelet.GetNode() if err != nil { diff --git a/pkg/kubemark/BUILD b/pkg/kubemark/BUILD index 40d0f495fba87..d00990bb6ba9a 100644 --- a/pkg/kubemark/BUILD +++ b/pkg/kubemark/BUILD @@ -34,6 +34,7 @@ go_library( "//pkg/util/oom:go_default_library", "//pkg/util/sysctl:go_default_library", "//pkg/volume/emptydir:go_default_library", + "//pkg/volume/projected:go_default_library", "//pkg/volume/secret:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/pkg/kubemark/hollow_kubelet.go b/pkg/kubemark/hollow_kubelet.go index 18b2a6095cf65..15bec8a9c92f8 100644 --- a/pkg/kubemark/hollow_kubelet.go +++ b/pkg/kubemark/hollow_kubelet.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/oom" "k8s.io/kubernetes/pkg/volume/emptydir" + "k8s.io/kubernetes/pkg/volume/projected" "k8s.io/kubernetes/pkg/volume/secret" "k8s.io/kubernetes/test/utils" @@ -64,6 +65,7 @@ func NewHollowKubelet( // ----------------- volumePlugins := emptydir.ProbeVolumePlugins() volumePlugins = append(volumePlugins, secret.ProbeVolumePlugins()...) + volumePlugins = append(volumePlugins, projected.ProbeVolumePlugins()...) d := &kubelet.Dependencies{ KubeClient: client, HeartbeatClient: client, diff --git a/pkg/master/BUILD b/pkg/master/BUILD index eb5bae69a6952..85c3d605bfda7 100644 --- a/pkg/master/BUILD +++ b/pkg/master/BUILD @@ -36,7 +36,6 @@ go_library( "//pkg/apis/settings/install:go_default_library", "//pkg/apis/storage/install:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", "//pkg/features:go_default_library", "//pkg/kubeapiserver/options:go_default_library", "//pkg/kubelet/client:go_default_library", @@ -51,7 +50,6 @@ go_library( "//pkg/registry/batch/rest:go_default_library", "//pkg/registry/certificates/rest:go_default_library", "//pkg/registry/coordination/rest:go_default_library", - "//pkg/registry/core/endpoint/storage:go_default_library", "//pkg/registry/core/rangeallocation:go_default_library", "//pkg/registry/core/rest:go_default_library", "//pkg/registry/core/service/ipallocator:go_default_library", diff --git a/pkg/master/client_ca_hook.go b/pkg/master/client_ca_hook.go index 4e5d4ff5198a4..8b0e023ed0339 100644 --- a/pkg/master/client_ca_hook.go +++ b/pkg/master/client_ca_hook.go @@ -69,7 +69,7 @@ func (h ClientCARegistrationHook) PostStartHook(hookContext genericapiserver.Pos // tryToWriteClientCAs is here for unit testing with a fake client. This is a wait.ConditionFunc so the bool // indicates if the condition was met. True when its finished, false when it should retry. func (h ClientCARegistrationHook) tryToWriteClientCAs(client coreclient.CoreInterface) (bool, error) { - if err := createNamespaceIfNeeded(client, metav1.NamespaceSystem); err != nil { + if err := createNamespaceIfNeededWithInternalClient(client, metav1.NamespaceSystem); err != nil { utilruntime.HandleError(err) return false, nil } diff --git a/pkg/master/client_util.go b/pkg/master/client_util.go index 3868fbae5c563..9323f1984f765 100644 --- a/pkg/master/client_util.go +++ b/pkg/master/client_util.go @@ -17,13 +17,34 @@ limitations under the License. package master import ( + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" api "k8s.io/kubernetes/pkg/apis/core" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" ) -func createNamespaceIfNeeded(c coreclient.NamespacesGetter, ns string) error { +func createNamespaceIfNeeded(c corev1client.NamespacesGetter, ns string) error { + if _, err := c.Namespaces().Get(ns, metav1.GetOptions{}); err == nil { + // the namespace already exists + return nil + } + newNs := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: ns, + Namespace: "", + }, + } + _, err := c.Namespaces().Create(newNs) + if err != nil && errors.IsAlreadyExists(err) { + err = nil + } + return err +} + +// TODO(yue9944882): Remove it once we switch ClientCARegistrationHook to external types +func createNamespaceIfNeededWithInternalClient(c coreclient.NamespacesGetter, ns string) error { if _, err := c.Namespaces().Get(ns, metav1.GetOptions{}); err == nil { // the namespace already exists return nil diff --git a/pkg/master/controller.go b/pkg/master/controller.go index f4cb74d8da4b8..e2e6f24e68638 100644 --- a/pkg/master/controller.go +++ b/pkg/master/controller.go @@ -31,8 +31,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" genericapiserver "k8s.io/apiserver/pkg/server" utilfeature "k8s.io/apiserver/pkg/util/feature" - api "k8s.io/kubernetes/pkg/apis/core" - coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/master/reconcilers" "k8s.io/kubernetes/pkg/registry/core/rangeallocation" @@ -49,9 +48,9 @@ const kubernetesServiceName = "kubernetes" // "default", "kube-system" and "kube-public" namespaces, and provide the IP // repair check on service IPs type Controller struct { - ServiceClient coreclient.ServicesGetter - NamespaceClient coreclient.NamespacesGetter - EventClient coreclient.EventsGetter + ServiceClient corev1client.ServicesGetter + NamespaceClient corev1client.NamespacesGetter + EventClient corev1client.EventsGetter ServiceClusterIPRegistry rangeallocation.RangeRegistry ServiceClusterIPInterval time.Duration @@ -72,8 +71,8 @@ type Controller struct { // ServiceIP indicates where the kubernetes service will live. It may not be nil. ServiceIP net.IP ServicePort int - ExtraServicePorts []api.ServicePort - ExtraEndpointPorts []api.EndpointPort + ExtraServicePorts []corev1.ServicePort + ExtraEndpointPorts []corev1.EndpointPort PublicServicePort int KubernetesServiceNodePort int @@ -81,7 +80,7 @@ type Controller struct { } // NewBootstrapController returns a controller for watching the core capabilities of the master -func (c *completedConfig) NewBootstrapController(legacyRESTStorage corerest.LegacyRESTStorage, serviceClient coreclient.ServicesGetter, nsClient coreclient.NamespacesGetter, eventClient coreclient.EventsGetter) *Controller { +func (c *completedConfig) NewBootstrapController(legacyRESTStorage corerest.LegacyRESTStorage, serviceClient corev1client.ServicesGetter, nsClient corev1client.NamespacesGetter, eventClient corev1client.EventsGetter) *Controller { _, publicServicePort, err := c.GenericConfig.SecureServing.HostPort() if err != nil { glog.Fatalf("failed to get listener address: %v", err) @@ -230,17 +229,17 @@ func (c *Controller) UpdateKubernetesService(reconcile bool) error { // createPortAndServiceSpec creates an array of service ports. // If the NodePort value is 0, just the servicePort is used, otherwise, a node port is exposed. -func createPortAndServiceSpec(servicePort int, targetServicePort int, nodePort int, servicePortName string, extraServicePorts []api.ServicePort) ([]api.ServicePort, api.ServiceType) { +func createPortAndServiceSpec(servicePort int, targetServicePort int, nodePort int, servicePortName string, extraServicePorts []corev1.ServicePort) ([]corev1.ServicePort, corev1.ServiceType) { //Use the Cluster IP type for the service port if NodePort isn't provided. //Otherwise, we will be binding the master service to a NodePort. - servicePorts := []api.ServicePort{{Protocol: api.ProtocolTCP, + servicePorts := []corev1.ServicePort{{Protocol: corev1.ProtocolTCP, Port: int32(servicePort), Name: servicePortName, TargetPort: intstr.FromInt(targetServicePort)}} - serviceType := api.ServiceTypeClusterIP + serviceType := corev1.ServiceTypeClusterIP if nodePort > 0 { servicePorts[0].NodePort = int32(nodePort) - serviceType = api.ServiceTypeNodePort + serviceType = corev1.ServiceTypeNodePort } if extraServicePorts != nil { servicePorts = append(servicePorts, extraServicePorts...) @@ -249,8 +248,8 @@ func createPortAndServiceSpec(servicePort int, targetServicePort int, nodePort i } // createEndpointPortSpec creates an array of endpoint ports -func createEndpointPortSpec(endpointPort int, endpointPortName string, extraEndpointPorts []api.EndpointPort) []api.EndpointPort { - endpointPorts := []api.EndpointPort{{Protocol: api.ProtocolTCP, +func createEndpointPortSpec(endpointPort int, endpointPortName string, extraEndpointPorts []corev1.EndpointPort) []corev1.EndpointPort { + endpointPorts := []corev1.EndpointPort{{Protocol: corev1.ProtocolTCP, Port: int32(endpointPort), Name: endpointPortName, }} @@ -262,7 +261,7 @@ func createEndpointPortSpec(endpointPort int, endpointPortName string, extraEndp // CreateMasterServiceIfNeeded will create the specified service if it // doesn't already exist. -func (c *Controller) CreateOrUpdateMasterServiceIfNeeded(serviceName string, serviceIP net.IP, servicePorts []api.ServicePort, serviceType api.ServiceType, reconcile bool) error { +func (c *Controller) CreateOrUpdateMasterServiceIfNeeded(serviceName string, serviceIP net.IP, servicePorts []corev1.ServicePort, serviceType corev1.ServiceType, reconcile bool) error { if s, err := c.ServiceClient.Services(metav1.NamespaceDefault).Get(serviceName, metav1.GetOptions{}); err == nil { // The service already exists. if reconcile { @@ -274,18 +273,18 @@ func (c *Controller) CreateOrUpdateMasterServiceIfNeeded(serviceName string, ser } return nil } - svc := &api.Service{ + svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: serviceName, Namespace: metav1.NamespaceDefault, Labels: map[string]string{"provider": "kubernetes", "component": "apiserver"}, }, - Spec: api.ServiceSpec{ + Spec: corev1.ServiceSpec{ Ports: servicePorts, // maintained by this code, not by the pod selector Selector: nil, ClusterIP: serviceIP.String(), - SessionAffinity: api.ServiceAffinityNone, + SessionAffinity: corev1.ServiceAffinityNone, Type: serviceType, }, } diff --git a/pkg/master/controller_test.go b/pkg/master/controller_test.go index 8e31a71ccfc1b..cfab7074ca208 100644 --- a/pkg/master/controller_test.go +++ b/pkg/master/controller_test.go @@ -21,11 +21,11 @@ import ( "reflect" "testing" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/kubernetes/fake" core "k8s.io/client-go/testing" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/master/reconcilers" ) @@ -38,23 +38,23 @@ func TestReconcileEndpoints(t *testing.T) { testName string serviceName string ip string - endpointPorts []api.EndpointPort + endpointPorts []corev1.EndpointPort additionalMasters int - endpoints *api.EndpointsList - expectUpdate *api.Endpoints // nil means none expected - expectCreate *api.Endpoints // nil means none expected + endpoints *corev1.EndpointsList + expectUpdate *corev1.Endpoints // nil means none expected + expectCreate *corev1.Endpoints // nil means none expected }{ { testName: "no existing endpoints", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpoints: nil, - expectCreate: &api.Endpoints{ + expectCreate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -62,13 +62,13 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints satisfy", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, @@ -77,21 +77,21 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints satisfy but too many", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}, {IP: "4.3.2.1"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "4.3.2.1"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -99,33 +99,33 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints satisfy but too many + extra masters", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, additionalMasters: 3, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -133,33 +133,33 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints satisfy but too many + extra masters + delete first", serviceName: "foo", ip: "4.3.2.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, additionalMasters: 3, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -167,17 +167,17 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints satisfy and endpoint addresses length less than master count", serviceName: "foo", ip: "4.3.2.2", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, additionalMasters: 3, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, @@ -187,27 +187,27 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints current IP missing and address length less than master count", serviceName: "foo", ip: "4.3.2.2", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, additionalMasters: 3, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "4.3.2.1"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -215,21 +215,21 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints wrong name", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("bar"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectCreate: &api.Endpoints{ + expectCreate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -237,21 +237,21 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints wrong IP", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "4.3.2.1"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "4.3.2.1"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -259,21 +259,21 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints wrong port", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 9090, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 9090, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -281,21 +281,21 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints wrong protocol", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "UDP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "UDP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -303,21 +303,21 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints wrong port name", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -325,17 +325,17 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints extra service ports satisfy", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{ + endpointPorts: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, {Name: "baz", Port: 1010, Protocol: "TCP"}, }, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, {Name: "baz", Port: 1010, Protocol: "TCP"}, @@ -348,24 +348,24 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints extra service ports missing port", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{ + endpointPorts: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, }, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, }, @@ -376,13 +376,13 @@ func TestReconcileEndpoints(t *testing.T) { testName: "no existing sctp endpoints", serviceName: "boo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "boo", Port: 7777, Protocol: "SCTP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "boo", Port: 7777, Protocol: "SCTP"}}, endpoints: nil, - expectCreate: &api.Endpoints{ + expectCreate: &corev1.Endpoints{ ObjectMeta: om("boo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "boo", Port: 7777, Protocol: "SCTP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "boo", Port: 7777, Protocol: "SCTP"}}, }}, }, }, @@ -440,26 +440,26 @@ func TestReconcileEndpoints(t *testing.T) { testName string serviceName string ip string - endpointPorts []api.EndpointPort + endpointPorts []corev1.EndpointPort additionalMasters int - endpoints *api.EndpointsList - expectUpdate *api.Endpoints // nil means none expected - expectCreate *api.Endpoints // nil means none expected + endpoints *corev1.EndpointsList + expectUpdate *corev1.Endpoints // nil means none expected + expectCreate *corev1.Endpoints // nil means none expected }{ { testName: "existing endpoints extra service ports missing port no update", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{ + endpointPorts: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, }, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, @@ -469,24 +469,24 @@ func TestReconcileEndpoints(t *testing.T) { testName: "existing endpoints extra service ports, wrong ports, wrong IP", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{ + endpointPorts: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, }, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "4.3.2.1"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "4.3.2.1"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -494,13 +494,13 @@ func TestReconcileEndpoints(t *testing.T) { testName: "no existing endpoints", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpoints: nil, - expectCreate: &api.Endpoints{ + expectCreate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -565,27 +565,27 @@ func TestCreateOrUpdateMasterService(t *testing.T) { create_tests := []struct { testName string serviceName string - servicePorts []api.ServicePort - serviceType api.ServiceType - expectCreate *api.Service // nil means none expected + servicePorts []corev1.ServicePort + serviceType corev1.ServiceType + expectCreate *corev1.Service // nil means none expected }{ { testName: "service does not exist", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - expectCreate: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + expectCreate: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, }, @@ -606,7 +606,7 @@ func TestCreateOrUpdateMasterService(t *testing.T) { t.Errorf("case %q: unexpected creations: %v", test.testName, creates) } else { obj := creates[0].GetObject() - if e, a := test.expectCreate.Spec, obj.(*api.Service).Spec; !reflect.DeepEqual(e, a) { + if e, a := test.expectCreate.Spec, obj.(*corev1.Service).Spec; !reflect.DeepEqual(e, a) { t.Errorf("case %q: expected create:\n%#v\ngot:\n%#v\n", test.testName, e, a) } } @@ -619,254 +619,254 @@ func TestCreateOrUpdateMasterService(t *testing.T) { reconcile_tests := []struct { testName string serviceName string - servicePorts []api.ServicePort - serviceType api.ServiceType - service *api.Service - expectUpdate *api.Service // nil means none expected + servicePorts []corev1.ServicePort + serviceType corev1.ServiceType + service *corev1.Service + expectUpdate *corev1.Service // nil means none expected }{ { testName: "service definition wrong port", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8000, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, - expectUpdate: &api.Service{ + expectUpdate: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, }, { testName: "service definition missing port", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, {Name: "baz", Port: 1000, Protocol: "TCP", TargetPort: intstr.FromInt(1000)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, - expectUpdate: &api.Service{ + expectUpdate: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, {Name: "baz", Port: 1000, Protocol: "TCP", TargetPort: intstr.FromInt(1000)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, }, { testName: "service definition incorrect port", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "bar", Port: 1000, Protocol: "UDP", TargetPort: intstr.FromInt(1000)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, - expectUpdate: &api.Service{ + expectUpdate: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, }, { testName: "service definition incorrect port name", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 1000, Protocol: "UDP", TargetPort: intstr.FromInt(1000)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, - expectUpdate: &api.Service{ + expectUpdate: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, }, { testName: "service definition incorrect target port", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(1000)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, - expectUpdate: &api.Service{ + expectUpdate: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, }, { testName: "service definition incorrect protocol", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "UDP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, - expectUpdate: &api.Service{ + expectUpdate: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, }, { testName: "service definition has incorrect type", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeNodePort, }, }, - expectUpdate: &api.Service{ + expectUpdate: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, }, { testName: "service definition satisfies", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, expectUpdate: nil, @@ -891,7 +891,7 @@ func TestCreateOrUpdateMasterService(t *testing.T) { t.Errorf("case %q: unexpected updates: %v", test.testName, updates) } else { obj := updates[0].GetObject() - if e, a := test.expectUpdate.Spec, obj.(*api.Service).Spec; !reflect.DeepEqual(e, a) { + if e, a := test.expectUpdate.Spec, obj.(*corev1.Service).Spec; !reflect.DeepEqual(e, a) { t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a) } } @@ -904,28 +904,28 @@ func TestCreateOrUpdateMasterService(t *testing.T) { non_reconcile_tests := []struct { testName string serviceName string - servicePorts []api.ServicePort - serviceType api.ServiceType - service *api.Service - expectUpdate *api.Service // nil means none expected + servicePorts []corev1.ServicePort + serviceType corev1.ServiceType + service *corev1.Service + expectUpdate *corev1.Service // nil means none expected }{ { testName: "service definition wrong port, no expected update", serviceName: "foo", - servicePorts: []api.ServicePort{ + servicePorts: []corev1.ServicePort{ {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, }, - serviceType: api.ServiceTypeClusterIP, - service: &api.Service{ + serviceType: corev1.ServiceTypeClusterIP, + service: &corev1.Service{ ObjectMeta: om("foo"), - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ {Name: "foo", Port: 1000, Protocol: "TCP", TargetPort: intstr.FromInt(1000)}, }, Selector: nil, ClusterIP: "1.2.3.4", - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, }, }, expectUpdate: nil, @@ -950,7 +950,7 @@ func TestCreateOrUpdateMasterService(t *testing.T) { t.Errorf("case %q: unexpected updates: %v", test.testName, updates) } else { obj := updates[0].GetObject() - if e, a := test.expectUpdate.Spec, obj.(*api.Service).Spec; !reflect.DeepEqual(e, a) { + if e, a := test.expectUpdate.Spec, obj.(*corev1.Service).Spec; !reflect.DeepEqual(e, a) { t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a) } } diff --git a/pkg/master/master.go b/pkg/master/master.go index ef22ec2f3a6f2..97c86986117f1 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -68,13 +68,10 @@ import ( "k8s.io/client-go/informers" corev1client "k8s.io/client-go/kubernetes/typed/core/v1" api "k8s.io/kubernetes/pkg/apis/core" - coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" - internalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options" kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" "k8s.io/kubernetes/pkg/master/reconcilers" "k8s.io/kubernetes/pkg/master/tunneler" - endpointsstorage "k8s.io/kubernetes/pkg/registry/core/endpoint/storage" "k8s.io/kubernetes/pkg/routes" "k8s.io/kubernetes/pkg/serviceaccount" nodeutil "k8s.io/kubernetes/pkg/util/node" @@ -145,10 +142,10 @@ type ExtraConfig struct { // service because this pkg is linked by out-of-tree projects // like openshift which want to use the GenericAPIServer but also do // more stuff. - ExtraServicePorts []api.ServicePort + ExtraServicePorts []apiv1.ServicePort // Additional ports to be exposed on the GenericAPIServer endpoints // Port names should align with ports defined in ExtraServicePorts - ExtraEndpointPorts []api.EndpointPort + ExtraEndpointPorts []apiv1.EndpointPort // If non-zero, the "kubernetes" services uses this port as NodePort. KubernetesServiceNodePort int @@ -175,7 +172,6 @@ type ExtraConfig struct { APIAudiences authenticator.Audiences VersionedInformers informers.SharedInformerFactory - InternalInformers internalinformers.SharedInformerFactory } type Config struct { @@ -208,7 +204,7 @@ type Master struct { } func (c *Config) createMasterCountReconciler() reconcilers.EndpointReconciler { - endpointClient := coreclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig) + endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig) return reconcilers.NewMasterCountEndpointReconciler(c.ExtraConfig.MasterCount, endpointClient) } @@ -217,6 +213,7 @@ func (c *Config) createNoneReconciler() reconcilers.EndpointReconciler { } func (c *Config) createLeaseReconciler() reconcilers.EndpointReconciler { + endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig) ttl := c.ExtraConfig.MasterEndpointReconcileTTL config, err := c.ExtraConfig.StorageFactory.NewConfig(api.Resource("apiServerIPInfo")) if err != nil { @@ -226,18 +223,8 @@ func (c *Config) createLeaseReconciler() reconcilers.EndpointReconciler { if err != nil { glog.Fatalf("Error creating storage factory: %v", err) } - endpointConfig, err := c.ExtraConfig.StorageFactory.NewConfig(api.Resource("endpoints")) - if err != nil { - glog.Fatalf("Error getting storage config: %v", err) - } - endpointsStorage := endpointsstorage.NewREST(generic.RESTOptions{ - StorageConfig: endpointConfig, - Decorator: generic.UndecoratedStorage, - DeleteCollectionWorkers: 0, - ResourcePrefix: c.ExtraConfig.StorageFactory.ResourcePrefix(api.Resource("endpoints")), - }) masterLeases := reconcilers.NewLeases(leaseStorage, "/masterleases/", ttl) - return reconcilers.NewLeaseEndpointReconciler(endpointsStorage.Store, masterLeases) + return reconcilers.NewLeaseEndpointReconciler(endpointClient, masterLeases) } func (c *Config) createEndpointReconciler() reconcilers.EndpointReconciler { @@ -377,12 +364,6 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) } m.GenericAPIServer.AddPostStartHookOrDie("ca-registration", c.ExtraConfig.ClientCARegistrationHook.PostStartHook) - m.GenericAPIServer.AddPostStartHookOrDie("start-kube-apiserver-informers", func(context genericapiserver.PostStartHookContext) error { - if c.ExtraConfig.InternalInformers != nil { - c.ExtraConfig.InternalInformers.Start(context.StopCh) - } - return nil - }) return m, nil } @@ -394,7 +375,7 @@ func (m *Master) InstallLegacyAPI(c *completedConfig, restOptionsGetter generic. } controllerName := "bootstrap-controller" - coreClient := coreclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig) + coreClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig) bootstrapController := c.NewBootstrapController(legacyRESTStorage, coreClient, coreClient, coreClient) m.GenericAPIServer.AddPostStartHookOrDie(controllerName, bootstrapController.PostStartHook) m.GenericAPIServer.AddPreShutdownHookOrDie(controllerName, bootstrapController.PreShutdownHook) diff --git a/pkg/master/reconcilers/BUILD b/pkg/master/reconcilers/BUILD index 09d274bea8248..97375d1453ee1 100644 --- a/pkg/master/reconcilers/BUILD +++ b/pkg/master/reconcilers/BUILD @@ -12,15 +12,14 @@ go_library( importpath = "k8s.io/kubernetes/pkg/master/reconcilers", visibility = ["//visibility:public"], deps = [ - "//pkg/api/endpoints:go_default_library", - "//pkg/apis/core:go_default_library", - "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", + "//pkg/api/v1/endpoints:go_default_library", + "//staging/src/k8s.io/api/core/v1: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:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", "//staging/src/k8s.io/client-go/util/retry:go_default_library", "//vendor/github.com/golang/glog:go_default_library", ], @@ -31,9 +30,9 @@ go_test( srcs = ["lease_test.go"], embed = [":go_default_library"], deps = [ - "//pkg/apis/core:go_default_library", - "//pkg/registry/registrytest:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", ], ) diff --git a/pkg/master/reconcilers/lease.go b/pkg/master/reconcilers/lease.go index 65a397db0b327..ec9f7ba63a88b 100644 --- a/pkg/master/reconcilers/lease.go +++ b/pkg/master/reconcilers/lease.go @@ -30,14 +30,14 @@ import ( "github.com/golang/glog" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kruntime "k8s.io/apimachinery/pkg/runtime" apirequest "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/storage" - "k8s.io/kubernetes/pkg/api/endpoints" - api "k8s.io/kubernetes/pkg/apis/core" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + endpointsv1 "k8s.io/kubernetes/pkg/api/v1/endpoints" ) // Leases is an interface which assists in managing the set of active masters @@ -62,7 +62,7 @@ var _ Leases = &storageLeases{} // ListLeases retrieves a list of the current master IPs from storage func (s *storageLeases) ListLeases() ([]string, error) { - ipInfoList := &api.EndpointsList{} + ipInfoList := &corev1.EndpointsList{} if err := s.storage.List(apirequest.NewDefaultContext(), s.baseKey, "0", storage.Everything, ipInfoList); err != nil { return nil, err } @@ -80,12 +80,12 @@ func (s *storageLeases) ListLeases() ([]string, error) { // UpdateLease resets the TTL on a master IP in storage func (s *storageLeases) UpdateLease(ip string) error { key := path.Join(s.baseKey, ip) - return s.storage.GuaranteedUpdate(apirequest.NewDefaultContext(), key, &api.Endpoints{}, true, nil, func(input kruntime.Object, respMeta storage.ResponseMeta) (kruntime.Object, *uint64, error) { + return s.storage.GuaranteedUpdate(apirequest.NewDefaultContext(), key, &corev1.Endpoints{}, true, nil, func(input kruntime.Object, respMeta storage.ResponseMeta) (kruntime.Object, *uint64, error) { // just make sure we've got the right IP set, and then refresh the TTL - existing := input.(*api.Endpoints) - existing.Subsets = []api.EndpointSubset{ + existing := input.(*corev1.Endpoints) + existing.Subsets = []corev1.EndpointSubset{ { - Addresses: []api.EndpointAddress{{IP: ip}}, + Addresses: []corev1.EndpointAddress{{IP: ip}}, }, } @@ -106,7 +106,7 @@ func (s *storageLeases) UpdateLease(ip string) error { // RemoveLease removes the lease on a master IP in storage func (s *storageLeases) RemoveLease(ip string) error { - return s.storage.Delete(apirequest.NewDefaultContext(), s.baseKey+"/"+ip, &api.Endpoints{}, nil) + return s.storage.Delete(apirequest.NewDefaultContext(), s.baseKey+"/"+ip, &corev1.Endpoints{}, nil) } // NewLeases creates a new etcd-based Leases implementation. @@ -119,16 +119,16 @@ func NewLeases(storage storage.Interface, baseKey string, leaseTime time.Duratio } type leaseEndpointReconciler struct { - endpointStorage rest.StandardStorage + endpointClient corev1client.EndpointsGetter masterLeases Leases stopReconcilingCalled bool reconcilingLock sync.Mutex } // NewLeaseEndpointReconciler creates a new LeaseEndpoint reconciler -func NewLeaseEndpointReconciler(endpointStorage rest.StandardStorage, masterLeases Leases) EndpointReconciler { +func NewLeaseEndpointReconciler(endpointClient corev1client.EndpointsGetter, masterLeases Leases) EndpointReconciler { return &leaseEndpointReconciler{ - endpointStorage: endpointStorage, + endpointClient: endpointClient, masterLeases: masterLeases, stopReconcilingCalled: false, } @@ -141,7 +141,7 @@ func NewLeaseEndpointReconciler(endpointStorage rest.StandardStorage, masterLeas // expire. ReconcileEndpoints will notice that the endpoints object is // different from the directory listing, and update the endpoints object // accordingly. -func (r *leaseEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error { +func (r *leaseEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []corev1.EndpointPort, reconcilePorts bool) error { r.reconcilingLock.Lock() defer r.reconcilingLock.Unlock() @@ -159,25 +159,21 @@ func (r *leaseEndpointReconciler) ReconcileEndpoints(serviceName string, ip net. return r.doReconcile(serviceName, endpointPorts, reconcilePorts) } -func (r *leaseEndpointReconciler) doReconcile(serviceName string, endpointPorts []api.EndpointPort, reconcilePorts bool) error { - ctx := apirequest.NewDefaultContext() - - // Retrieve the current list of endpoints... - var e *api.Endpoints - obj, err := r.endpointStorage.Get(ctx, serviceName, &metav1.GetOptions{}) +func (r *leaseEndpointReconciler) doReconcile(serviceName string, endpointPorts []corev1.EndpointPort, reconcilePorts bool) error { + e, err := r.endpointClient.Endpoints(corev1.NamespaceDefault).Get(serviceName, metav1.GetOptions{}) + shouldCreate := false if err != nil { if !errors.IsNotFound(err) { return err } - e = &api.Endpoints{ + shouldCreate = true + e = &corev1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: serviceName, - Namespace: api.NamespaceDefault, + Namespace: corev1.NamespaceDefault, }, } - } else { - e = obj.(*api.Endpoints) } // ... and the list of master IP keys from etcd @@ -201,21 +197,21 @@ func (r *leaseEndpointReconciler) doReconcile(serviceName string, endpointPorts if !formatCorrect { // Something is egregiously wrong, just re-make the endpoints record. - e.Subsets = []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{}, + e.Subsets = []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{}, Ports: endpointPorts, }} } if !formatCorrect || !ipCorrect { // repopulate the addresses according to the expected IPs from etcd - e.Subsets[0].Addresses = make([]api.EndpointAddress, len(masterIPs)) + e.Subsets[0].Addresses = make([]corev1.EndpointAddress, len(masterIPs)) for ind, ip := range masterIPs { - e.Subsets[0].Addresses[ind] = api.EndpointAddress{IP: ip} + e.Subsets[0].Addresses[ind] = corev1.EndpointAddress{IP: ip} } // Lexicographic order is retained by this step. - e.Subsets = endpoints.RepackSubsets(e.Subsets) + e.Subsets = endpointsv1.RepackSubsets(e.Subsets) } if !portsCorrect { @@ -224,7 +220,13 @@ func (r *leaseEndpointReconciler) doReconcile(serviceName string, endpointPorts } glog.Warningf("Resetting endpoints for master service %q to %v", serviceName, masterIPs) - _, _, err = r.endpointStorage.Update(ctx, e.Name, rest.DefaultUpdatedObjectInfo(e), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) + if shouldCreate { + if _, err = r.endpointClient.Endpoints(corev1.NamespaceDefault).Create(e); errors.IsAlreadyExists(err) { + err = nil + } + } else { + _, err = r.endpointClient.Endpoints(corev1.NamespaceDefault).Update(e) + } return err } @@ -236,7 +238,7 @@ func (r *leaseEndpointReconciler) doReconcile(serviceName string, endpointPorts // * ipsCorrect when the addresses in the endpoints match the expected addresses list // * portsCorrect is true when endpoint ports exactly match provided ports. // portsCorrect is only evaluated when reconcilePorts is set to true. -func checkEndpointSubsetFormatWithLease(e *api.Endpoints, expectedIPs []string, ports []api.EndpointPort, reconcilePorts bool) (formatCorrect bool, ipsCorrect bool, portsCorrect bool) { +func checkEndpointSubsetFormatWithLease(e *corev1.Endpoints, expectedIPs []string, ports []corev1.EndpointPort, reconcilePorts bool) (formatCorrect bool, ipsCorrect bool, portsCorrect bool) { if len(e.Subsets) != 1 { return false, false, false } @@ -281,7 +283,7 @@ func checkEndpointSubsetFormatWithLease(e *api.Endpoints, expectedIPs []string, return true, ipsCorrect, portsCorrect } -func (r *leaseEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []api.EndpointPort) error { +func (r *leaseEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []corev1.EndpointPort) error { r.reconcilingLock.Lock() defer r.reconcilingLock.Unlock() r.stopReconcilingCalled = true diff --git a/pkg/master/reconcilers/lease_test.go b/pkg/master/reconcilers/lease_test.go index 97000d39fba49..3c8402a786797 100644 --- a/pkg/master/reconcilers/lease_test.go +++ b/pkg/master/reconcilers/lease_test.go @@ -26,9 +26,9 @@ import ( "reflect" "testing" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/registry/registrytest" + "k8s.io/client-go/kubernetes/fake" ) type fakeLeases struct { @@ -76,7 +76,7 @@ func (f *fakeLeases) GetUpdatedKeys() []string { } func TestLeaseEndpointReconciler(t *testing.T) { - ns := api.NamespaceDefault + ns := corev1.NamespaceDefault om := func(name string) metav1.ObjectMeta { return metav1.ObjectMeta{Namespace: ns, Name: name} } @@ -84,22 +84,22 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName string serviceName string ip string - endpointPorts []api.EndpointPort + endpointPorts []corev1.EndpointPort endpointKeys []string - endpoints *api.EndpointsList - expectUpdate *api.Endpoints // nil means none expected + endpoints *corev1.EndpointsList + expectUpdate *corev1.Endpoints // nil means none expected }{ { testName: "no existing endpoints", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpoints: nil, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -107,13 +107,13 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints satisfy", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, @@ -122,14 +122,14 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints satisfy + refresh existing key", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpointKeys: []string{"1.2.3.4"}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, @@ -138,21 +138,21 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints satisfy but too many", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}, {IP: "4.3.2.1"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "4.3.2.1"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -160,33 +160,33 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints satisfy but too many + extra masters", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpointKeys: []string{"1.2.3.4", "4.3.2.2", "4.3.2.3", "4.3.2.4"}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -194,33 +194,33 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints satisfy but too many + extra masters + delete first", serviceName: "foo", ip: "4.3.2.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpointKeys: []string{"4.3.2.1", "4.3.2.2", "4.3.2.3", "4.3.2.4"}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -228,27 +228,27 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints current IP missing", serviceName: "foo", ip: "4.3.2.2", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpointKeys: []string{"4.3.2.1"}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "4.3.2.1"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "4.3.2.1"}, {IP: "4.3.2.2"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -256,21 +256,21 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints wrong name", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("bar"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -278,21 +278,21 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints wrong IP", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "4.3.2.1"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "4.3.2.1"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -300,21 +300,21 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints wrong port", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 9090, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 9090, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -322,21 +322,21 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints wrong protocol", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "UDP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "UDP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -344,21 +344,21 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints wrong port name", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpointPorts: []corev1.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}}, + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -366,17 +366,17 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints extra service ports satisfy", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{ + endpointPorts: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, {Name: "baz", Port: 1010, Protocol: "TCP"}, }, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, {Name: "baz", Port: 1010, Protocol: "TCP"}, @@ -389,24 +389,24 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints extra service ports missing port", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{ + endpointPorts: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, }, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, }, @@ -417,24 +417,29 @@ func TestLeaseEndpointReconciler(t *testing.T) { for _, test := range reconcileTests { fakeLeases := newFakeLeases() fakeLeases.SetKeys(test.endpointKeys) - registry := ®istrytest.EndpointRegistry{ - Endpoints: test.endpoints, + clientset := fake.NewSimpleClientset() + if test.endpoints != nil { + for _, ep := range test.endpoints.Items { + if _, err := clientset.CoreV1().Endpoints(ep.Namespace).Create(&ep); err != nil { + t.Errorf("case %q: unexpected error: %v", test.testName, err) + continue + } + } } - r := NewLeaseEndpointReconciler(registry, fakeLeases) + r := NewLeaseEndpointReconciler(clientset.CoreV1(), fakeLeases) err := r.ReconcileEndpoints(test.serviceName, net.ParseIP(test.ip), test.endpointPorts, true) if err != nil { t.Errorf("case %q: unexpected error: %v", test.testName, err) } + actualEndpoints, err := clientset.CoreV1().Endpoints(corev1.NamespaceDefault).Get(test.serviceName, metav1.GetOptions{}) + if err != nil { + t.Errorf("case %q: unexpected error: %v", test.testName, err) + } if test.expectUpdate != nil { - if len(registry.Updates) != 1 { - t.Errorf("case %q: unexpected updates: %v", test.testName, registry.Updates) - } else if e, a := test.expectUpdate, ®istry.Updates[0]; !reflect.DeepEqual(e, a) { + if e, a := test.expectUpdate, actualEndpoints; !reflect.DeepEqual(e, a) { t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a) } } - if test.expectUpdate == nil && len(registry.Updates) > 0 { - t.Errorf("case %q: no update expected, yet saw: %v", test.testName, registry.Updates) - } if updatedKeys := fakeLeases.GetUpdatedKeys(); len(updatedKeys) != 1 || updatedKeys[0] != test.ip { t.Errorf("case %q: expected the master's IP to be refreshed, but the following IPs were refreshed instead: %v", test.testName, updatedKeys) } @@ -444,25 +449,25 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName string serviceName string ip string - endpointPorts []api.EndpointPort + endpointPorts []corev1.EndpointPort endpointKeys []string - endpoints *api.EndpointsList - expectUpdate *api.Endpoints // nil means none expected + endpoints *corev1.EndpointsList + expectUpdate *corev1.Endpoints // nil means none expected }{ { testName: "existing endpoints extra service ports missing port no update", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{ + endpointPorts: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, }, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, @@ -472,24 +477,24 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "existing endpoints extra service ports, wrong ports, wrong IP", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{ + endpointPorts: []corev1.EndpointPort{ {Name: "foo", Port: 8080, Protocol: "TCP"}, {Name: "bar", Port: 1000, Protocol: "TCP"}, }, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "4.3.2.1"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "4.3.2.1"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -497,13 +502,13 @@ func TestLeaseEndpointReconciler(t *testing.T) { testName: "no existing endpoints", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpoints: nil, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -512,24 +517,29 @@ func TestLeaseEndpointReconciler(t *testing.T) { t.Run(test.testName, func(t *testing.T) { fakeLeases := newFakeLeases() fakeLeases.SetKeys(test.endpointKeys) - registry := ®istrytest.EndpointRegistry{ - Endpoints: test.endpoints, + clientset := fake.NewSimpleClientset() + if test.endpoints != nil { + for _, ep := range test.endpoints.Items { + if _, err := clientset.CoreV1().Endpoints(ep.Namespace).Create(&ep); err != nil { + t.Errorf("case %q: unexpected error: %v", test.testName, err) + continue + } + } } - r := NewLeaseEndpointReconciler(registry, fakeLeases) + r := NewLeaseEndpointReconciler(clientset.CoreV1(), fakeLeases) err := r.ReconcileEndpoints(test.serviceName, net.ParseIP(test.ip), test.endpointPorts, false) if err != nil { t.Errorf("case %q: unexpected error: %v", test.testName, err) } + actualEndpoints, err := clientset.CoreV1().Endpoints(corev1.NamespaceDefault).Get(test.serviceName, metav1.GetOptions{}) + if err != nil { + t.Errorf("case %q: unexpected error: %v", test.testName, err) + } if test.expectUpdate != nil { - if len(registry.Updates) != 1 { - t.Errorf("case %q: unexpected updates: %v", test.testName, registry.Updates) - } else if e, a := test.expectUpdate, ®istry.Updates[0]; !reflect.DeepEqual(e, a) { + if e, a := test.expectUpdate, actualEndpoints; !reflect.DeepEqual(e, a) { t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a) } } - if test.expectUpdate == nil && len(registry.Updates) > 0 { - t.Errorf("case %q: no update expected, yet saw: %v", test.testName, registry.Updates) - } if updatedKeys := fakeLeases.GetUpdatedKeys(); len(updatedKeys) != 1 || updatedKeys[0] != test.ip { t.Errorf("case %q: expected the master's IP to be refreshed, but the following IPs were refreshed instead: %v", test.testName, updatedKeys) } @@ -538,7 +548,7 @@ func TestLeaseEndpointReconciler(t *testing.T) { } func TestLeaseStopReconciling(t *testing.T) { - ns := api.NamespaceDefault + ns := corev1.NamespaceDefault om := func(name string) metav1.ObjectMeta { return metav1.ObjectMeta{Namespace: ns, Name: name} } @@ -546,40 +556,40 @@ func TestLeaseStopReconciling(t *testing.T) { testName string serviceName string ip string - endpointPorts []api.EndpointPort + endpointPorts []corev1.EndpointPort endpointKeys []string - endpoints *api.EndpointsList - expectUpdate *api.Endpoints // nil means none expected + endpoints *corev1.EndpointsList + expectUpdate *corev1.Endpoints // nil means none expected }{ { testName: "successful stop reconciling", serviceName: "foo", ip: "1.2.3.4", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpointKeys: []string{"1.2.3.4", "4.3.2.2", "4.3.2.3", "4.3.2.4"}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, - expectUpdate: &api.Endpoints{ + expectUpdate: &corev1.Endpoints{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }, }, @@ -587,19 +597,19 @@ func TestLeaseStopReconciling(t *testing.T) { testName: "stop reconciling with ip not in endpoint ip list", serviceName: "foo", ip: "5.6.7.8", - endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpointKeys: []string{"1.2.3.4", "4.3.2.2", "4.3.2.3", "4.3.2.4"}, - endpoints: &api.EndpointsList{ - Items: []api.Endpoints{{ + endpoints: &corev1.EndpointsList{ + Items: []corev1.Endpoints{{ ObjectMeta: om("foo"), - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ + Subsets: []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "4.3.2.2"}, {IP: "4.3.2.3"}, {IP: "4.3.2.4"}, }, - Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, + Ports: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, }}, }}, }, @@ -609,24 +619,27 @@ func TestLeaseStopReconciling(t *testing.T) { t.Run(test.testName, func(t *testing.T) { fakeLeases := newFakeLeases() fakeLeases.SetKeys(test.endpointKeys) - registry := ®istrytest.EndpointRegistry{ - Endpoints: test.endpoints, + clientset := fake.NewSimpleClientset() + for _, ep := range test.endpoints.Items { + if _, err := clientset.CoreV1().Endpoints(ep.Namespace).Create(&ep); err != nil { + t.Errorf("case %q: unexpected error: %v", test.testName, err) + continue + } } - r := NewLeaseEndpointReconciler(registry, fakeLeases) + r := NewLeaseEndpointReconciler(clientset.CoreV1(), fakeLeases) err := r.StopReconciling(test.serviceName, net.ParseIP(test.ip), test.endpointPorts) if err != nil { t.Errorf("case %q: unexpected error: %v", test.testName, err) } + actualEndpoints, err := clientset.CoreV1().Endpoints(corev1.NamespaceDefault).Get(test.serviceName, metav1.GetOptions{}) + if err != nil { + t.Errorf("case %q: unexpected error: %v", test.testName, err) + } if test.expectUpdate != nil { - if len(registry.Updates) != 1 { - t.Errorf("case %q: unexpected updates: %v", test.testName, registry.Updates) - } else if e, a := test.expectUpdate, ®istry.Updates[0]; !reflect.DeepEqual(e, a) { + if e, a := test.expectUpdate, actualEndpoints; !reflect.DeepEqual(e, a) { t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a) } } - if test.expectUpdate == nil && len(registry.Updates) > 0 { - t.Errorf("case %q: no update expected, yet saw: %v", test.testName, registry.Updates) - } for _, key := range fakeLeases.GetUpdatedKeys() { if key == test.ip { t.Errorf("case %q: Found ip %s in leases but shouldn't be there", test.testName, key) diff --git a/pkg/master/reconcilers/mastercount.go b/pkg/master/reconcilers/mastercount.go index d7aa4c77185a2..479883e70a266 100644 --- a/pkg/master/reconcilers/mastercount.go +++ b/pkg/master/reconcilers/mastercount.go @@ -22,26 +22,26 @@ import ( "sync" "github.com/golang/glog" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/util/retry" - "k8s.io/kubernetes/pkg/api/endpoints" - api "k8s.io/kubernetes/pkg/apis/core" - coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" + endpointsv1 "k8s.io/kubernetes/pkg/api/v1/endpoints" ) // masterCountEndpointReconciler reconciles endpoints based on a specified expected number of // masters. masterCountEndpointReconciler implements EndpointReconciler. type masterCountEndpointReconciler struct { masterCount int - endpointClient coreclient.EndpointsGetter + endpointClient corev1client.EndpointsGetter stopReconcilingCalled bool reconcilingLock sync.Mutex } // NewMasterCountEndpointReconciler creates a new EndpointReconciler that reconciles based on a // specified expected number of masters. -func NewMasterCountEndpointReconciler(masterCount int, endpointClient coreclient.EndpointsGetter) EndpointReconciler { +func NewMasterCountEndpointReconciler(masterCount int, endpointClient corev1client.EndpointsGetter) EndpointReconciler { return &masterCountEndpointReconciler{ masterCount: masterCount, endpointClient: endpointClient, @@ -60,7 +60,7 @@ func NewMasterCountEndpointReconciler(masterCount int, endpointClient coreclient // * All apiservers MUST know and agree on the number of apiservers expected // to be running (c.masterCount). // * ReconcileEndpoints is called periodically from all apiservers. -func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error { +func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []corev1.EndpointPort, reconcilePorts bool) error { r.reconcilingLock.Lock() defer r.reconcilingLock.Unlock() @@ -70,7 +70,7 @@ func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, i e, err := r.endpointClient.Endpoints(metav1.NamespaceDefault).Get(serviceName, metav1.GetOptions{}) if err != nil { - e = &api.Endpoints{ + e = &corev1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: serviceName, Namespace: metav1.NamespaceDefault, @@ -79,8 +79,8 @@ func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, i } if errors.IsNotFound(err) { // Simply create non-existing endpoints for the service. - e.Subsets = []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: ip.String()}}, + e.Subsets = []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: ip.String()}}, Ports: endpointPorts, }} _, err = r.endpointClient.Endpoints(metav1.NamespaceDefault).Create(e) @@ -92,8 +92,8 @@ func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, i formatCorrect, ipCorrect, portsCorrect := checkEndpointSubsetFormat(e, ip.String(), endpointPorts, r.masterCount, reconcilePorts) if !formatCorrect { // Something is egregiously wrong, just re-make the endpoints record. - e.Subsets = []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: ip.String()}}, + e.Subsets = []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{IP: ip.String()}}, Ports: endpointPorts, }} glog.Warningf("Resetting endpoints for master service %q to %#v", serviceName, e) @@ -105,10 +105,10 @@ func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, i } if !ipCorrect { // We *always* add our own IP address. - e.Subsets[0].Addresses = append(e.Subsets[0].Addresses, api.EndpointAddress{IP: ip.String()}) + e.Subsets[0].Addresses = append(e.Subsets[0].Addresses, corev1.EndpointAddress{IP: ip.String()}) // Lexicographic order is retained by this step. - e.Subsets = endpoints.RepackSubsets(e.Subsets) + e.Subsets = endpointsv1.RepackSubsets(e.Subsets) // If too many IP addresses, remove the ones lexicographically after our // own IP address. Given the requirements stated at the top of @@ -137,7 +137,7 @@ func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, i return err } -func (r *masterCountEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []api.EndpointPort) error { +func (r *masterCountEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []corev1.EndpointPort) error { r.reconcilingLock.Lock() defer r.reconcilingLock.Unlock() r.stopReconcilingCalled = true @@ -152,14 +152,14 @@ func (r *masterCountEndpointReconciler) StopReconciling(serviceName string, ip n } // Remove our IP from the list of addresses - new := []api.EndpointAddress{} + new := []corev1.EndpointAddress{} for _, addr := range e.Subsets[0].Addresses { if addr.IP != ip.String() { new = append(new, addr) } } e.Subsets[0].Addresses = new - e.Subsets = endpoints.RepackSubsets(e.Subsets) + e.Subsets = endpointsv1.RepackSubsets(e.Subsets) err = retry.RetryOnConflict(retry.DefaultBackoff, func() error { _, err := r.endpointClient.Endpoints(metav1.NamespaceDefault).Update(e) return err @@ -175,7 +175,7 @@ func (r *masterCountEndpointReconciler) StopReconciling(serviceName string, ip n // of addresses is less than or equal to the master count. // * portsCorrect is true when endpoint ports exactly match provided ports. // portsCorrect is only evaluated when reconcilePorts is set to true. -func checkEndpointSubsetFormat(e *api.Endpoints, ip string, ports []api.EndpointPort, count int, reconcilePorts bool) (formatCorrect bool, ipCorrect bool, portsCorrect bool) { +func checkEndpointSubsetFormat(e *corev1.Endpoints, ip string, ports []corev1.EndpointPort, count int, reconcilePorts bool) (formatCorrect bool, ipCorrect bool, portsCorrect bool) { if len(e.Subsets) != 1 { return false, false, false } @@ -214,7 +214,7 @@ func checkEndpointSubsetFormat(e *api.Endpoints, ip string, ports []api.Endpoint // * All apiservers MUST use GetMasterServiceUpdateIfNeeded and only // GetMasterServiceUpdateIfNeeded to manage service attributes // * updateMasterService is called periodically from all apiservers. -func GetMasterServiceUpdateIfNeeded(svc *api.Service, servicePorts []api.ServicePort, serviceType api.ServiceType) (s *api.Service, updated bool) { +func GetMasterServiceUpdateIfNeeded(svc *corev1.Service, servicePorts []corev1.ServicePort, serviceType corev1.ServiceType) (s *corev1.Service, updated bool) { // Determine if the service is in the format we expect // (servicePorts are present and service type matches) formatCorrect := checkServiceFormat(svc, servicePorts, serviceType) @@ -229,7 +229,7 @@ func GetMasterServiceUpdateIfNeeded(svc *api.Service, servicePorts []api.Service // Determine if the service is in the correct format // GetMasterServiceUpdateIfNeeded expects (servicePorts are correct // and service type matches). -func checkServiceFormat(s *api.Service, ports []api.ServicePort, serviceType api.ServiceType) (formatCorrect bool) { +func checkServiceFormat(s *corev1.Service, ports []corev1.ServicePort, serviceType corev1.ServiceType) (formatCorrect bool) { if s.Spec.Type != serviceType { return false } diff --git a/pkg/master/reconcilers/none.go b/pkg/master/reconcilers/none.go index dce38c2a66aa3..9bd4ee5ad7fe5 100644 --- a/pkg/master/reconcilers/none.go +++ b/pkg/master/reconcilers/none.go @@ -18,7 +18,7 @@ limitations under the License. package reconcilers import ( - api "k8s.io/kubernetes/pkg/apis/core" + corev1 "k8s.io/api/core/v1" "net" ) @@ -32,11 +32,11 @@ func NewNoneEndpointReconciler() EndpointReconciler { } // ReconcileEndpoints noop reconcile -func (r *noneEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error { +func (r *noneEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []corev1.EndpointPort, reconcilePorts bool) error { return nil } // StopReconciling noop reconcile -func (r *noneEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []api.EndpointPort) error { +func (r *noneEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []corev1.EndpointPort) error { return nil } diff --git a/pkg/master/reconcilers/reconcilers.go b/pkg/master/reconcilers/reconcilers.go index 8bbabc659019f..0cfb9a0aaf85f 100644 --- a/pkg/master/reconcilers/reconcilers.go +++ b/pkg/master/reconcilers/reconcilers.go @@ -18,7 +18,7 @@ limitations under the License. package reconcilers import ( - api "k8s.io/kubernetes/pkg/apis/core" + corev1 "k8s.io/api/core/v1" "net" ) @@ -34,8 +34,8 @@ type EndpointReconciler interface { // * All apiservers MUST use ReconcileEndpoints and only ReconcileEndpoints to manage the // endpoints for their {rw, ro} services. // * ReconcileEndpoints is called periodically from all apiservers. - ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error - StopReconciling(serviceName string, ip net.IP, endpointPorts []api.EndpointPort) error + ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []corev1.EndpointPort, reconcilePorts bool) error + StopReconciling(serviceName string, ip net.IP, endpointPorts []corev1.EndpointPort) error } // Type the reconciler type diff --git a/pkg/printers/internalversion/BUILD b/pkg/printers/internalversion/BUILD index de8753275619f..8f04a12db04ff 100644 --- a/pkg/printers/internalversion/BUILD +++ b/pkg/printers/internalversion/BUILD @@ -96,6 +96,7 @@ go_library( "//staging/src/k8s.io/api/coordination/v1beta1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1: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/api/rbac/v1beta1:go_default_library", "//staging/src/k8s.io/api/scheduling/v1beta1:go_default_library", diff --git a/pkg/printers/internalversion/describe.go b/pkg/printers/internalversion/describe.go index f4f848931a507..ef79f5e05cbc6 100644 --- a/pkg/printers/internalversion/describe.go +++ b/pkg/printers/internalversion/describe.go @@ -774,6 +774,8 @@ func describeVolumes(volumes []api.Volume, w PrefixWriter, space string) { printFlexVolumeSource(volume.VolumeSource.FlexVolume, w) case volume.VolumeSource.Flocker != nil: printFlockerVolumeSource(volume.VolumeSource.Flocker, w) + case volume.VolumeSource.Projected != nil: + printProjectedVolumeSource(volume.VolumeSource.Projected, w) default: w.Write(LEVEL_1, "\n") } @@ -837,6 +839,26 @@ func printConfigMapVolumeSource(configMap *api.ConfigMapVolumeSource, w PrefixWr configMap.Name, optional) } +func printProjectedVolumeSource(projected *api.ProjectedVolumeSource, w PrefixWriter) { + w.Write(LEVEL_2, "Type:\tProjected (a volume that contains injected data from multiple sources)\n") + for _, source := range projected.Sources { + if source.Secret != nil { + w.Write(LEVEL_2, "SecretName:\t%v\n"+ + " SecretOptionalName:\t%v\n", + source.Secret.Name, source.Secret.Optional) + } else if source.DownwardAPI != nil { + w.Write(LEVEL_2, "DownwardAPI:\ttrue\n") + } else if source.ConfigMap != nil { + w.Write(LEVEL_2, "ConfigMapName:\t%v\n"+ + " ConfigMapOptional:\t%v\n", + source.ConfigMap.Name, source.ConfigMap.Optional) + } else if source.ServiceAccountToken != nil { + w.Write(LEVEL_2, "TokenExpirationSeconds:\t%v\n", + source.ServiceAccountToken.ExpirationSeconds) + } + } +} + func printNFSVolumeSource(nfs *api.NFSVolumeSource, w PrefixWriter) { w.Write(LEVEL_2, "Type:\tNFS (an NFS mount that lasts the lifetime of a pod)\n"+ " Server:\t%v\n"+ @@ -1872,7 +1894,7 @@ type ReplicaSetDescriber struct { } func (d *ReplicaSetDescriber) Describe(namespace, name string, describerSettings printers.DescriberSettings) (string, error) { - rsc := d.Extensions().ReplicaSets(namespace) + rsc := d.Apps().ReplicaSets(namespace) pc := d.Core().Pods(namespace) rs, err := rsc.Get(name, metav1.GetOptions{}) @@ -1895,7 +1917,7 @@ func (d *ReplicaSetDescriber) Describe(namespace, name string, describerSettings return describeReplicaSet(rs, events, running, waiting, succeeded, failed, getPodErr) } -func describeReplicaSet(rs *extensions.ReplicaSet, events *api.EventList, running, waiting, succeeded, failed int, getPodErr error) (string, error) { +func describeReplicaSet(rs *apps.ReplicaSet, events *api.EventList, running, waiting, succeeded, failed int, getPodErr error) (string, error) { return tabbedString(func(out io.Writer) error { w := NewPrefixWriter(out) w.Write(LEVEL_0, "Name:\t%s\n", rs.Name) @@ -2085,7 +2107,7 @@ type DaemonSetDescriber struct { } func (d *DaemonSetDescriber) Describe(namespace, name string, describerSettings printers.DescriberSettings) (string, error) { - dc := d.Extensions().DaemonSets(namespace) + dc := d.Apps().DaemonSets(namespace) pc := d.Core().Pods(namespace) daemon, err := dc.Get(name, metav1.GetOptions{}) @@ -2110,7 +2132,7 @@ func (d *DaemonSetDescriber) Describe(namespace, name string, describerSettings return describeDaemonSet(daemon, events, running, waiting, succeeded, failed) } -func describeDaemonSet(daemon *extensions.DaemonSet, events *api.EventList, running, waiting, succeeded, failed int) (string, error) { +func describeDaemonSet(daemon *apps.DaemonSet, events *api.EventList, running, waiting, succeeded, failed int) (string, error) { return tabbedString(func(out io.Writer) error { w := NewPrefixWriter(out) w.Write(LEVEL_0, "Name:\t%s\n", daemon.Name) @@ -3129,7 +3151,8 @@ func describeNodeResource(nodeNonTerminatedPodsList *api.PodList, node *api.Node w.Write(LEVEL_1, "Resource\tRequests\tLimits\n") w.Write(LEVEL_1, "--------\t--------\t------\n") reqs, limits := getPodsTotalRequestsAndLimits(nodeNonTerminatedPodsList) - cpuReqs, cpuLimits, memoryReqs, memoryLimits := reqs[api.ResourceCPU], limits[api.ResourceCPU], reqs[api.ResourceMemory], limits[api.ResourceMemory] + cpuReqs, cpuLimits, memoryReqs, memoryLimits, ephemeralstorageReqs, ephemeralstorageLimits := + reqs[api.ResourceCPU], limits[api.ResourceCPU], reqs[api.ResourceMemory], limits[api.ResourceMemory], reqs[api.ResourceEphemeralStorage], limits[api.ResourceEphemeralStorage] fractionCpuReqs := float64(0) fractionCpuLimits := float64(0) if allocatable.Cpu().MilliValue() != 0 { @@ -3142,10 +3165,18 @@ func describeNodeResource(nodeNonTerminatedPodsList *api.PodList, node *api.Node fractionMemoryReqs = float64(memoryReqs.Value()) / float64(allocatable.Memory().Value()) * 100 fractionMemoryLimits = float64(memoryLimits.Value()) / float64(allocatable.Memory().Value()) * 100 } + fractionEphemeralStorageReqs := float64(0) + fractionEphemeralStorageLimits := float64(0) + if allocatable.StorageEphemeral().Value() != 0 { + fractionEphemeralStorageReqs = float64(ephemeralstorageReqs.Value()) / float64(allocatable.StorageEphemeral().Value()) * 100 + fractionEphemeralStorageLimits = float64(ephemeralstorageLimits.Value()) / float64(allocatable.StorageEphemeral().Value()) * 100 + } w.Write(LEVEL_1, "%s\t%s (%d%%)\t%s (%d%%)\n", api.ResourceCPU, cpuReqs.String(), int64(fractionCpuReqs), cpuLimits.String(), int64(fractionCpuLimits)) w.Write(LEVEL_1, "%s\t%s (%d%%)\t%s (%d%%)\n", api.ResourceMemory, memoryReqs.String(), int64(fractionMemoryReqs), memoryLimits.String(), int64(fractionMemoryLimits)) + w.Write(LEVEL_1, "%s\t%s (%d%%)\t%s (%d%%)\n", + api.ResourceEphemeralStorage, ephemeralstorageReqs.String(), int64(fractionEphemeralStorageReqs), ephemeralstorageLimits.String(), int64(fractionEphemeralStorageLimits)) extResources := make([]string, 0, len(allocatable)) for resource := range allocatable { if !helper.IsStandardContainerResourceName(string(resource)) && resource != api.ResourcePods { @@ -3224,8 +3255,8 @@ func (dd *DeploymentDescriber) Describe(namespace, name string, describerSetting if err != nil { return "", err } - internalDeployment := &extensions.Deployment{} - if err := legacyscheme.Scheme.Convert(d, internalDeployment, extensions.SchemeGroupVersion); err != nil { + internalDeployment := &apps.Deployment{} + if err := legacyscheme.Scheme.Convert(d, internalDeployment, apps.SchemeGroupVersion); err != nil { return "", err } @@ -3237,7 +3268,7 @@ func (dd *DeploymentDescriber) Describe(namespace, name string, describerSetting return describeDeployment(d, selector, internalDeployment, events, dd) } -func describeDeployment(d *appsv1.Deployment, selector labels.Selector, internalDeployment *extensions.Deployment, events *api.EventList, dd *DeploymentDescriber) (string, error) { +func describeDeployment(d *appsv1.Deployment, selector labels.Selector, internalDeployment *apps.Deployment, events *api.EventList, dd *DeploymentDescriber) (string, error) { return tabbedString(func(out io.Writer) error { w := NewPrefixWriter(out) w.Write(LEVEL_0, "Name:\t%s\n", d.ObjectMeta.Name) diff --git a/pkg/printers/internalversion/describe_test.go b/pkg/printers/internalversion/describe_test.go index 381bb7f527c41..ceded030e41cb 100644 --- a/pkg/printers/internalversion/describe_test.go +++ b/pkg/printers/internalversion/describe_test.go @@ -36,7 +36,6 @@ import ( "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/networking" "k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/storage" @@ -2188,7 +2187,7 @@ func TestDescribeEvents(t *testing.T) { m := map[string]printers.Describer{ "DaemonSetDescriber": &DaemonSetDescriber{ - fake.NewSimpleClientset(&extensions.DaemonSet{ + fake.NewSimpleClientset(&apps.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ Name: "bar", Namespace: "foo", @@ -2245,7 +2244,7 @@ func TestDescribeEvents(t *testing.T) { }, events), }, "ReplicaSetDescriber": &ReplicaSetDescriber{ - fake.NewSimpleClientset(&extensions.ReplicaSet{ + fake.NewSimpleClientset(&apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Name: "bar", Namespace: "foo", diff --git a/pkg/printers/internalversion/printers.go b/pkg/printers/internalversion/printers.go index 57c156a056f83..749d4a2da06a5 100644 --- a/pkg/printers/internalversion/printers.go +++ b/pkg/printers/internalversion/printers.go @@ -19,7 +19,6 @@ package internalversion import ( "bytes" "fmt" - "io" "net" "sort" "strconv" @@ -34,6 +33,7 @@ import ( coordinationv1beta1 "k8s.io/api/coordination/v1beta1" apiv1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + policyv1beta1 "k8s.io/api/policy/v1beta1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" storagev1 "k8s.io/api/storage/v1" @@ -346,14 +346,14 @@ func AddHandlers(h printers.PrintHandler) { podSecurityPolicyColumnDefinitions := []metav1beta1.TableColumnDefinition{ {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, - {Name: "Priv", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["privileged"]}, - {Name: "Caps", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["allowedCapabilities"]}, - {Name: "SELinux", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["seLinux"]}, - {Name: "RunAsUser", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["runAsUser"]}, - {Name: "FsGroup", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["fsGroup"]}, - {Name: "SupGroup", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["supplementalGroups"]}, - {Name: "ReadOnlyRootFs", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["readOnlyRootFilesystem"]}, - {Name: "Volumes", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["volumes"]}, + {Name: "Priv", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["privileged"]}, + {Name: "Caps", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["allowedCapabilities"]}, + {Name: "SELinux", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["seLinux"]}, + {Name: "RunAsUser", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["runAsUser"]}, + {Name: "FsGroup", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["fsGroup"]}, + {Name: "SupGroup", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["supplementalGroups"]}, + {Name: "ReadOnlyRootFs", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["readOnlyRootFilesystem"]}, + {Name: "Volumes", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["volumes"]}, } h.TableHandler(podSecurityPolicyColumnDefinitions, printPodSecurityPolicy) h.TableHandler(podSecurityPolicyColumnDefinitions, printPodSecurityPolicyList) @@ -769,7 +769,7 @@ func printReplicationControllerList(list *api.ReplicationControllerList, options return rows, nil } -func printReplicaSet(obj *extensions.ReplicaSet, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { +func printReplicaSet(obj *apps.ReplicaSet, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { row := metav1beta1.TableRow{ Object: runtime.RawExtension{Object: obj}, } @@ -786,7 +786,7 @@ func printReplicaSet(obj *extensions.ReplicaSet, options printers.PrintOptions) return []metav1beta1.TableRow{row}, nil } -func printReplicaSetList(list *extensions.ReplicaSetList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { +func printReplicaSetList(list *apps.ReplicaSetList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { rows := make([]metav1beta1.TableRow, 0, len(list.Items)) for i := range list.Items { r, err := printReplicaSet(&list.Items[i], options) @@ -1063,7 +1063,7 @@ func printStatefulSetList(list *apps.StatefulSetList, options printers.PrintOpti return rows, nil } -func printDaemonSet(obj *extensions.DaemonSet, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { +func printDaemonSet(obj *apps.DaemonSet, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { row := metav1beta1.TableRow{ Object: runtime.RawExtension{Object: obj}, } @@ -1082,7 +1082,7 @@ func printDaemonSet(obj *extensions.DaemonSet, options printers.PrintOptions) ([ return []metav1beta1.TableRow{row}, nil } -func printDaemonSetList(list *extensions.DaemonSetList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { +func printDaemonSetList(list *apps.DaemonSetList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { rows := make([]metav1beta1.TableRow, 0, len(list.Items)) for i := range list.Items { r, err := printDaemonSet(&list.Items[i], options) @@ -1548,14 +1548,7 @@ func printComponentStatusList(list *api.ComponentStatusList, options printers.Pr return rows, nil } -func truncate(str string, maxLen int) string { - if len(str) > maxLen { - return str[0:maxLen] + "..." - } - return str -} - -func printDeployment(obj *extensions.Deployment, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { +func printDeployment(obj *apps.Deployment, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { row := metav1beta1.TableRow{ Object: runtime.RawExtension{Object: obj}, } @@ -1578,7 +1571,7 @@ func printDeployment(obj *extensions.Deployment, options printers.PrintOptions) return []metav1beta1.TableRow{row}, nil } -func printDeploymentList(list *extensions.DeploymentList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { +func printDeploymentList(list *apps.DeploymentList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) { rows := make([]metav1beta1.TableRow, 0, len(list.Items)) for i := range list.Items { r, err := printDeployment(&list.Items[i], options) @@ -1829,24 +1822,6 @@ func printStatus(obj *metav1.Status, options printers.PrintOptions) ([]metav1bet return []metav1beta1.TableRow{row}, nil } -// Lay out all the containers on one line if use wide output. -// DEPRECATED: convert to TableHandler and use layoutContainerCells -func layoutContainers(containers []api.Container, w io.Writer) error { - var namesBuffer bytes.Buffer - var imagesBuffer bytes.Buffer - - for i, container := range containers { - namesBuffer.WriteString(container.Name) - imagesBuffer.WriteString(container.Image) - if i != len(containers)-1 { - namesBuffer.WriteString(",") - imagesBuffer.WriteString(",") - } - } - _, err := fmt.Fprintf(w, "\t%s\t%s", namesBuffer.String(), imagesBuffer.String()) - return err -} - // Lay out all the containers on one line if use wide output. func layoutContainerCells(containers []api.Container) (names string, images string) { var namesBuffer bytes.Buffer diff --git a/pkg/printers/internalversion/printers_test.go b/pkg/printers/internalversion/printers_test.go index ef0641d4cf02f..01afac8198a26 100644 --- a/pkg/printers/internalversion/printers_test.go +++ b/pkg/printers/internalversion/printers_test.go @@ -1971,17 +1971,17 @@ func TestTranslateTimestampUntil(t *testing.T) { func TestPrintDeployment(t *testing.T) { tests := []struct { - deployment extensions.Deployment + deployment apps.Deployment expect string wideExpect string }{ { - extensions.Deployment{ + apps.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: "test1", CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)}, }, - Spec: extensions.DeploymentSpec{ + Spec: apps.DeploymentSpec{ Replicas: 5, Template: api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -1999,7 +1999,7 @@ func TestPrintDeployment(t *testing.T) { }, Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, - Status: extensions.DeploymentStatus{ + Status: apps.DeploymentStatus{ Replicas: 10, UpdatedReplicas: 2, AvailableReplicas: 1, @@ -2040,21 +2040,21 @@ func TestPrintDeployment(t *testing.T) { func TestPrintDaemonSet(t *testing.T) { tests := []struct { - ds extensions.DaemonSet + ds apps.DaemonSet startsWith string }{ { - extensions.DaemonSet{ + apps.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ Name: "test1", CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)}, }, - Spec: extensions.DaemonSetSpec{ + Spec: apps.DaemonSetSpec{ Template: api.PodTemplateSpec{ Spec: api.PodSpec{Containers: make([]api.Container, 2)}, }, }, - Status: extensions.DaemonSetStatus{ + Status: apps.DaemonSetStatus{ CurrentNumberScheduled: 2, DesiredNumberScheduled: 3, NumberReady: 1, @@ -3154,17 +3154,17 @@ func boolP(b bool) *bool { func TestPrintReplicaSet(t *testing.T) { tests := []struct { - replicaSet extensions.ReplicaSet + replicaSet apps.ReplicaSet expect string wideExpect string }{ { - extensions.ReplicaSet{ + apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Name: "test1", CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)}, }, - Spec: extensions.ReplicaSetSpec{ + Spec: apps.ReplicaSetSpec{ Replicas: 5, Template: api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -3182,7 +3182,7 @@ func TestPrintReplicaSet(t *testing.T) { }, Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, - Status: extensions.ReplicaSetStatus{ + Status: apps.ReplicaSetStatus{ Replicas: 5, ReadyReplicas: 2, }, diff --git a/pkg/proxy/apis/config/types.go b/pkg/proxy/apis/config/types.go index e309317b0a290..dacee32bb3a6b 100644 --- a/pkg/proxy/apis/config/types.go +++ b/pkg/proxy/apis/config/types.go @@ -172,7 +172,7 @@ type IPVSSchedulerMethod string const ( // RoundRobin distributes jobs equally amongst the available real servers. RoundRobin IPVSSchedulerMethod = "rr" - // WeightedRoundRobin assigns jobs to real servers proportionally to there real servers' weight. + // WeightedRoundRobin assigns jobs to real servers proportionally to their real servers' weight. // Servers with higher weights receive new jobs first and get more jobs than servers with lower weights. // Servers with equal weights get an equal distribution of new jobs. WeightedRoundRobin IPVSSchedulerMethod = "wrr" diff --git a/pkg/proxy/ipvs/README.md b/pkg/proxy/ipvs/README.md index fcdca80744928..eb0f456f690a2 100644 --- a/pkg/proxy/ipvs/README.md +++ b/pkg/proxy/ipvs/README.md @@ -38,7 +38,7 @@ Differences between IPVS mode and IPTABLES mode are as follows: ### When ipvs falls back to iptables IPVS proxier will employ iptables in doing packet filtering, SNAT or masquerade. -Specifically, ipvs proxier will use ipset to store source or destination address of traffics that need DROP or do masquared, to make sure the number of iptables rules be constant, no metter how many services we have. +Specifically, ipvs proxier will use ipset to store source or destination address of traffics that need DROP or do masquerade, to make sure the number of iptables rules be constant, no metter how many services we have. Here is the table of ipset sets that ipvs proxier used. @@ -259,7 +259,7 @@ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 match-set KUBE-EXT Currently, local-up scripts, GCE scripts and kubeadm support switching IPVS proxy mode via exporting environment variables or specifying flags. ### Prerequisite -Ensure IPVS required kernel modules +Ensure IPVS required kernel modules (**Notes**: use `nf_conntrack` instead of `nf_conntrack_ipv4` for Linux kernel 4.19 and later) ```shell ip_vs ip_vs_rr diff --git a/pkg/proxy/ipvs/proxier.go b/pkg/proxy/ipvs/proxier.go index 2c0f15e797d0e..d9233a0801af1 100644 --- a/pkg/proxy/ipvs/proxier.go +++ b/pkg/proxy/ipvs/proxier.go @@ -113,23 +113,22 @@ var iptablesChains = []struct { var ipsetInfo = []struct { name string setType utilipset.Type - isIPv6 bool comment string }{ - {kubeLoopBackIPSet, utilipset.HashIPPortIP, true, kubeLoopBackIPSetComment}, - {kubeClusterIPSet, utilipset.HashIPPort, true, kubeClusterIPSetComment}, - {kubeExternalIPSet, utilipset.HashIPPort, true, kubeExternalIPSetComment}, - {kubeLoadBalancerSet, utilipset.HashIPPort, true, kubeLoadBalancerSetComment}, - {kubeLoadbalancerFWSet, utilipset.HashIPPort, true, kubeLoadbalancerFWSetComment}, - {kubeLoadBalancerLocalSet, utilipset.HashIPPort, true, kubeLoadBalancerLocalSetComment}, - {kubeLoadBalancerSourceIPSet, utilipset.HashIPPortIP, true, kubeLoadBalancerSourceIPSetComment}, - {kubeLoadBalancerSourceCIDRSet, utilipset.HashIPPortNet, true, kubeLoadBalancerSourceCIDRSetComment}, - {kubeNodePortSetTCP, utilipset.BitmapPort, false, kubeNodePortSetTCPComment}, - {kubeNodePortLocalSetTCP, utilipset.BitmapPort, false, kubeNodePortLocalSetTCPComment}, - {kubeNodePortSetUDP, utilipset.BitmapPort, false, kubeNodePortSetUDPComment}, - {kubeNodePortLocalSetUDP, utilipset.BitmapPort, false, kubeNodePortLocalSetUDPComment}, - {kubeNodePortSetSCTP, utilipset.BitmapPort, false, kubeNodePortSetSCTPComment}, - {kubeNodePortLocalSetSCTP, utilipset.BitmapPort, false, kubeNodePortLocalSetSCTPComment}, + {kubeLoopBackIPSet, utilipset.HashIPPortIP, kubeLoopBackIPSetComment}, + {kubeClusterIPSet, utilipset.HashIPPort, kubeClusterIPSetComment}, + {kubeExternalIPSet, utilipset.HashIPPort, kubeExternalIPSetComment}, + {kubeLoadBalancerSet, utilipset.HashIPPort, kubeLoadBalancerSetComment}, + {kubeLoadbalancerFWSet, utilipset.HashIPPort, kubeLoadbalancerFWSetComment}, + {kubeLoadBalancerLocalSet, utilipset.HashIPPort, kubeLoadBalancerLocalSetComment}, + {kubeLoadBalancerSourceIPSet, utilipset.HashIPPortIP, kubeLoadBalancerSourceIPSetComment}, + {kubeLoadBalancerSourceCIDRSet, utilipset.HashIPPortNet, kubeLoadBalancerSourceCIDRSetComment}, + {kubeNodePortSetTCP, utilipset.BitmapPort, kubeNodePortSetTCPComment}, + {kubeNodePortLocalSetTCP, utilipset.BitmapPort, kubeNodePortLocalSetTCPComment}, + {kubeNodePortSetUDP, utilipset.BitmapPort, kubeNodePortSetUDPComment}, + {kubeNodePortLocalSetUDP, utilipset.BitmapPort, kubeNodePortLocalSetUDPComment}, + {kubeNodePortSetSCTP, utilipset.BitmapPort, kubeNodePortSetSCTPComment}, + {kubeNodePortLocalSetSCTP, utilipset.BitmapPort, kubeNodePortLocalSetSCTPComment}, } // ipsetWithIptablesChain is the ipsets list with iptables source chain and the chain jump to @@ -158,19 +157,13 @@ var ipsetWithIptablesChain = []struct { {kubeNodePortLocalSetSCTP, string(KubeNodePortChain), "RETURN", "dst", "sctp"}, } -var ipvsModules = []string{ - "ip_vs", - "ip_vs_rr", - "ip_vs_wrr", - "ip_vs_sh", - "nf_conntrack_ipv4", -} - // In IPVS proxy mode, the following flags need to be set const sysctlRouteLocalnet = "net/ipv4/conf/all/route_localnet" const sysctlBridgeCallIPTables = "net/bridge/bridge-nf-call-iptables" const sysctlVSConnTrack = "net/ipv4/vs/conntrack" const sysctlForward = "net/ipv4/ip_forward" +const sysctlArpIgnore = "net/ipv4/conf/all/arp_ignore" +const sysctlArpAnnounce = "net/ipv4/conf/all/arp_announce" // Proxier is an ipvs based proxy for connections between a localhost:lport // and services that provide the actual backends. @@ -327,6 +320,20 @@ func NewProxier(ipt utiliptables.Interface, } } + // Set the arp_ignore sysctl we need for + if val, _ := sysctl.GetSysctl(sysctlArpIgnore); val != 1 { + if err := sysctl.SetSysctl(sysctlArpIgnore, 1); err != nil { + return nil, fmt.Errorf("can't set sysctl %s: %v", sysctlArpIgnore, err) + } + } + + // Set the arp_announce sysctl we need for + if val, _ := sysctl.GetSysctl(sysctlArpAnnounce); val != 2 { + if err := sysctl.SetSysctl(sysctlArpAnnounce, 2); err != nil { + return nil, fmt.Errorf("can't set sysctl %s: %v", sysctlArpAnnounce, err) + } + } + // Generate the masquerade mark to use for SNAT rules. masqueradeValue := 1 << uint(masqueradeBit) masqueradeMark := fmt.Sprintf("%#08x/%#08x", masqueradeValue, masqueradeValue) @@ -391,10 +398,7 @@ func NewProxier(ipt utiliptables.Interface, // initialize ipsetList with all sets we needed proxier.ipsetList = make(map[string]*IPSet) for _, is := range ipsetInfo { - if is.isIPv6 { - proxier.ipsetList[is.name] = NewIPSet(ipset, is.name, is.setType, isIPv6, is.comment) - } - proxier.ipsetList[is.name] = NewIPSet(ipset, is.name, is.setType, false, is.comment) + proxier.ipsetList[is.name] = NewIPSet(ipset, is.name, is.setType, isIPv6, is.comment) } burstSyncs := 2 glog.V(3).Infof("minSyncPeriod: %v, syncPeriod: %v, burstSyncs: %d", minSyncPeriod, syncPeriod, burstSyncs) @@ -442,14 +446,12 @@ func NewLinuxKernelHandler() *LinuxKernelHandler { // GetModules returns all installed kernel modules. func (handle *LinuxKernelHandler) GetModules() ([]string, error) { // Check whether IPVS required kernel modules are built-in - kernelVersionFile := "/proc/sys/kernel/osrelease" - b, err := ioutil.ReadFile(kernelVersionFile) + kernelVersion, ipvsModules, err := utilipvs.GetKernelVersionAndIPVSMods(handle.executor) if err != nil { - glog.Errorf("Failed to read file %s with error %v", kernelVersionFile, err) + return nil, err } - kernelVersion := strings.TrimSpace(string(b)) builtinModsFilePath := fmt.Sprintf("/lib/modules/%s/modules.builtin", kernelVersion) - b, err = ioutil.ReadFile(builtinModsFilePath) + b, err := ioutil.ReadFile(builtinModsFilePath) if err != nil { glog.Warningf("Failed to read file %s with error %v. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules", builtinModsFilePath, err) } @@ -490,11 +492,26 @@ func CanUseIPVSProxier(handle KernelHandler, ipsetver IPSetVersioner) (bool, err } wantModules := sets.NewString() loadModules := sets.NewString() + linuxKernelHandler := NewLinuxKernelHandler() + _, ipvsModules, _ := utilipvs.GetKernelVersionAndIPVSMods(linuxKernelHandler.executor) wantModules.Insert(ipvsModules...) loadModules.Insert(mods...) modules := wantModules.Difference(loadModules).UnsortedList() - if len(modules) != 0 { - return false, fmt.Errorf("IPVS proxier will not be used because the following required kernel modules are not loaded: %v", modules) + var missingMods []string + ConntrackiMissingCounter := 0 + for _, mod := range modules { + if strings.Contains(mod, "nf_conntrack") { + ConntrackiMissingCounter++ + } else { + missingMods = append(missingMods, mod) + } + } + if ConntrackiMissingCounter == 2 { + missingMods = append(missingMods, "nf_conntrack_ipv4(or nf_conntrack for Linux kernel 4.19 and later)") + } + + if len(missingMods) != 0 { + return false, fmt.Errorf("IPVS proxier will not be used because the following required kernel modules are not loaded: %v", missingMods) } // Check ipset version diff --git a/pkg/proxy/winkernel/proxier.go b/pkg/proxy/winkernel/proxier.go index 70148a03284f5..a1343d24b306f 100644 --- a/pkg/proxy/winkernel/proxier.go +++ b/pkg/proxy/winkernel/proxier.go @@ -180,10 +180,12 @@ func newServiceInfo(svcPortName proxy.ServicePortName, port *v1.ServicePort, ser stickyMaxAgeSeconds = int(*service.Spec.SessionAffinityConfig.ClientIP.TimeoutSeconds) } info := &serviceInfo{ - clusterIP: net.ParseIP(service.Spec.ClusterIP), - port: int(port.Port), - protocol: port.Protocol, - nodePort: int(port.NodePort), + clusterIP: net.ParseIP(service.Spec.ClusterIP), + port: int(port.Port), + protocol: port.Protocol, + nodePort: int(port.NodePort), + // targetPort is zero if it is specified as a name in port.TargetPort. + // Its real value would be got later from endpoints. targetPort: port.TargetPort.IntValue(), // Deep-copy in case the service instance changes loadBalancerStatus: *service.Status.LoadBalancer.DeepCopy(), @@ -977,6 +979,14 @@ func (proxier *Proxier) syncProxyRules() { var newHnsEndpoint *hcsshim.HNSEndpoint hnsNetworkName := proxier.network.name var err error + + // targetPort is zero if it is specified as a name in port.TargetPort, so the real port should be got from endpoints. + // Note that hcsshim.AddLoadBalancer() doesn't support endpoints with different ports, so only port from first endpoint is used. + // TODO(feiskyer): add support of different endpoint ports after hcsshim.AddLoadBalancer() add that. + if svcInfo.targetPort == 0 { + svcInfo.targetPort = int(ep.port) + } + if len(ep.hnsID) > 0 { newHnsEndpoint, err = hcsshim.GetHNSEndpointByID(ep.hnsID) } diff --git a/pkg/proxy/winuserspace/proxysocket.go b/pkg/proxy/winuserspace/proxysocket.go index df7d334d948e3..23782d6209b9f 100644 --- a/pkg/proxy/winuserspace/proxysocket.go +++ b/pkg/proxy/winuserspace/proxysocket.go @@ -505,7 +505,7 @@ func (udp *udpProxySocket) ProxyLoop(service ServicePortPortalName, myInfo *serv dnsSearch = []string{"", namespaceServiceDomain, serviceDomain, clusterDomain} execer := exec.New() ipconfigInterface := ipconfig.New(execer) - suffixList, err := ipconfigInterface.GetDnsSuffixSearchList() + suffixList, err := ipconfigInterface.GetDNSSuffixSearchList() if err == nil { for _, suffix := range suffixList { dnsSearch = append(dnsSearch, suffix) diff --git a/pkg/registry/apps/daemonset/BUILD b/pkg/registry/apps/daemonset/BUILD index 6a47e9bc6515b..68ae8aefac1bc 100644 --- a/pkg/registry/apps/daemonset/BUILD +++ b/pkg/registry/apps/daemonset/BUILD @@ -16,8 +16,8 @@ go_library( deps = [ "//pkg/api/legacyscheme:go_default_library", "//pkg/api/pod:go_default_library", - "//pkg/apis/extensions:go_default_library", - "//pkg/apis/extensions/validation:go_default_library", + "//pkg/apis/apps:go_default_library", + "//pkg/apis/apps/validation:go_default_library", "//staging/src/k8s.io/api/apps/v1beta2:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", @@ -36,8 +36,8 @@ go_test( srcs = ["strategy_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/apps/daemonset/storage/BUILD b/pkg/registry/apps/daemonset/storage/BUILD index 34b996da257a0..db60b336a3c27 100644 --- a/pkg/registry/apps/daemonset/storage/BUILD +++ b/pkg/registry/apps/daemonset/storage/BUILD @@ -11,8 +11,8 @@ go_test( srcs = ["storage_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/registry/registrytest:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library", @@ -29,7 +29,7 @@ go_library( srcs = ["storage.go"], importpath = "k8s.io/kubernetes/pkg/registry/apps/daemonset/storage", deps = [ - "//pkg/apis/extensions:go_default_library", + "//pkg/apis/apps:go_default_library", "//pkg/printers:go_default_library", "//pkg/printers/internalversion:go_default_library", "//pkg/printers/storage:go_default_library", diff --git a/pkg/registry/apps/daemonset/storage/storage.go b/pkg/registry/apps/daemonset/storage/storage.go index a8966491471a2..00f771c812170 100644 --- a/pkg/registry/apps/daemonset/storage/storage.go +++ b/pkg/registry/apps/daemonset/storage/storage.go @@ -24,7 +24,7 @@ import ( "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" "k8s.io/apiserver/pkg/registry/rest" - "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" printerstorage "k8s.io/kubernetes/pkg/printers/storage" @@ -40,9 +40,9 @@ type REST struct { // NewREST returns a RESTStorage object that will work against DaemonSets. func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) { store := &genericregistry.Store{ - NewFunc: func() runtime.Object { return &extensions.DaemonSet{} }, - NewListFunc: func() runtime.Object { return &extensions.DaemonSetList{} }, - DefaultQualifiedResource: extensions.Resource("daemonsets"), + NewFunc: func() runtime.Object { return &apps.DaemonSet{} }, + NewListFunc: func() runtime.Object { return &apps.DaemonSetList{} }, + DefaultQualifiedResource: apps.Resource("daemonsets"), CreateStrategy: daemonset.Strategy, UpdateStrategy: daemonset.Strategy, @@ -87,7 +87,7 @@ type StatusREST struct { } func (r *StatusREST) New() runtime.Object { - return &extensions.DaemonSet{} + return &apps.DaemonSet{} } // Get retrieves the object from the storage. It is required to support Patch. diff --git a/pkg/registry/apps/daemonset/storage/storage_test.go b/pkg/registry/apps/daemonset/storage/storage_test.go index 50dd81ca5a1f6..845de8a0212f5 100644 --- a/pkg/registry/apps/daemonset/storage/storage_test.go +++ b/pkg/registry/apps/daemonset/storage/storage_test.go @@ -26,13 +26,13 @@ import ( "k8s.io/apiserver/pkg/registry/generic" genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" + "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/registry/registrytest" ) func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) { - etcdStorage, server := registrytest.NewEtcdStorage(t, extensions.GroupName) + etcdStorage, server := registrytest.NewEtcdStorage(t, apps.GroupName) restOptions := generic.RESTOptions{ StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, @@ -43,15 +43,16 @@ func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) return daemonSetStorage, statusStorage, server } -func newValidDaemonSet() *extensions.DaemonSet { - return &extensions.DaemonSet{ +func newValidDaemonSet() *apps.DaemonSet { + return &apps.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", Namespace: metav1.NamespaceDefault, + Labels: map[string]string{"a": "b"}, }, - Spec: extensions.DaemonSetSpec{ - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, + Spec: apps.DaemonSetSpec{ + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, }, Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}}, Template: api.PodTemplateSpec{ @@ -88,15 +89,15 @@ func TestCreate(t *testing.T) { // valid ds, // invalid (invalid selector) - &extensions.DaemonSet{ - Spec: extensions.DaemonSetSpec{ + &apps.DaemonSet{ + Spec: apps.DaemonSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{}}, Template: validDaemonSet.Spec.Template, }, }, // invalid update strategy - &extensions.DaemonSet{ - Spec: extensions.DaemonSetSpec{ + &apps.DaemonSet{ + Spec: apps.DaemonSetSpec{ Selector: validDaemonSet.Spec.Selector, Template: validDaemonSet.Spec.Template, }, @@ -114,19 +115,19 @@ func TestUpdate(t *testing.T) { newValidDaemonSet(), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.DaemonSet) + object := obj.(*apps.DaemonSet) object.Spec.Template.Spec.NodeSelector = map[string]string{"c": "d"} object.Spec.Template.Spec.DNSPolicy = api.DNSDefault return object }, // invalid updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.DaemonSet) + object := obj.(*apps.DaemonSet) object.Name = "" return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.DaemonSet) + object := obj.(*apps.DaemonSet) object.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure return object }, diff --git a/pkg/registry/apps/daemonset/strategy.go b/pkg/registry/apps/daemonset/strategy.go index cdc70a600fcf4..f9b89bb552e2f 100644 --- a/pkg/registry/apps/daemonset/strategy.go +++ b/pkg/registry/apps/daemonset/strategy.go @@ -31,8 +31,8 @@ import ( "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/pod" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/apis/extensions/validation" + "k8s.io/kubernetes/pkg/apis/apps" + "k8s.io/kubernetes/pkg/apis/apps/validation" ) // daemonSetStrategy implements verification logic for daemon sets. @@ -66,8 +66,8 @@ func (daemonSetStrategy) NamespaceScoped() bool { // PrepareForCreate clears the status of a daemon set before creation. func (daemonSetStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { - daemonSet := obj.(*extensions.DaemonSet) - daemonSet.Status = extensions.DaemonSetStatus{} + daemonSet := obj.(*apps.DaemonSet) + daemonSet.Status = apps.DaemonSetStatus{} daemonSet.Generation = 1 if daemonSet.Spec.TemplateGeneration < 1 { @@ -79,8 +79,8 @@ func (daemonSetStrategy) PrepareForCreate(ctx context.Context, obj runtime.Objec // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (daemonSetStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { - newDaemonSet := obj.(*extensions.DaemonSet) - oldDaemonSet := old.(*extensions.DaemonSet) + newDaemonSet := obj.(*apps.DaemonSet) + oldDaemonSet := old.(*apps.DaemonSet) pod.DropDisabledAlphaFields(&newDaemonSet.Spec.Template.Spec) pod.DropDisabledAlphaFields(&oldDaemonSet.Spec.Template.Spec) @@ -114,7 +114,7 @@ func (daemonSetStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime. // Validate validates a new daemon set. func (daemonSetStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { - daemonSet := obj.(*extensions.DaemonSet) + daemonSet := obj.(*apps.DaemonSet) return validation.ValidateDaemonSet(daemonSet) } @@ -130,9 +130,9 @@ func (daemonSetStrategy) AllowCreateOnUpdate() bool { // ValidateUpdate is the default update validation for an end user. func (daemonSetStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - newDaemonSet := obj.(*extensions.DaemonSet) - oldDaemonSet := old.(*extensions.DaemonSet) - allErrs := validation.ValidateDaemonSet(obj.(*extensions.DaemonSet)) + newDaemonSet := obj.(*apps.DaemonSet) + oldDaemonSet := old.(*apps.DaemonSet) + allErrs := validation.ValidateDaemonSet(obj.(*apps.DaemonSet)) allErrs = append(allErrs, validation.ValidateDaemonSetUpdate(newDaemonSet, oldDaemonSet)...) // Update is not allowed to set Spec.Selector for apps/v1 and apps/v1beta2 (allowed for extensions/v1beta1). @@ -165,11 +165,11 @@ type daemonSetStatusStrategy struct { var StatusStrategy = daemonSetStatusStrategy{Strategy} func (daemonSetStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { - newDaemonSet := obj.(*extensions.DaemonSet) - oldDaemonSet := old.(*extensions.DaemonSet) + newDaemonSet := obj.(*apps.DaemonSet) + oldDaemonSet := old.(*apps.DaemonSet) newDaemonSet.Spec = oldDaemonSet.Spec } func (daemonSetStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - return validation.ValidateDaemonSetStatusUpdate(obj.(*extensions.DaemonSet), old.(*extensions.DaemonSet)) + return validation.ValidateDaemonSetStatusUpdate(obj.(*apps.DaemonSet), old.(*apps.DaemonSet)) } diff --git a/pkg/registry/apps/daemonset/strategy_test.go b/pkg/registry/apps/daemonset/strategy_test.go index 539a560cb8638..eb932cbf6ffca 100644 --- a/pkg/registry/apps/daemonset/strategy_test.go +++ b/pkg/registry/apps/daemonset/strategy_test.go @@ -24,8 +24,8 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" ) const ( @@ -160,20 +160,20 @@ func TestSelectorImmutability(t *testing.T) { } } -func newDaemonSetWithSelectorLabels(selectorLabels map[string]string, templateGeneration int64) *extensions.DaemonSet { - return &extensions.DaemonSet{ +func newDaemonSetWithSelectorLabels(selectorLabels map[string]string, templateGeneration int64) *apps.DaemonSet { + return &apps.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ Name: daemonsetName, Namespace: namespace, ResourceVersion: "1", }, - Spec: extensions.DaemonSetSpec{ + Spec: apps.DaemonSetSpec{ Selector: &metav1.LabelSelector{ MatchLabels: selectorLabels, MatchExpressions: []metav1.LabelSelectorRequirement{}, }, - UpdateStrategy: extensions.DaemonSetUpdateStrategy{ - Type: extensions.OnDeleteDaemonSetStrategyType, + UpdateStrategy: apps.DaemonSetUpdateStrategy{ + Type: apps.OnDeleteDaemonSetStrategyType, }, TemplateGeneration: templateGeneration, Template: api.PodTemplateSpec{ diff --git a/pkg/registry/apps/deployment/BUILD b/pkg/registry/apps/deployment/BUILD index 2fcc999bf9462..1ba9a291035da 100644 --- a/pkg/registry/apps/deployment/BUILD +++ b/pkg/registry/apps/deployment/BUILD @@ -16,8 +16,8 @@ go_library( deps = [ "//pkg/api/legacyscheme:go_default_library", "//pkg/api/pod:go_default_library", - "//pkg/apis/extensions:go_default_library", - "//pkg/apis/extensions/validation:go_default_library", + "//pkg/apis/apps:go_default_library", + "//pkg/apis/apps/validation:go_default_library", "//staging/src/k8s.io/api/apps/v1beta1:go_default_library", "//staging/src/k8s.io/api/apps/v1beta2:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", @@ -37,8 +37,8 @@ go_test( srcs = ["strategy_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", diff --git a/pkg/registry/apps/deployment/storage/BUILD b/pkg/registry/apps/deployment/storage/BUILD index bc9b896959d20..d310867ea685e 100644 --- a/pkg/registry/apps/deployment/storage/BUILD +++ b/pkg/registry/apps/deployment/storage/BUILD @@ -11,9 +11,9 @@ go_test( srcs = ["storage_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/registry/registrytest:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", @@ -37,14 +37,14 @@ go_library( srcs = ["storage.go"], importpath = "k8s.io/kubernetes/pkg/registry/apps/deployment/storage", deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/apps/v1beta1:go_default_library", "//pkg/apis/apps/v1beta2:go_default_library", + "//pkg/apis/apps/validation:go_default_library", "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/autoscaling/v1:go_default_library", "//pkg/apis/autoscaling/validation:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", - "//pkg/apis/extensions/validation:go_default_library", "//pkg/printers:go_default_library", "//pkg/printers/internalversion:go_default_library", "//pkg/printers/storage:go_default_library", diff --git a/pkg/registry/apps/deployment/storage/storage.go b/pkg/registry/apps/deployment/storage/storage.go index a1ccfb5d78f5b..5ee1fa2690d30 100644 --- a/pkg/registry/apps/deployment/storage/storage.go +++ b/pkg/registry/apps/deployment/storage/storage.go @@ -31,14 +31,14 @@ import ( "k8s.io/apiserver/pkg/storage" storeerr "k8s.io/apiserver/pkg/storage/errors" "k8s.io/apiserver/pkg/util/dryrun" + "k8s.io/kubernetes/pkg/apis/apps" appsv1beta1 "k8s.io/kubernetes/pkg/apis/apps/v1beta1" appsv1beta2 "k8s.io/kubernetes/pkg/apis/apps/v1beta2" + appsvalidation "k8s.io/kubernetes/pkg/apis/apps/validation" "k8s.io/kubernetes/pkg/apis/autoscaling" autoscalingv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1" autoscalingvalidation "k8s.io/kubernetes/pkg/apis/autoscaling/validation" - "k8s.io/kubernetes/pkg/apis/extensions" extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" - extvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" printerstorage "k8s.io/kubernetes/pkg/printers/storage" @@ -72,9 +72,9 @@ type REST struct { // NewREST returns a RESTStorage object that will work against deployments. func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *RollbackREST) { store := &genericregistry.Store{ - NewFunc: func() runtime.Object { return &extensions.Deployment{} }, - NewListFunc: func() runtime.Object { return &extensions.DeploymentList{} }, - DefaultQualifiedResource: extensions.Resource("deployments"), + NewFunc: func() runtime.Object { return &apps.Deployment{} }, + NewListFunc: func() runtime.Object { return &apps.DeploymentList{} }, + DefaultQualifiedResource: apps.Resource("deployments"), CreateStrategy: deployment.Strategy, UpdateStrategy: deployment.Strategy, @@ -119,7 +119,7 @@ type StatusREST struct { } func (r *StatusREST) New() runtime.Object { - return &extensions.Deployment{} + return &apps.Deployment{} } // Get retrieves the object from the storage. It is required to support Patch. @@ -155,19 +155,19 @@ var _ = rest.StorageMetadata(&RollbackREST{}) // New creates a rollback func (r *RollbackREST) New() runtime.Object { - return &extensions.DeploymentRollback{} + return &apps.DeploymentRollback{} } var _ = rest.Creater(&RollbackREST{}) func (r *RollbackREST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { - rollback, ok := obj.(*extensions.DeploymentRollback) + rollback, ok := obj.(*apps.DeploymentRollback) if !ok { return nil, errors.NewBadRequest(fmt.Sprintf("not a DeploymentRollback: %#v", obj)) } - if errs := extvalidation.ValidateDeploymentRollback(rollback); len(errs) != 0 { - return nil, errors.NewInvalid(extensions.Kind("DeploymentRollback"), rollback.Name, errs) + if errs := appsvalidation.ValidateDeploymentRollback(rollback); len(errs) != 0 { + return nil, errors.NewInvalid(apps.Kind("DeploymentRollback"), rollback.Name, errs) } // Update the Deployment with information in DeploymentRollback to trigger rollback @@ -182,10 +182,10 @@ func (r *RollbackREST) Create(ctx context.Context, obj runtime.Object, createVal }, nil } -func (r *RollbackREST) rollbackDeployment(ctx context.Context, deploymentID string, config *extensions.RollbackConfig, annotations map[string]string, dryRun bool) error { +func (r *RollbackREST) rollbackDeployment(ctx context.Context, deploymentID string, config *apps.RollbackConfig, annotations map[string]string, dryRun bool) error { if _, err := r.setDeploymentRollback(ctx, deploymentID, config, annotations, dryRun); err != nil { - err = storeerr.InterpretGetError(err, extensions.Resource("deployments"), deploymentID) - err = storeerr.InterpretUpdateError(err, extensions.Resource("deployments"), deploymentID) + err = storeerr.InterpretGetError(err, apps.Resource("deployments"), deploymentID) + err = storeerr.InterpretUpdateError(err, apps.Resource("deployments"), deploymentID) if _, ok := err.(*errors.StatusError); !ok { err = errors.NewInternalError(err) } @@ -194,14 +194,14 @@ func (r *RollbackREST) rollbackDeployment(ctx context.Context, deploymentID stri return nil } -func (r *RollbackREST) setDeploymentRollback(ctx context.Context, deploymentID string, config *extensions.RollbackConfig, annotations map[string]string, dryRun bool) (*extensions.Deployment, error) { +func (r *RollbackREST) setDeploymentRollback(ctx context.Context, deploymentID string, config *apps.RollbackConfig, annotations map[string]string, dryRun bool) (*apps.Deployment, error) { dKey, err := r.store.KeyFunc(ctx, deploymentID) if err != nil { return nil, err } - var finalDeployment *extensions.Deployment - err = r.store.Storage.GuaranteedUpdate(ctx, dKey, &extensions.Deployment{}, false, nil, storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { - d, ok := obj.(*extensions.Deployment) + var finalDeployment *apps.Deployment + err = r.store.Storage.GuaranteedUpdate(ctx, dKey, &apps.Deployment{}, false, nil, storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { + d, ok := obj.(*apps.Deployment) if !ok { return nil, fmt.Errorf("unexpected object: %#v", obj) } @@ -247,9 +247,9 @@ func (r *ScaleREST) New() runtime.Object { func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { obj, err := r.store.Get(ctx, name, options) if err != nil { - return nil, errors.NewNotFound(extensions.Resource("deployments/scale"), name) + return nil, errors.NewNotFound(apps.Resource("deployments/scale"), name) } - deployment := obj.(*extensions.Deployment) + deployment := obj.(*apps.Deployment) scale, err := scaleFromDeployment(deployment) if err != nil { return nil, errors.NewBadRequest(fmt.Sprintf("%v", err)) @@ -260,9 +260,9 @@ func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOpt func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { obj, err := r.store.Get(ctx, name, &metav1.GetOptions{}) if err != nil { - return nil, false, errors.NewNotFound(extensions.Resource("deployments/scale"), name) + return nil, false, errors.NewNotFound(apps.Resource("deployments/scale"), name) } - deployment := obj.(*extensions.Deployment) + deployment := obj.(*apps.Deployment) oldScale, err := scaleFromDeployment(deployment) if err != nil { @@ -282,7 +282,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update } if errs := autoscalingvalidation.ValidateScale(scale); len(errs) > 0 { - return nil, false, errors.NewInvalid(extensions.Kind("Scale"), name, errs) + return nil, false, errors.NewInvalid(autoscaling.Kind("Scale"), name, errs) } deployment.Spec.Replicas = scale.Spec.Replicas @@ -291,7 +291,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update if err != nil { return nil, false, err } - deployment = obj.(*extensions.Deployment) + deployment = obj.(*apps.Deployment) newScale, err := scaleFromDeployment(deployment) if err != nil { return nil, false, errors.NewBadRequest(fmt.Sprintf("%v", err)) @@ -300,7 +300,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update } // scaleFromDeployment returns a scale subresource for a deployment. -func scaleFromDeployment(deployment *extensions.Deployment) (*autoscaling.Scale, error) { +func scaleFromDeployment(deployment *apps.Deployment) (*autoscaling.Scale, error) { selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector) if err != nil { return nil, err diff --git a/pkg/registry/apps/deployment/storage/storage_test.go b/pkg/registry/apps/deployment/storage/storage_test.go index b3efd531a20bc..26bcdc0acc633 100644 --- a/pkg/registry/apps/deployment/storage/storage_test.go +++ b/pkg/registry/apps/deployment/storage/storage_test.go @@ -35,16 +35,16 @@ import ( "k8s.io/apiserver/pkg/registry/rest" storeerr "k8s.io/apiserver/pkg/storage/errors" etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" + "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/registry/registrytest" ) const defaultReplicas = 100 func newStorage(t *testing.T) (*DeploymentStorage, *etcdtesting.EtcdTestServer) { - etcdStorage, server := registrytest.NewEtcdStorage(t, extensions.GroupName) + etcdStorage, server := registrytest.NewEtcdStorage(t, apps.GroupName) restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "deployments"} deploymentStorage := NewStorage(restOptions) return &deploymentStorage, server @@ -53,17 +53,17 @@ func newStorage(t *testing.T) (*DeploymentStorage, *etcdtesting.EtcdTestServer) var namespace = "foo-namespace" var name = "foo-deployment" -func validNewDeployment() *extensions.Deployment { - return &extensions.Deployment{ +func validNewDeployment() *apps.Deployment { + return &apps.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, }, - Spec: extensions.DeploymentSpec{ + Spec: apps.DeploymentSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}}, - Strategy: extensions.DeploymentStrategy{ - Type: extensions.RollingUpdateDeploymentStrategyType, - RollingUpdate: &extensions.RollingUpdateDeployment{ + Strategy: apps.DeploymentStrategy{ + Type: apps.RollingUpdateDeploymentStrategyType, + RollingUpdate: &apps.RollingUpdateDeployment{ MaxSurge: intstr.FromInt(1), MaxUnavailable: intstr.FromInt(1), }, @@ -87,7 +87,7 @@ func validNewDeployment() *extensions.Deployment { }, Replicas: 7, }, - Status: extensions.DeploymentStatus{ + Status: apps.DeploymentStatus{ Replicas: 5, }, } @@ -106,8 +106,8 @@ func TestCreate(t *testing.T) { // valid deployment, // invalid (invalid selector) - &extensions.Deployment{ - Spec: extensions.DeploymentSpec{ + &apps.Deployment{ + Spec: apps.DeploymentSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{}}, Template: validDeployment.Spec.Template, }, @@ -125,23 +125,23 @@ func TestUpdate(t *testing.T) { validNewDeployment(), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.Deployment) + object := obj.(*apps.Deployment) object.Spec.Template.Spec.NodeSelector = map[string]string{"c": "d"} return object }, // invalid updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.Deployment) + object := obj.(*apps.Deployment) object.Name = "" return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.Deployment) + object := obj.(*apps.Deployment) object.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.Deployment) + object := obj.(*apps.Deployment) object.Spec.Selector = &metav1.LabelSelector{MatchLabels: map[string]string{}} return object }, @@ -202,7 +202,7 @@ func TestScaleGet(t *testing.T) { storage, server := newStorage(t) defer server.Terminate(t) defer storage.Deployment.Store.DestroyFunc() - var deployment extensions.Deployment + var deployment apps.Deployment ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), namespace) key := "/deployments/" + namespace + "/" + name if err := storage.Deployment.Storage.Create(ctx, key, &validDeployment, &deployment, 0, false); err != nil { @@ -243,7 +243,7 @@ func TestScaleUpdate(t *testing.T) { storage, server := newStorage(t) defer server.Terminate(t) defer storage.Deployment.Store.DestroyFunc() - var deployment extensions.Deployment + var deployment apps.Deployment ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), namespace) key := "/deployments/" + namespace + "/" + name if err := storage.Deployment.Storage.Create(ctx, key, &validDeployment, &deployment, 0, false); err != nil { @@ -286,12 +286,12 @@ func TestStatusUpdate(t *testing.T) { if err := storage.Deployment.Storage.Create(ctx, key, &validDeployment, nil, 0, false); err != nil { t.Fatalf("unexpected error: %v", err) } - update := extensions.Deployment{ + update := apps.Deployment{ ObjectMeta: validDeployment.ObjectMeta, - Spec: extensions.DeploymentSpec{ + Spec: apps.DeploymentSpec{ Replicas: defaultReplicas, }, - Status: extensions.DeploymentStatus{ + Status: apps.DeploymentStatus{ Replicas: defaultReplicas, }, } @@ -304,7 +304,7 @@ func TestStatusUpdate(t *testing.T) { t.Fatalf("unexpected error: %v", err) } - deployment := obj.(*extensions.Deployment) + deployment := obj.(*apps.Deployment) if deployment.Spec.Replicas != 7 { t.Errorf("we expected .spec.replicas to not be updated but it was updated to %v", deployment.Spec.Replicas) } @@ -317,28 +317,28 @@ func TestEtcdCreateDeploymentRollback(t *testing.T) { ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), namespace) testCases := map[string]struct { - rollback extensions.DeploymentRollback + rollback apps.DeploymentRollback errOK func(error) bool }{ "normal": { - rollback: extensions.DeploymentRollback{ + rollback: apps.DeploymentRollback{ Name: name, UpdatedAnnotations: map[string]string{}, - RollbackTo: extensions.RollbackConfig{Revision: 1}, + RollbackTo: apps.RollbackConfig{Revision: 1}, }, errOK: func(err error) bool { return err == nil }, }, "noAnnotation": { - rollback: extensions.DeploymentRollback{ + rollback: apps.DeploymentRollback{ Name: name, - RollbackTo: extensions.RollbackConfig{Revision: 1}, + RollbackTo: apps.RollbackConfig{Revision: 1}, }, errOK: func(err error) bool { return err == nil }, }, "noName": { - rollback: extensions.DeploymentRollback{ + rollback: apps.DeploymentRollback{ UpdatedAnnotations: map[string]string{}, - RollbackTo: extensions.RollbackConfig{Revision: 1}, + RollbackTo: apps.RollbackConfig{Revision: 1}, }, errOK: func(err error) bool { return err != nil }, }, @@ -365,8 +365,8 @@ func TestEtcdCreateDeploymentRollback(t *testing.T) { d, err := storage.Deployment.Get(ctx, validNewDeployment().ObjectMeta.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("%s: unexpected error: %v", k, err) - } else if !reflect.DeepEqual(*d.(*extensions.Deployment).Spec.RollbackTo, test.rollback.RollbackTo) { - t.Errorf("%s: expected: %v, got: %v", k, *d.(*extensions.Deployment).Spec.RollbackTo, test.rollback.RollbackTo) + } else if !reflect.DeepEqual(*d.(*apps.Deployment).Spec.RollbackTo, test.rollback.RollbackTo) { + t.Errorf("%s: expected: %v, got: %v", k, *d.(*apps.Deployment).Spec.RollbackTo, test.rollback.RollbackTo) } } storage.Deployment.Store.DestroyFunc() @@ -383,15 +383,15 @@ func TestEtcdCreateDeploymentRollbackNoDeployment(t *testing.T) { rollbackStorage := storage.Rollback ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), namespace) - _, err := rollbackStorage.Create(ctx, &extensions.DeploymentRollback{ + _, err := rollbackStorage.Create(ctx, &apps.DeploymentRollback{ Name: name, UpdatedAnnotations: map[string]string{}, - RollbackTo: extensions.RollbackConfig{Revision: 1}, + RollbackTo: apps.RollbackConfig{Revision: 1}, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err == nil { t.Fatalf("Expected not-found-error but got nothing") } - if !errors.IsNotFound(storeerr.InterpretGetError(err, extensions.Resource("deployments"), name)) { + if !errors.IsNotFound(storeerr.InterpretGetError(err, apps.Resource("deployments"), name)) { t.Fatalf("Unexpected error returned: %#v", err) } @@ -399,7 +399,7 @@ func TestEtcdCreateDeploymentRollbackNoDeployment(t *testing.T) { if err == nil { t.Fatalf("Expected not-found-error but got nothing") } - if !errors.IsNotFound(storeerr.InterpretGetError(err, extensions.Resource("deployments"), name)) { + if !errors.IsNotFound(storeerr.InterpretGetError(err, apps.Resource("deployments"), name)) { t.Fatalf("Unexpected error: %v", err) } } diff --git a/pkg/registry/apps/deployment/strategy.go b/pkg/registry/apps/deployment/strategy.go index 139d6df6aff27..e9d593d838b1a 100644 --- a/pkg/registry/apps/deployment/strategy.go +++ b/pkg/registry/apps/deployment/strategy.go @@ -32,8 +32,8 @@ import ( "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/pod" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/apis/extensions/validation" + "k8s.io/kubernetes/pkg/apis/apps" + "k8s.io/kubernetes/pkg/apis/apps/validation" ) // deploymentStrategy implements behavior for Deployments. @@ -68,8 +68,8 @@ func (deploymentStrategy) NamespaceScoped() bool { // PrepareForCreate clears fields that are not allowed to be set by end users on creation. func (deploymentStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { - deployment := obj.(*extensions.Deployment) - deployment.Status = extensions.DeploymentStatus{} + deployment := obj.(*apps.Deployment) + deployment.Status = apps.DeploymentStatus{} deployment.Generation = 1 pod.DropDisabledAlphaFields(&deployment.Spec.Template.Spec) @@ -77,7 +77,7 @@ func (deploymentStrategy) PrepareForCreate(ctx context.Context, obj runtime.Obje // Validate validates a new deployment. func (deploymentStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { - deployment := obj.(*extensions.Deployment) + deployment := obj.(*apps.Deployment) return validation.ValidateDeployment(deployment) } @@ -92,8 +92,8 @@ func (deploymentStrategy) AllowCreateOnUpdate() bool { // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (deploymentStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { - newDeployment := obj.(*extensions.Deployment) - oldDeployment := old.(*extensions.Deployment) + newDeployment := obj.(*apps.Deployment) + oldDeployment := old.(*apps.Deployment) newDeployment.Status = oldDeployment.Status pod.DropDisabledAlphaFields(&newDeployment.Spec.Template.Spec) @@ -110,8 +110,8 @@ func (deploymentStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime // ValidateUpdate is the default update validation for an end user. func (deploymentStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - newDeployment := obj.(*extensions.Deployment) - oldDeployment := old.(*extensions.Deployment) + newDeployment := obj.(*apps.Deployment) + oldDeployment := old.(*apps.Deployment) allErrs := validation.ValidateDeploymentUpdate(newDeployment, oldDeployment) // Update is not allowed to set Spec.Selector for all groups/versions except extensions/v1beta1. @@ -145,13 +145,13 @@ var StatusStrategy = deploymentStatusStrategy{Strategy} // PrepareForUpdate clears fields that are not allowed to be set by end users on update of status func (deploymentStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { - newDeployment := obj.(*extensions.Deployment) - oldDeployment := old.(*extensions.Deployment) + newDeployment := obj.(*apps.Deployment) + oldDeployment := old.(*apps.Deployment) newDeployment.Spec = oldDeployment.Spec newDeployment.Labels = oldDeployment.Labels } // ValidateUpdate is the default update validation for an end user updating status func (deploymentStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - return validation.ValidateDeploymentStatusUpdate(obj.(*extensions.Deployment), old.(*extensions.Deployment)) + return validation.ValidateDeploymentStatusUpdate(obj.(*apps.Deployment), old.(*apps.Deployment)) } diff --git a/pkg/registry/apps/deployment/strategy_test.go b/pkg/registry/apps/deployment/strategy_test.go index 02a95479c568d..a7a68766b4166 100644 --- a/pkg/registry/apps/deployment/strategy_test.go +++ b/pkg/registry/apps/deployment/strategy_test.go @@ -26,8 +26,8 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" ) const ( @@ -63,17 +63,17 @@ func TestStatusUpdates(t *testing.T) { } } -func newDeployment(labels, annotations map[string]string) *extensions.Deployment { - return &extensions.Deployment{ +func newDeployment(labels, annotations map[string]string) *apps.Deployment { + return &apps.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Labels: labels, Annotations: annotations, }, - Spec: extensions.DeploymentSpec{ + Spec: apps.DeploymentSpec{ Replicas: 1, - Strategy: extensions.DeploymentStrategy{ - Type: extensions.RecreateDeploymentStrategyType, + Strategy: apps.DeploymentStrategy{ + Type: apps.RecreateDeploymentStrategyType, }, Template: api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -152,21 +152,21 @@ func TestSelectorImmutability(t *testing.T) { } } -func newDeploymentWithSelectorLabels(selectorLabels map[string]string) *extensions.Deployment { - return &extensions.Deployment{ +func newDeploymentWithSelectorLabels(selectorLabels map[string]string) *apps.Deployment { + return &apps.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: deploymentName, Namespace: namespace, ResourceVersion: "1", }, - Spec: extensions.DeploymentSpec{ + Spec: apps.DeploymentSpec{ Selector: &metav1.LabelSelector{ MatchLabels: selectorLabels, MatchExpressions: []metav1.LabelSelectorRequirement{}, }, - Strategy: extensions.DeploymentStrategy{ - Type: extensions.RollingUpdateDeploymentStrategyType, - RollingUpdate: &extensions.RollingUpdateDeployment{ + Strategy: apps.DeploymentStrategy{ + Type: apps.RollingUpdateDeploymentStrategyType, + RollingUpdate: &apps.RollingUpdateDeployment{ MaxSurge: intstr.FromInt(1), MaxUnavailable: intstr.FromInt(1), }, diff --git a/pkg/registry/apps/replicaset/BUILD b/pkg/registry/apps/replicaset/BUILD index 7485665176462..bce7b57ba8052 100644 --- a/pkg/registry/apps/replicaset/BUILD +++ b/pkg/registry/apps/replicaset/BUILD @@ -16,8 +16,8 @@ go_library( deps = [ "//pkg/api/legacyscheme:go_default_library", "//pkg/api/pod:go_default_library", - "//pkg/apis/extensions:go_default_library", - "//pkg/apis/extensions/validation:go_default_library", + "//pkg/apis/apps:go_default_library", + "//pkg/apis/apps/validation:go_default_library", "//staging/src/k8s.io/api/apps/v1beta2:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", @@ -40,8 +40,8 @@ go_test( srcs = ["strategy_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/apps/replicaset/storage/BUILD b/pkg/registry/apps/replicaset/storage/BUILD index 70a72f6354cf8..5c7a8a38a7b4a 100644 --- a/pkg/registry/apps/replicaset/storage/BUILD +++ b/pkg/registry/apps/replicaset/storage/BUILD @@ -11,9 +11,9 @@ go_test( srcs = ["storage_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/registry/registrytest:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", @@ -35,12 +35,12 @@ go_library( srcs = ["storage.go"], importpath = "k8s.io/kubernetes/pkg/registry/apps/replicaset/storage", deps = [ + "//pkg/apis/apps:go_default_library", "//pkg/apis/apps/v1beta1:go_default_library", "//pkg/apis/apps/v1beta2:go_default_library", "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/autoscaling/v1:go_default_library", "//pkg/apis/autoscaling/validation:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", "//pkg/printers:go_default_library", "//pkg/printers/internalversion:go_default_library", diff --git a/pkg/registry/apps/replicaset/storage/storage.go b/pkg/registry/apps/replicaset/storage/storage.go index 87c8155fc9ece..d8bce92411db9 100644 --- a/pkg/registry/apps/replicaset/storage/storage.go +++ b/pkg/registry/apps/replicaset/storage/storage.go @@ -29,12 +29,12 @@ import ( "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/kubernetes/pkg/apis/apps" appsv1beta1 "k8s.io/kubernetes/pkg/apis/apps/v1beta1" appsv1beta2 "k8s.io/kubernetes/pkg/apis/apps/v1beta2" "k8s.io/kubernetes/pkg/apis/autoscaling" autoscalingv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1" autoscalingvalidation "k8s.io/kubernetes/pkg/apis/autoscaling/validation" - "k8s.io/kubernetes/pkg/apis/extensions" extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" @@ -67,10 +67,10 @@ type REST struct { // NewREST returns a RESTStorage object that will work against ReplicaSet. func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) { store := &genericregistry.Store{ - NewFunc: func() runtime.Object { return &extensions.ReplicaSet{} }, - NewListFunc: func() runtime.Object { return &extensions.ReplicaSetList{} }, + NewFunc: func() runtime.Object { return &apps.ReplicaSet{} }, + NewListFunc: func() runtime.Object { return &apps.ReplicaSetList{} }, PredicateFunc: replicaset.MatchReplicaSet, - DefaultQualifiedResource: extensions.Resource("replicasets"), + DefaultQualifiedResource: apps.Resource("replicasets"), CreateStrategy: replicaset.Strategy, UpdateStrategy: replicaset.Strategy, @@ -116,7 +116,7 @@ type StatusREST struct { } func (r *StatusREST) New() runtime.Object { - return &extensions.ReplicaSet{} + return &apps.ReplicaSet{} } // Get retrieves the object from the storage. It is required to support Patch. @@ -160,9 +160,9 @@ func (r *ScaleREST) New() runtime.Object { func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { obj, err := r.store.Get(ctx, name, options) if err != nil { - return nil, errors.NewNotFound(extensions.Resource("replicasets/scale"), name) + return nil, errors.NewNotFound(apps.Resource("replicasets/scale"), name) } - rs := obj.(*extensions.ReplicaSet) + rs := obj.(*apps.ReplicaSet) scale, err := scaleFromReplicaSet(rs) if err != nil { return nil, errors.NewBadRequest(fmt.Sprintf("%v", err)) @@ -173,9 +173,9 @@ func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOpt func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { obj, err := r.store.Get(ctx, name, &metav1.GetOptions{}) if err != nil { - return nil, false, errors.NewNotFound(extensions.Resource("replicasets/scale"), name) + return nil, false, errors.NewNotFound(apps.Resource("replicasets/scale"), name) } - rs := obj.(*extensions.ReplicaSet) + rs := obj.(*apps.ReplicaSet) oldScale, err := scaleFromReplicaSet(rs) if err != nil { @@ -196,7 +196,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update } if errs := autoscalingvalidation.ValidateScale(scale); len(errs) > 0 { - return nil, false, errors.NewInvalid(extensions.Kind("Scale"), scale.Name, errs) + return nil, false, errors.NewInvalid(autoscaling.Kind("Scale"), scale.Name, errs) } rs.Spec.Replicas = scale.Spec.Replicas @@ -205,7 +205,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update if err != nil { return nil, false, err } - rs = obj.(*extensions.ReplicaSet) + rs = obj.(*apps.ReplicaSet) newScale, err := scaleFromReplicaSet(rs) if err != nil { return nil, false, errors.NewBadRequest(fmt.Sprintf("%v", err)) @@ -214,7 +214,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update } // scaleFromReplicaSet returns a scale subresource for a replica set. -func scaleFromReplicaSet(rs *extensions.ReplicaSet) (*autoscaling.Scale, error) { +func scaleFromReplicaSet(rs *apps.ReplicaSet) (*autoscaling.Scale, error) { selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) if err != nil { return nil, err diff --git a/pkg/registry/apps/replicaset/storage/storage_test.go b/pkg/registry/apps/replicaset/storage/storage_test.go index e1877c773e4bd..48420b8f23dae 100644 --- a/pkg/registry/apps/replicaset/storage/storage_test.go +++ b/pkg/registry/apps/replicaset/storage/storage_test.go @@ -31,9 +31,9 @@ import ( genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" "k8s.io/apiserver/pkg/registry/rest" etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" + "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/registry/registrytest" ) @@ -47,23 +47,23 @@ func newStorage(t *testing.T) (*ReplicaSetStorage, *etcdtesting.EtcdTestServer) } // createReplicaSet is a helper function that returns a ReplicaSet with the updated resource version. -func createReplicaSet(storage *REST, rs extensions.ReplicaSet, t *testing.T) (extensions.ReplicaSet, error) { +func createReplicaSet(storage *REST, rs apps.ReplicaSet, t *testing.T) (apps.ReplicaSet, error) { ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), rs.Namespace) obj, err := storage.Create(ctx, &rs, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Failed to create ReplicaSet, %v", err) } - newRS := obj.(*extensions.ReplicaSet) + newRS := obj.(*apps.ReplicaSet) return *newRS, nil } -func validNewReplicaSet() *extensions.ReplicaSet { - return &extensions.ReplicaSet{ +func validNewReplicaSet() *apps.ReplicaSet { + return &apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", Namespace: metav1.NamespaceDefault, }, - Spec: extensions.ReplicaSetSpec{ + Spec: apps.ReplicaSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}}, Template: api.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -84,7 +84,7 @@ func validNewReplicaSet() *extensions.ReplicaSet { }, Replicas: 7, }, - Status: extensions.ReplicaSetStatus{ + Status: apps.ReplicaSetStatus{ Replicas: 5, }, } @@ -103,8 +103,8 @@ func TestCreate(t *testing.T) { // valid rs, // invalid (invalid selector) - &extensions.ReplicaSet{ - Spec: extensions.ReplicaSetSpec{ + &apps.ReplicaSet{ + Spec: apps.ReplicaSetSpec{ Replicas: 2, Selector: &metav1.LabelSelector{MatchLabels: map[string]string{}}, Template: validReplicaSet.Spec.Template, @@ -123,18 +123,18 @@ func TestUpdate(t *testing.T) { validNewReplicaSet(), // valid updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.ReplicaSet) + object := obj.(*apps.ReplicaSet) object.Spec.Replicas = object.Spec.Replicas + 1 return object }, // invalid updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.ReplicaSet) + object := obj.(*apps.ReplicaSet) object.Name = "" return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*extensions.ReplicaSet) + object := obj.(*apps.ReplicaSet) object.Spec.Selector = &metav1.LabelSelector{MatchLabels: map[string]string{}} return object }, @@ -165,7 +165,7 @@ func TestGenerationNumber(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - storedRS, _ := etcdRS.(*extensions.ReplicaSet) + storedRS, _ := etcdRS.(*apps.ReplicaSet) // Generation initialization if storedRS.Generation != 1 || storedRS.Status.ObservedGeneration != 0 { @@ -181,7 +181,7 @@ func TestGenerationNumber(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - storedRS, _ = etcdRS.(*extensions.ReplicaSet) + storedRS, _ = etcdRS.(*apps.ReplicaSet) if storedRS.Generation != 2 || storedRS.Status.ObservedGeneration != 0 { t.Fatalf("Unexpected generation, spec: %v, status: %v", storedRS.Generation, storedRS.Status.ObservedGeneration) } @@ -195,7 +195,7 @@ func TestGenerationNumber(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - storedRS, _ = etcdRS.(*extensions.ReplicaSet) + storedRS, _ = etcdRS.(*apps.ReplicaSet) if storedRS.Generation != 2 || storedRS.Status.ObservedGeneration != 0 { t.Fatalf("Unexpected generation number, spec: %v, status: %v", storedRS.Generation, storedRS.Status.ObservedGeneration) } @@ -257,7 +257,7 @@ func TestScaleGet(t *testing.T) { name := "foo" - var rs extensions.ReplicaSet + var rs apps.ReplicaSet ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault) key := "/replicasets/" + metav1.NamespaceDefault + "/" + name if err := storage.ReplicaSet.Storage.Create(ctx, key, &validReplicaSet, &rs, 0, false); err != nil { @@ -302,7 +302,7 @@ func TestScaleUpdate(t *testing.T) { name := "foo" - var rs extensions.ReplicaSet + var rs apps.ReplicaSet ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault) key := "/replicasets/" + metav1.NamespaceDefault + "/" + name if err := storage.ReplicaSet.Storage.Create(ctx, key, &validReplicaSet, &rs, 0, false); err != nil { @@ -350,12 +350,12 @@ func TestStatusUpdate(t *testing.T) { if err := storage.ReplicaSet.Storage.Create(ctx, key, &validReplicaSet, nil, 0, false); err != nil { t.Fatalf("unexpected error: %v", err) } - update := extensions.ReplicaSet{ + update := apps.ReplicaSet{ ObjectMeta: validReplicaSet.ObjectMeta, - Spec: extensions.ReplicaSetSpec{ + Spec: apps.ReplicaSetSpec{ Replicas: defaultReplicas, }, - Status: extensions.ReplicaSetStatus{ + Status: apps.ReplicaSetStatus{ Replicas: defaultReplicas, }, } @@ -368,7 +368,7 @@ func TestStatusUpdate(t *testing.T) { t.Fatalf("unexpected error: %v", err) } - rs := obj.(*extensions.ReplicaSet) + rs := obj.(*apps.ReplicaSet) if rs.Spec.Replicas != 7 { t.Errorf("we expected .spec.replicas to not be updated but it was updated to %v", rs.Spec.Replicas) } diff --git a/pkg/registry/apps/replicaset/strategy.go b/pkg/registry/apps/replicaset/strategy.go index decb062c623d9..592c6893deae2 100644 --- a/pkg/registry/apps/replicaset/strategy.go +++ b/pkg/registry/apps/replicaset/strategy.go @@ -39,8 +39,8 @@ import ( "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/pod" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/apis/extensions/validation" + "k8s.io/kubernetes/pkg/apis/apps" + "k8s.io/kubernetes/pkg/apis/apps/validation" ) // rsStrategy implements verification logic for ReplicaSets. @@ -74,8 +74,8 @@ func (rsStrategy) NamespaceScoped() bool { // PrepareForCreate clears the status of a ReplicaSet before creation. func (rsStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { - rs := obj.(*extensions.ReplicaSet) - rs.Status = extensions.ReplicaSetStatus{} + rs := obj.(*apps.ReplicaSet) + rs.Status = apps.ReplicaSetStatus{} rs.Generation = 1 @@ -84,8 +84,8 @@ func (rsStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (rsStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { - newRS := obj.(*extensions.ReplicaSet) - oldRS := old.(*extensions.ReplicaSet) + newRS := obj.(*apps.ReplicaSet) + oldRS := old.(*apps.ReplicaSet) // update is not allowed to set status newRS.Status = oldRS.Status @@ -107,7 +107,7 @@ func (rsStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) // Validate validates a new ReplicaSet. func (rsStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { - rs := obj.(*extensions.ReplicaSet) + rs := obj.(*apps.ReplicaSet) return validation.ValidateReplicaSet(rs) } @@ -123,9 +123,9 @@ func (rsStrategy) AllowCreateOnUpdate() bool { // ValidateUpdate is the default update validation for an end user. func (rsStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - newReplicaSet := obj.(*extensions.ReplicaSet) - oldReplicaSet := old.(*extensions.ReplicaSet) - allErrs := validation.ValidateReplicaSet(obj.(*extensions.ReplicaSet)) + newReplicaSet := obj.(*apps.ReplicaSet) + oldReplicaSet := old.(*apps.ReplicaSet) + allErrs := validation.ValidateReplicaSet(obj.(*apps.ReplicaSet)) allErrs = append(allErrs, validation.ValidateReplicaSetUpdate(newReplicaSet, oldReplicaSet)...) // Update is not allowed to set Spec.Selector for all groups/versions except extensions/v1beta1. @@ -151,7 +151,7 @@ func (rsStrategy) AllowUnconditionalUpdate() bool { } // ReplicaSetToSelectableFields returns a field set that represents the object. -func ReplicaSetToSelectableFields(rs *extensions.ReplicaSet) fields.Set { +func ReplicaSetToSelectableFields(rs *apps.ReplicaSet) fields.Set { objectMetaFieldsSet := generic.ObjectMetaFieldsSet(&rs.ObjectMeta, true) rsSpecificFieldsSet := fields.Set{ "status.replicas": strconv.Itoa(int(rs.Status.Replicas)), @@ -161,7 +161,7 @@ func ReplicaSetToSelectableFields(rs *extensions.ReplicaSet) fields.Set { // GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) { - rs, ok := obj.(*extensions.ReplicaSet) + rs, ok := obj.(*apps.ReplicaSet) if !ok { return nil, nil, false, fmt.Errorf("given object is not a ReplicaSet.") } @@ -186,12 +186,12 @@ type rsStatusStrategy struct { var StatusStrategy = rsStatusStrategy{Strategy} func (rsStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { - newRS := obj.(*extensions.ReplicaSet) - oldRS := old.(*extensions.ReplicaSet) + newRS := obj.(*apps.ReplicaSet) + oldRS := old.(*apps.ReplicaSet) // update is not allowed to set spec newRS.Spec = oldRS.Spec } func (rsStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - return validation.ValidateReplicaSetStatusUpdate(obj.(*extensions.ReplicaSet), old.(*extensions.ReplicaSet)) + return validation.ValidateReplicaSetStatusUpdate(obj.(*apps.ReplicaSet), old.(*apps.ReplicaSet)) } diff --git a/pkg/registry/apps/replicaset/strategy_test.go b/pkg/registry/apps/replicaset/strategy_test.go index c2a98e3957f6b..6023fe0aa1ce4 100644 --- a/pkg/registry/apps/replicaset/strategy_test.go +++ b/pkg/registry/apps/replicaset/strategy_test.go @@ -24,8 +24,8 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" ) const ( @@ -57,13 +57,13 @@ func TestReplicaSetStrategy(t *testing.T) { }, }, } - rs := &extensions.ReplicaSet{ + rs := &apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: extensions.ReplicaSetSpec{ + Spec: apps.ReplicaSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: validSelector}, Template: validPodTemplate.Template, }, - Status: extensions.ReplicaSetStatus{ + Status: apps.ReplicaSetStatus{ Replicas: 1, ObservedGeneration: int64(10), }, @@ -81,7 +81,7 @@ func TestReplicaSetStrategy(t *testing.T) { t.Errorf("Unexpected error validating %v", errs) } - invalidRc := &extensions.ReplicaSet{ + invalidRc := &apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{Name: "bar", ResourceVersion: "4"}, } Strategy.PrepareForUpdate(ctx, invalidRc, rs) @@ -115,26 +115,26 @@ func TestReplicaSetStatusStrategy(t *testing.T) { }, }, } - oldRS := &extensions.ReplicaSet{ + oldRS := &apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "10"}, - Spec: extensions.ReplicaSetSpec{ + Spec: apps.ReplicaSetSpec{ Replicas: 3, Selector: &metav1.LabelSelector{MatchLabels: validSelector}, Template: validPodTemplate.Template, }, - Status: extensions.ReplicaSetStatus{ + Status: apps.ReplicaSetStatus{ Replicas: 1, ObservedGeneration: int64(10), }, } - newRS := &extensions.ReplicaSet{ + newRS := &apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "9"}, - Spec: extensions.ReplicaSetSpec{ + Spec: apps.ReplicaSetSpec{ Replicas: 1, Selector: &metav1.LabelSelector{MatchLabels: validSelector}, Template: validPodTemplate.Template, }, - Status: extensions.ReplicaSetStatus{ + Status: apps.ReplicaSetStatus{ Replicas: 3, ObservedGeneration: int64(11), }, @@ -203,14 +203,14 @@ func TestSelectorImmutability(t *testing.T) { } } -func newReplicaSetWithSelectorLabels(selectorLabels map[string]string) *extensions.ReplicaSet { - return &extensions.ReplicaSet{ +func newReplicaSetWithSelectorLabels(selectorLabels map[string]string) *apps.ReplicaSet { + return &apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Name: replicasetName, Namespace: namespace, ResourceVersion: "1", }, - Spec: extensions.ReplicaSetSpec{ + Spec: apps.ReplicaSetSpec{ Selector: &metav1.LabelSelector{ MatchLabels: selectorLabels, MatchExpressions: []metav1.LabelSelectorRequirement{}, diff --git a/pkg/registry/apps/statefulset/storage/BUILD b/pkg/registry/apps/statefulset/storage/BUILD index 3375715be0466..4d5e0c88349a9 100644 --- a/pkg/registry/apps/statefulset/storage/BUILD +++ b/pkg/registry/apps/statefulset/storage/BUILD @@ -40,7 +40,6 @@ go_library( "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/autoscaling/v1:go_default_library", "//pkg/apis/autoscaling/validation:go_default_library", - "//pkg/apis/extensions:go_default_library", "//pkg/printers:go_default_library", "//pkg/printers/internalversion:go_default_library", "//pkg/printers/storage:go_default_library", diff --git a/pkg/registry/apps/statefulset/storage/storage.go b/pkg/registry/apps/statefulset/storage/storage.go index 9808a4cadbcde..51d595f75fd45 100644 --- a/pkg/registry/apps/statefulset/storage/storage.go +++ b/pkg/registry/apps/statefulset/storage/storage.go @@ -33,7 +33,6 @@ import ( "k8s.io/kubernetes/pkg/apis/autoscaling" autoscalingv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1" autoscalingvalidation "k8s.io/kubernetes/pkg/apis/autoscaling/validation" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" printerstorage "k8s.io/kubernetes/pkg/printers/storage" @@ -184,7 +183,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update } if errs := autoscalingvalidation.ValidateScale(scale); len(errs) > 0 { - return nil, false, errors.NewInvalid(extensions.Kind("Scale"), scale.Name, errs) + return nil, false, errors.NewInvalid(autoscaling.Kind("Scale"), scale.Name, errs) } ss.Spec.Replicas = scale.Spec.Replicas diff --git a/pkg/registry/authentication/OWNERS b/pkg/registry/authentication/OWNERS index 81919881ff32f..c607d2aa8c5fe 100755 --- a/pkg/registry/authentication/OWNERS +++ b/pkg/registry/authentication/OWNERS @@ -1,2 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers reviewers: -- deads2k +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/pkg/registry/authorization/OWNERS b/pkg/registry/authorization/OWNERS index d21ad8662fdcf..cd0d70a0f8f02 100755 --- a/pkg/registry/authorization/OWNERS +++ b/pkg/registry/authorization/OWNERS @@ -1,4 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers reviewers: -- deads2k -- liggitt -- enj +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/pkg/registry/certificates/OWNERS b/pkg/registry/certificates/OWNERS index ce89a734755bb..470b7a1c92d15 100755 --- a/pkg/registry/certificates/OWNERS +++ b/pkg/registry/certificates/OWNERS @@ -1,11 +1,7 @@ +approvers: +- sig-auth-certificates-approvers reviewers: -- smarterclayton -- wojtek-t -- deads2k -- mikedanese -- liggitt -- timothysc -- dims -- hongchaodeng -- david-mcmahon -- enj +- sig-auth-certificates-reviewers +labels: +- sig/auth + diff --git a/pkg/registry/core/service/ipallocator/controller/BUILD b/pkg/registry/core/service/ipallocator/controller/BUILD index c10229edbb7de..8921bbc23ad11 100644 --- a/pkg/registry/core/service/ipallocator/controller/BUILD +++ b/pkg/registry/core/service/ipallocator/controller/BUILD @@ -13,8 +13,7 @@ go_library( deps = [ "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/apis/core/helper:go_default_library", - "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", + "//pkg/apis/core/v1/helper:go_default_library", "//pkg/registry/core/rangeallocation:go_default_library", "//pkg/registry/core/service/ipallocator:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", @@ -22,6 +21,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/util/retry:go_default_library", ], @@ -33,9 +33,10 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/apis/core:go_default_library", - "//pkg/client/clientset_generated/internalclientset/fake:go_default_library", "//pkg/registry/core/service/ipallocator:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", ], ) diff --git a/pkg/registry/core/service/ipallocator/controller/repair.go b/pkg/registry/core/service/ipallocator/controller/repair.go index b4aaf1c289c37..11bb117d74303 100644 --- a/pkg/registry/core/service/ipallocator/controller/repair.go +++ b/pkg/registry/core/service/ipallocator/controller/repair.go @@ -26,12 +26,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/tools/record" "k8s.io/client-go/util/retry" "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/core/helper" - coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" + "k8s.io/kubernetes/pkg/apis/core/v1/helper" "k8s.io/kubernetes/pkg/registry/core/rangeallocation" "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" ) @@ -53,7 +53,7 @@ import ( // TODO: perform repair? type Repair struct { interval time.Duration - serviceClient coreclient.ServicesGetter + serviceClient corev1client.ServicesGetter network *net.IPNet alloc rangeallocation.RangeRegistry leaks map[string]int // counter per leaked IP @@ -66,9 +66,9 @@ const numRepairsBeforeLeakCleanup = 3 // NewRepair creates a controller that periodically ensures that all clusterIPs are uniquely allocated across the cluster // and generates informational warnings for a cluster that is not in sync. -func NewRepair(interval time.Duration, serviceClient coreclient.ServicesGetter, eventClient coreclient.EventsGetter, network *net.IPNet, alloc rangeallocation.RangeRegistry) *Repair { +func NewRepair(interval time.Duration, serviceClient corev1client.ServicesGetter, eventClient corev1client.EventsGetter, network *net.IPNet, alloc rangeallocation.RangeRegistry) *Repair { eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartRecordingToSink(&coreclient.EventSinkImpl{Interface: eventClient.Events("")}) + eventBroadcaster.StartRecordingToSink(&corev1client.EventSinkImpl{Interface: eventClient.Events("")}) recorder := eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "ipallocator-repair-controller"}) return &Repair{ diff --git a/pkg/registry/core/service/ipallocator/controller/repair_test.go b/pkg/registry/core/service/ipallocator/controller/repair_test.go index 0bbd6f5959cb5..af2e59b22f493 100644 --- a/pkg/registry/core/service/ipallocator/controller/repair_test.go +++ b/pkg/registry/core/service/ipallocator/controller/repair_test.go @@ -22,9 +22,10 @@ import ( "strings" "testing" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" ) @@ -134,29 +135,29 @@ func TestRepairWithExisting(t *testing.T) { } fakeClient := fake.NewSimpleClientset( - &api.Service{ + &corev1.Service{ ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "one"}, - Spec: api.ServiceSpec{ClusterIP: "192.168.1.1"}, + Spec: corev1.ServiceSpec{ClusterIP: "192.168.1.1"}, }, - &api.Service{ + &corev1.Service{ ObjectMeta: metav1.ObjectMeta{Namespace: "two", Name: "two"}, - Spec: api.ServiceSpec{ClusterIP: "192.168.1.100"}, + Spec: corev1.ServiceSpec{ClusterIP: "192.168.1.100"}, }, - &api.Service{ // outside CIDR, will be dropped + &corev1.Service{ // outside CIDR, will be dropped ObjectMeta: metav1.ObjectMeta{Namespace: "three", Name: "three"}, - Spec: api.ServiceSpec{ClusterIP: "192.168.0.1"}, + Spec: corev1.ServiceSpec{ClusterIP: "192.168.0.1"}, }, - &api.Service{ // empty, ignored + &corev1.Service{ // empty, ignored ObjectMeta: metav1.ObjectMeta{Namespace: "four", Name: "four"}, - Spec: api.ServiceSpec{ClusterIP: ""}, + Spec: corev1.ServiceSpec{ClusterIP: ""}, }, - &api.Service{ // duplicate, dropped + &corev1.Service{ // duplicate, dropped ObjectMeta: metav1.ObjectMeta{Namespace: "five", Name: "five"}, - Spec: api.ServiceSpec{ClusterIP: "192.168.1.1"}, + Spec: corev1.ServiceSpec{ClusterIP: "192.168.1.1"}, }, - &api.Service{ // headless + &corev1.Service{ // headless ObjectMeta: metav1.ObjectMeta{Namespace: "six", Name: "six"}, - Spec: api.ServiceSpec{ClusterIP: "None"}, + Spec: corev1.ServiceSpec{ClusterIP: "None"}, }, ) diff --git a/pkg/registry/core/service/portallocator/controller/BUILD b/pkg/registry/core/service/portallocator/controller/BUILD index 8a6b511eda6d3..c4ea3f284d059 100644 --- a/pkg/registry/core/service/portallocator/controller/BUILD +++ b/pkg/registry/core/service/portallocator/controller/BUILD @@ -13,7 +13,6 @@ go_library( deps = [ "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", "//pkg/registry/core/rangeallocation:go_default_library", "//pkg/registry/core/service/portallocator:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", @@ -22,6 +21,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/util/retry:go_default_library", ], @@ -33,10 +33,11 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/apis/core:go_default_library", - "//pkg/client/clientset_generated/internalclientset/fake:go_default_library", "//pkg/registry/core/service/portallocator:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", ], ) diff --git a/pkg/registry/core/service/portallocator/controller/repair.go b/pkg/registry/core/service/portallocator/controller/repair.go index c1a4f0dadbd0e..20485cc044244 100644 --- a/pkg/registry/core/service/portallocator/controller/repair.go +++ b/pkg/registry/core/service/portallocator/controller/repair.go @@ -21,16 +21,17 @@ import ( "time" "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/tools/record" "k8s.io/client-go/util/retry" "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" - coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/registry/core/rangeallocation" "k8s.io/kubernetes/pkg/registry/core/service/portallocator" ) @@ -38,7 +39,7 @@ import ( // See ipallocator/controller/repair.go; this is a copy for ports. type Repair struct { interval time.Duration - serviceClient coreclient.ServicesGetter + serviceClient corev1client.ServicesGetter portRange net.PortRange alloc rangeallocation.RangeRegistry leaks map[int]int // counter per leaked port @@ -51,9 +52,9 @@ const numRepairsBeforeLeakCleanup = 3 // NewRepair creates a controller that periodically ensures that all ports are uniquely allocated across the cluster // and generates informational warnings for a cluster that is not in sync. -func NewRepair(interval time.Duration, serviceClient coreclient.ServicesGetter, eventClient coreclient.EventsGetter, portRange net.PortRange, alloc rangeallocation.RangeRegistry) *Repair { +func NewRepair(interval time.Duration, serviceClient corev1client.ServicesGetter, eventClient corev1client.EventsGetter, portRange net.PortRange, alloc rangeallocation.RangeRegistry) *Repair { eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartRecordingToSink(&coreclient.EventSinkImpl{Interface: eventClient.Events("")}) + eventBroadcaster.StartRecordingToSink(&corev1client.EventSinkImpl{Interface: eventClient.Events("")}) recorder := eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "portallocator-repair-controller"}) return &Repair{ @@ -196,7 +197,7 @@ func (c *Repair) runOnce() error { return nil } -func collectServiceNodePorts(service *api.Service) []int { +func collectServiceNodePorts(service *corev1.Service) []int { servicePorts := []int{} for i := range service.Spec.Ports { servicePort := &service.Spec.Ports[i] diff --git a/pkg/registry/core/service/portallocator/controller/repair_test.go b/pkg/registry/core/service/portallocator/controller/repair_test.go index 48c41aa989ab3..0df94f898d743 100644 --- a/pkg/registry/core/service/portallocator/controller/repair_test.go +++ b/pkg/registry/core/service/portallocator/controller/repair_test.go @@ -21,10 +21,11 @@ import ( "strings" "testing" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/net" + "k8s.io/client-go/kubernetes/fake" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/registry/core/service/portallocator" ) @@ -134,39 +135,39 @@ func TestRepairWithExisting(t *testing.T) { } fakeClient := fake.NewSimpleClientset( - &api.Service{ + &corev1.Service{ ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "one"}, - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{{NodePort: 111}}, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{NodePort: 111}}, }, }, - &api.Service{ + &corev1.Service{ ObjectMeta: metav1.ObjectMeta{Namespace: "two", Name: "two"}, - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{{NodePort: 122}, {NodePort: 133}}, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{NodePort: 122}, {NodePort: 133}}, }, }, - &api.Service{ // outside range, will be dropped + &corev1.Service{ // outside range, will be dropped ObjectMeta: metav1.ObjectMeta{Namespace: "three", Name: "three"}, - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{{NodePort: 201}}, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{NodePort: 201}}, }, }, - &api.Service{ // empty, ignored + &corev1.Service{ // empty, ignored ObjectMeta: metav1.ObjectMeta{Namespace: "four", Name: "four"}, - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{{}}, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{}}, }, }, - &api.Service{ // duplicate, dropped + &corev1.Service{ // duplicate, dropped ObjectMeta: metav1.ObjectMeta{Namespace: "five", Name: "five"}, - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{{NodePort: 111}}, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{NodePort: 111}}, }, }, - &api.Service{ + &corev1.Service{ ObjectMeta: metav1.ObjectMeta{Namespace: "six", Name: "six"}, - Spec: api.ServiceSpec{ + Spec: corev1.ServiceSpec{ HealthCheckNodePort: 144, }, }, diff --git a/pkg/registry/policy/OWNERS b/pkg/registry/policy/OWNERS index f65afe9ed9a48..787630abd2fd2 100755 --- a/pkg/registry/policy/OWNERS +++ b/pkg/registry/policy/OWNERS @@ -1,3 +1,7 @@ +approvers: +- sig-auth-policy-approvers reviewers: -- deads2k -- hongchaodeng +- sig-auth-policy-reviewers +labels: +- sig/auth + diff --git a/pkg/registry/rbac/OWNERS b/pkg/registry/rbac/OWNERS index d21ad8662fdcf..cd0d70a0f8f02 100755 --- a/pkg/registry/rbac/OWNERS +++ b/pkg/registry/rbac/OWNERS @@ -1,4 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers reviewers: -- deads2k -- liggitt -- enj +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/pkg/registry/rbac/reconciliation/BUILD b/pkg/registry/rbac/reconciliation/BUILD index 563d9fec99192..33b5a58511579 100644 --- a/pkg/registry/rbac/reconciliation/BUILD +++ b/pkg/registry/rbac/reconciliation/BUILD @@ -26,6 +26,7 @@ go_library( srcs = [ "clusterrole_interfaces.go", "clusterrolebinding_interfaces.go", + "namespace.go", "reconcile_role.go", "reconcile_rolebindings.go", "role_interfaces.go", @@ -42,6 +43,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/rbac/v1:go_default_library", ], diff --git a/pkg/registry/rbac/reconciliation/namespace.go b/pkg/registry/rbac/reconciliation/namespace.go new file mode 100644 index 0000000000000..2ee7fe9a2b0a1 --- /dev/null +++ b/pkg/registry/rbac/reconciliation/namespace.go @@ -0,0 +1,44 @@ +/* +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 reconciliation + +import ( + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" +) + +// tryEnsureNamespace gets or creates the given namespace while ignoring forbidden errors. +// It is a best effort attempt as the user may not be able to get or create namespaces. +// This allows us to handle flows where the user can only mutate roles and role bindings. +func tryEnsureNamespace(client corev1client.NamespaceInterface, namespace string) error { + _, getErr := client.Get(namespace, metav1.GetOptions{}) + if getErr == nil { + return nil + } + + if fatalGetErr := utilerrors.FilterOut(getErr, apierrors.IsNotFound, apierrors.IsForbidden); fatalGetErr != nil { + return fatalGetErr + } + + ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}} + _, createErr := client.Create(ns) + + return utilerrors.FilterOut(createErr, apierrors.IsAlreadyExists, apierrors.IsForbidden) +} diff --git a/pkg/registry/rbac/reconciliation/role_interfaces.go b/pkg/registry/rbac/reconciliation/role_interfaces.go index 24cb7899d3701..1c349d36e7d15 100644 --- a/pkg/registry/rbac/reconciliation/role_interfaces.go +++ b/pkg/registry/rbac/reconciliation/role_interfaces.go @@ -17,9 +17,7 @@ limitations under the License. package reconciliation import ( - corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" corev1client "k8s.io/client-go/kubernetes/typed/core/v1" @@ -90,8 +88,7 @@ func (c RoleModifier) Get(namespace, name string) (RuleOwner, error) { } func (c RoleModifier) Create(in RuleOwner) (RuleOwner, error) { - ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: in.GetNamespace()}} - if _, err := c.NamespaceClient.Create(ns); err != nil && !apierrors.IsAlreadyExists(err) { + if err := tryEnsureNamespace(c.NamespaceClient, in.GetNamespace()); err != nil { return nil, err } diff --git a/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go b/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go index 23bf6b653a88d..3d60537815e8a 100644 --- a/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go +++ b/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go @@ -17,9 +17,7 @@ limitations under the License. package reconciliation import ( - corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -92,8 +90,7 @@ func (c RoleBindingClientAdapter) Get(namespace, name string) (RoleBinding, erro } func (c RoleBindingClientAdapter) Create(in RoleBinding) (RoleBinding, error) { - ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: in.GetNamespace()}} - if _, err := c.NamespaceClient.Create(ns); err != nil && !apierrors.IsAlreadyExists(err) { + if err := tryEnsureNamespace(c.NamespaceClient, in.GetNamespace()); err != nil { return nil, err } diff --git a/pkg/registry/settings/podpreset/BUILD b/pkg/registry/settings/podpreset/BUILD index 3db54bf6c5489..56a3d37db1bb9 100644 --- a/pkg/registry/settings/podpreset/BUILD +++ b/pkg/registry/settings/podpreset/BUILD @@ -14,7 +14,6 @@ go_library( importpath = "k8s.io/kubernetes/pkg/registry/settings/podpreset", deps = [ "//pkg/api/legacyscheme:go_default_library", - "//pkg/api/pod:go_default_library", "//pkg/apis/settings:go_default_library", "//pkg/apis/settings/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/pkg/registry/settings/podpreset/strategy.go b/pkg/registry/settings/podpreset/strategy.go index b6e2f2c7b3e5f..658f5696483e1 100644 --- a/pkg/registry/settings/podpreset/strategy.go +++ b/pkg/registry/settings/podpreset/strategy.go @@ -23,7 +23,6 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" - "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/apis/settings" "k8s.io/kubernetes/pkg/apis/settings/validation" ) @@ -46,8 +45,6 @@ func (podPresetStrategy) NamespaceScoped() bool { func (podPresetStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { pip := obj.(*settings.PodPreset) pip.Generation = 1 - - pod.DropDisabledVolumeMountsAlphaFields(pip.Spec.VolumeMounts) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -55,9 +52,6 @@ func (podPresetStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime. newPodPreset := obj.(*settings.PodPreset) oldPodPreset := old.(*settings.PodPreset) - pod.DropDisabledVolumeMountsAlphaFields(oldPodPreset.Spec.VolumeMounts) - pod.DropDisabledVolumeMountsAlphaFields(newPodPreset.Spec.VolumeMounts) - // Update is not allowed newPodPreset.Spec = oldPodPreset.Spec } diff --git a/pkg/scheduler/BUILD b/pkg/scheduler/BUILD index 7880deda52937..22585cbad75c5 100644 --- a/pkg/scheduler/BUILD +++ b/pkg/scheduler/BUILD @@ -54,12 +54,12 @@ go_test( "//pkg/scheduler/factory:go_default_library", "//pkg/scheduler/internal/cache:go_default_library", "//pkg/scheduler/internal/cache/fake:go_default_library", - "//pkg/scheduler/testing:go_default_library", "//pkg/scheduler/volumebinder:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", @@ -67,6 +67,7 @@ go_test( "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", + "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library", ], diff --git a/pkg/scheduler/algorithm/predicates/metadata.go b/pkg/scheduler/algorithm/predicates/metadata.go index 7d63c45060101..3feb23e4937b0 100644 --- a/pkg/scheduler/algorithm/predicates/metadata.go +++ b/pkg/scheduler/algorithm/predicates/metadata.go @@ -399,7 +399,7 @@ func getTPMapMatchingExistingAntiAffinity(pod *v1.Pod, nodeInfoMap map[string]*s appendTopologyPairsMaps(existingPodTopologyMaps) } } - workqueue.Parallelize(16, len(allNodeNames), processNode) + workqueue.ParallelizeUntil(context.TODO(), 16, len(allNodeNames), processNode) return topologyMaps, firstError } @@ -408,13 +408,12 @@ func getTPMapMatchingExistingAntiAffinity(pod *v1.Pod, nodeInfoMap map[string]*s // predicate. With this topologyPairsMaps available, the affinity predicate does not // need to check all the pods in the cluster. func getTPMapMatchingIncomingAffinityAntiAffinity(pod *v1.Pod, nodeInfoMap map[string]*schedulercache.NodeInfo) (topologyPairsAffinityPodsMaps *topologyPairsMaps, topologyPairsAntiAffinityPodsMaps *topologyPairsMaps, err error) { - allNodeNames := make([]string, 0, len(nodeInfoMap)) - affinity := pod.Spec.Affinity if affinity == nil || (affinity.PodAffinity == nil && affinity.PodAntiAffinity == nil) { return newTopologyPairsMaps(), newTopologyPairsMaps(), nil } + allNodeNames := make([]string, 0, len(nodeInfoMap)) for name := range nodeInfoMap { allNodeNames = append(allNodeNames, name) } diff --git a/pkg/scheduler/algorithm/predicates/predicates_test.go b/pkg/scheduler/algorithm/predicates/predicates_test.go index c097486377297..d147ec2d716f0 100644 --- a/pkg/scheduler/algorithm/predicates/predicates_test.go +++ b/pkg/scheduler/algorithm/predicates/predicates_test.go @@ -2368,7 +2368,7 @@ func TestInterPodAffinity(t *testing.T) { pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, node: &node1, fits: false, - name: "satisfies the PodAffinity but doesn't satisfies the PodAntiAffinity with the existing pod", + name: "satisfies the PodAffinity but doesn't satisfy the PodAntiAffinity with the existing pod", expectFailureReasons: []algorithm.PredicateFailureReason{ErrPodAffinityNotMatch, ErrPodAntiAffinityRulesNotMatch}, }, { @@ -2441,7 +2441,7 @@ func TestInterPodAffinity(t *testing.T) { }, node: &node1, fits: false, - name: "satisfies the PodAffinity and PodAntiAffinity but doesn't satisfies PodAntiAffinity symmetry with the existing pod", + name: "satisfies the PodAffinity and PodAntiAffinity but doesn't satisfy PodAntiAffinity symmetry with the existing pod", expectFailureReasons: []algorithm.PredicateFailureReason{ErrPodAffinityNotMatch, ErrExistingPodsAntiAffinityRulesNotMatch}, }, { @@ -2984,7 +2984,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "machine3": false, }, nodesExpectAffinityFailureReasons: [][]algorithm.PredicateFailureReason{nil, nil, {ErrPodAffinityNotMatch, ErrPodAffinityRulesNotMatch}}, - name: "A pod can be scheduled onto all the nodes that have the same topology key & label value with one of them has an existing pod that match the affinity rules", + name: "A pod can be scheduled onto all the nodes that have the same topology key & label value with one of them has an existing pod that matches the affinity rules", }, { pod: &v1.Pod{ @@ -3037,7 +3037,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeA": false, "nodeB": true, }, - name: "NodeA and nodeB have same topologyKey and label value. NodeA does not satisfy node affinity rule, but has an existing pod that match the inter pod affinity rule. The pod can be scheduled onto nodeB.", + name: "NodeA and nodeB have same topologyKey and label value. NodeA does not satisfy node affinity rule, but has an existing pod that matches the inter pod affinity rule. The pod can be scheduled onto nodeB.", }, { pod: &v1.Pod{ @@ -3091,7 +3091,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeB": true, }, name: "The affinity rule is to schedule all of the pods of this collection to the same zone. The first pod of the collection " + - "should not be blocked from being scheduled onto any node, even there's no existing pod that match the rule anywhere.", + "should not be blocked from being scheduled onto any node, even there's no existing pod that matches the rule anywhere.", }, { pod: &v1.Pod{ @@ -3128,7 +3128,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeA": false, "nodeB": false, }, - name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that match the inter pod affinity rule. The pod can not be scheduled onto nodeA and nodeB.", + name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that matches the inter pod affinity rule. The pod can not be scheduled onto nodeA and nodeB.", }, { pod: &v1.Pod{ @@ -3219,7 +3219,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeB": false, "nodeC": true, }, - name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that match the inter pod affinity rule. The pod can not be scheduled onto nodeA and nodeB but can be scheduled onto nodeC", + name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that matches the inter pod affinity rule. The pod can not be scheduled onto nodeA and nodeB but can be scheduled onto nodeC", }, { pod: &v1.Pod{ @@ -3289,7 +3289,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeC": false, "nodeD": true, }, - name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that match the inter pod affinity rule. NodeC has an existing pod that match the inter pod affinity rule. The pod can not be scheduled onto nodeA, nodeB and nodeC but can be schedulerd onto nodeD", + name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that matches the inter pod affinity rule. NodeC has an existing pod that match the inter pod affinity rule. The pod can not be scheduled onto nodeA, nodeB and nodeC but can be schedulerd onto nodeD", nometa: true, }, { @@ -3367,7 +3367,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeB": false, "nodeC": true, }, - name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that match the inter pod affinity rule. The pod can not be scheduled onto nodeA, nodeB, but can be scheduled onto nodeC (NodeC has an existing pod that match the inter pod affinity rule but in different namespace)", + name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that matches the inter pod affinity rule. The pod can not be scheduled onto nodeA, nodeB, but can be scheduled onto nodeC (NodeC has an existing pod that match the inter pod affinity rule but in different namespace)", }, { pod: &v1.Pod{ @@ -3626,7 +3626,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeA": false, "nodeB": true, }, - name: "Test existing pod's anti-affinity: only when labelSelector and topologyKey both matches, it's counted as a single term match - case when one term has invalid topologyKey", + name: "Test existing pod's anti-affinity: only when labelSelector and topologyKey both match, it's counted as a single term match - case when one term has invalid topologyKey", }, { pod: &v1.Pod{ @@ -3680,7 +3680,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeA": false, "nodeB": true, }, - name: "Test incoming pod's anti-affinity: only when labelSelector and topologyKey both matches, it's counted as a single term match - case when one term has invalid topologyKey", + name: "Test incoming pod's anti-affinity: only when labelSelector and topologyKey both match, it's counted as a single term match - case when one term has invalid topologyKey", }, { pod: &v1.Pod{ @@ -3733,7 +3733,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeA": false, "nodeB": false, }, - name: "Test existing pod's anti-affinity: only when labelSelector and topologyKey both matches, it's counted as a single term match - case when all terms have valid topologyKey", + name: "Test existing pod's anti-affinity: only when labelSelector and topologyKey both match, it's counted as a single term match - case when all terms have valid topologyKey", }, { pod: &v1.Pod{ @@ -3788,7 +3788,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeA": false, "nodeB": false, }, - name: "Test incoming pod's anti-affinity: only when labelSelector and topologyKey both matches, it's counted as a single term match - case when all terms have valid topologyKey", + name: "Test incoming pod's anti-affinity: only when labelSelector and topologyKey both match, it's counted as a single term match - case when all terms have valid topologyKey", }, { pod: &v1.Pod{ @@ -3931,7 +3931,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeA": true, "nodeB": true, }, - name: "Test incoming pod's affinity: firstly check if all affinityTerms matches, and then check if all topologyKeys match", + name: "Test incoming pod's affinity: firstly check if all affinityTerms match, and then check if all topologyKeys match", }, { pod: &v1.Pod{ @@ -3992,7 +3992,7 @@ func TestInterPodAffinityWithMultipleNodes(t *testing.T) { "nodeA": false, "nodeB": false, }, - name: "Test incoming pod's affinity: firstly check if all affinityTerms matches, and then check if all topologyKeys match, and the match logic should be satified on the same pod", + name: "Test incoming pod's affinity: firstly check if all affinityTerms match, and then check if all topologyKeys match, and the match logic should be satified on the same pod", }, } @@ -4072,7 +4072,7 @@ func TestPodToleratesTaints(t *testing.T) { }, }, fits: false, - name: "a pod having no tolerations can't be scheduled onto a node with nonempty taints", + name: "A pod having no tolerations can't be scheduled onto a node with nonempty taints", }, { pod: &v1.Pod{ @@ -4090,7 +4090,7 @@ func TestPodToleratesTaints(t *testing.T) { }, }, fits: true, - name: "a pod which can be scheduled on a dedicated node assigned to user1 with effect NoSchedule", + name: "A pod which can be scheduled on a dedicated node assigned to user1 with effect NoSchedule", }, { pod: &v1.Pod{ @@ -4108,7 +4108,7 @@ func TestPodToleratesTaints(t *testing.T) { }, }, fits: false, - name: "a pod which can't be scheduled on a dedicated node assigned to user2 with effect NoSchedule", + name: "A pod which can't be scheduled on a dedicated node assigned to user2 with effect NoSchedule", }, { pod: &v1.Pod{ @@ -4126,7 +4126,7 @@ func TestPodToleratesTaints(t *testing.T) { }, }, fits: true, - name: "a pod can be scheduled onto the node, with a toleration uses operator Exists that tolerates the taints on the node", + name: "A pod can be scheduled onto the node, with a toleration uses operator Exists that tolerates the taints on the node", }, { pod: &v1.Pod{ @@ -4150,7 +4150,7 @@ func TestPodToleratesTaints(t *testing.T) { }, }, fits: true, - name: "a pod has multiple tolerations, node has multiple taints, all the taints are tolerated, pod can be scheduled onto the node", + name: "A pod has multiple tolerations, node has multiple taints, all the taints are tolerated, pod can be scheduled onto the node", }, { pod: &v1.Pod{ @@ -4170,7 +4170,7 @@ func TestPodToleratesTaints(t *testing.T) { }, }, fits: false, - name: "a pod has a toleration that keys and values match the taint on the node, but (non-empty) effect doesn't match, " + + name: "A pod has a toleration that keys and values match the taint on the node, but (non-empty) effect doesn't match, " + "can't be scheduled onto the node", }, { diff --git a/pkg/scheduler/algorithm/priorities/interpod_affinity.go b/pkg/scheduler/algorithm/priorities/interpod_affinity.go index 7e640566c82a6..7b3246e56d1c5 100644 --- a/pkg/scheduler/algorithm/priorities/interpod_affinity.go +++ b/pkg/scheduler/algorithm/priorities/interpod_affinity.go @@ -92,15 +92,13 @@ func (p *podAffinityPriorityMap) processTerm(term *v1.PodAffinityTerm, podDefini } match := priorityutil.PodMatchesTermsNamespaceAndSelector(podToCheck, namespaces, selector) if match { - func() { - p.Lock() - defer p.Unlock() - for _, node := range p.nodes { - if priorityutil.NodesHaveSameTopologyKey(node, fixedNode, term.TopologyKey) { - p.counts[node.Name] += weight - } + for _, node := range p.nodes { + if priorityutil.NodesHaveSameTopologyKey(node, fixedNode, term.TopologyKey) { + p.Lock() + p.counts[node.Name] += weight + p.Unlock() } - }() + } } } diff --git a/pkg/scheduler/algorithm/priorities/metadata_test.go b/pkg/scheduler/algorithm/priorities/metadata_test.go index c6a5f20f9e66b..a778df6f649cf 100644 --- a/pkg/scheduler/algorithm/priorities/metadata_test.go +++ b/pkg/scheduler/algorithm/priorities/metadata_test.go @@ -152,14 +152,14 @@ func TestPriorityMetadata(t *testing.T) { name: "Produce a priorityMetadata with specified requests", }, } - mataDataProducer := NewPriorityMetadataFactory( + metaDataProducer := NewPriorityMetadataFactory( schedulertesting.FakeServiceLister([]*v1.Service{}), schedulertesting.FakeControllerLister([]*v1.ReplicationController{}), schedulertesting.FakeReplicaSetLister([]*apps.ReplicaSet{}), schedulertesting.FakeStatefulSetLister([]*apps.StatefulSet{})) for _, test := range tests { t.Run(test.name, func(t *testing.T) { - ptData := mataDataProducer(test.pod, nil) + ptData := metaDataProducer(test.pod, nil) if !reflect.DeepEqual(test.expected, ptData) { t.Errorf("expected %#v, got %#v", test.expected, ptData) } diff --git a/pkg/scheduler/algorithm/priorities/selector_spreading_test.go b/pkg/scheduler/algorithm/priorities/selector_spreading_test.go index c0872f4272354..954f790068325 100644 --- a/pkg/scheduler/algorithm/priorities/selector_spreading_test.go +++ b/pkg/scheduler/algorithm/priorities/selector_spreading_test.go @@ -347,14 +347,14 @@ func TestSelectorSpreadPriority(t *testing.T) { statefulSetLister: schedulertesting.FakeStatefulSetLister(test.sss), } - mataDataProducer := NewPriorityMetadataFactory( + metaDataProducer := NewPriorityMetadataFactory( schedulertesting.FakeServiceLister(test.services), schedulertesting.FakeControllerLister(test.rcs), schedulertesting.FakeReplicaSetLister(test.rss), schedulertesting.FakeStatefulSetLister(test.sss)) - mataData := mataDataProducer(test.pod, nodeNameToInfo) + metaData := metaDataProducer(test.pod, nodeNameToInfo) - ttp := priorityFunction(selectorSpread.CalculateSpreadPriorityMap, selectorSpread.CalculateSpreadPriorityReduce, mataData) + ttp := priorityFunction(selectorSpread.CalculateSpreadPriorityMap, selectorSpread.CalculateSpreadPriorityReduce, metaData) list, err := ttp(test.pod, nodeNameToInfo, makeNodeList(test.nodes)) if err != nil { t.Errorf("unexpected error: %v \n", err) @@ -583,13 +583,13 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { statefulSetLister: schedulertesting.FakeStatefulSetLister(test.sss), } - mataDataProducer := NewPriorityMetadataFactory( + metaDataProducer := NewPriorityMetadataFactory( schedulertesting.FakeServiceLister(test.services), schedulertesting.FakeControllerLister(test.rcs), schedulertesting.FakeReplicaSetLister(test.rss), schedulertesting.FakeStatefulSetLister(test.sss)) - mataData := mataDataProducer(test.pod, nodeNameToInfo) - ttp := priorityFunction(selectorSpread.CalculateSpreadPriorityMap, selectorSpread.CalculateSpreadPriorityReduce, mataData) + metaData := metaDataProducer(test.pod, nodeNameToInfo) + ttp := priorityFunction(selectorSpread.CalculateSpreadPriorityMap, selectorSpread.CalculateSpreadPriorityReduce, metaData) list, err := ttp(test.pod, nodeNameToInfo, makeLabeledNodeList(labeledNodes)) if err != nil { t.Errorf("unexpected error: %v", err) @@ -760,7 +760,7 @@ func TestZoneSpreadPriority(t *testing.T) { }, } // these local variables just make sure controllerLister\replicaSetLister\statefulSetLister not nil - // when construct mataDataProducer + // when construct metaDataProducer sss := []*apps.StatefulSet{{Spec: apps.StatefulSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}} rcs := []*v1.ReplicationController{{Spec: v1.ReplicationControllerSpec{Selector: map[string]string{"foo": "bar"}}}} rss := []*apps.ReplicaSet{{Spec: apps.ReplicaSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}} @@ -770,13 +770,13 @@ func TestZoneSpreadPriority(t *testing.T) { nodeNameToInfo := schedulercache.CreateNodeNameToInfoMap(test.pods, makeLabeledNodeList(test.nodes)) zoneSpread := ServiceAntiAffinity{podLister: schedulertesting.FakePodLister(test.pods), serviceLister: schedulertesting.FakeServiceLister(test.services), label: "zone"} - mataDataProducer := NewPriorityMetadataFactory( + metaDataProducer := NewPriorityMetadataFactory( schedulertesting.FakeServiceLister(test.services), schedulertesting.FakeControllerLister(rcs), schedulertesting.FakeReplicaSetLister(rss), schedulertesting.FakeStatefulSetLister(sss)) - mataData := mataDataProducer(test.pod, nodeNameToInfo) - ttp := priorityFunction(zoneSpread.CalculateAntiAffinityPriorityMap, zoneSpread.CalculateAntiAffinityPriorityReduce, mataData) + metaData := metaDataProducer(test.pod, nodeNameToInfo) + ttp := priorityFunction(zoneSpread.CalculateAntiAffinityPriorityMap, zoneSpread.CalculateAntiAffinityPriorityReduce, metaData) list, err := ttp(test.pod, nodeNameToInfo, makeLabeledNodeList(test.nodes)) if err != nil { t.Errorf("unexpected error: %v", err) diff --git a/pkg/scheduler/algorithm/priorities/test_util.go b/pkg/scheduler/algorithm/priorities/test_util.go index 74ffef34cfb2d..da85c6b391bc9 100644 --- a/pkg/scheduler/algorithm/priorities/test_util.go +++ b/pkg/scheduler/algorithm/priorities/test_util.go @@ -41,18 +41,18 @@ func makeNode(node string, milliCPU, memory int64) *v1.Node { } } -func priorityFunction(mapFn algorithm.PriorityMapFunction, reduceFn algorithm.PriorityReduceFunction, mataData interface{}) algorithm.PriorityFunction { +func priorityFunction(mapFn algorithm.PriorityMapFunction, reduceFn algorithm.PriorityReduceFunction, metaData interface{}) algorithm.PriorityFunction { return func(pod *v1.Pod, nodeNameToInfo map[string]*schedulercache.NodeInfo, nodes []*v1.Node) (schedulerapi.HostPriorityList, error) { result := make(schedulerapi.HostPriorityList, 0, len(nodes)) for i := range nodes { - hostResult, err := mapFn(pod, mataData, nodeNameToInfo[nodes[i].Name]) + hostResult, err := mapFn(pod, metaData, nodeNameToInfo[nodes[i].Name]) if err != nil { return nil, err } result = append(result, hostResult) } if reduceFn != nil { - if err := reduceFn(pod, mataData, nodeNameToInfo, result); err != nil { + if err := reduceFn(pod, metaData, nodeNameToInfo, result); err != nil { return nil, err } } diff --git a/pkg/scheduler/algorithmprovider/defaults/defaults.go b/pkg/scheduler/algorithmprovider/defaults/defaults.go index ce1093cb5a979..6976e659d5a92 100644 --- a/pkg/scheduler/algorithmprovider/defaults/defaults.go +++ b/pkg/scheduler/algorithmprovider/defaults/defaults.go @@ -207,14 +207,16 @@ func ApplyFeatureGates() { factory.InsertPredicateKeyToAlgorithmProviderMap(predicates.PodToleratesNodeTaintsPred) factory.InsertPredicateKeyToAlgorithmProviderMap(predicates.CheckNodeUnschedulablePred) - glog.Warningf("TaintNodesByCondition is enabled, PodToleratesNodeTaints predicate is mandatory") + glog.Infof("TaintNodesByCondition is enabled, PodToleratesNodeTaints predicate is mandatory") } // Prioritizes nodes that satisfy pod's resource limits if utilfeature.DefaultFeatureGate.Enabled(features.ResourceLimitsPriorityFunction) { + glog.Infof("Registering resourcelimits priority function") factory.RegisterPriorityFunction2("ResourceLimitsPriority", priorities.ResourceLimitsPriorityMap, nil, 1) + // Register the priority function to specific provider too. + factory.InsertPriorityKeyToAlgorithmProviderMap(factory.RegisterPriorityFunction2("ResourceLimitsPriority", priorities.ResourceLimitsPriorityMap, nil, 1)) } - } func registerAlgorithmProvider(predSet, priSet sets.String) { diff --git a/pkg/scheduler/core/generic_scheduler.go b/pkg/scheduler/core/generic_scheduler.go index 092b9026af147..11802b9200f76 100644 --- a/pkg/scheduler/core/generic_scheduler.go +++ b/pkg/scheduler/core/generic_scheduler.go @@ -653,28 +653,23 @@ func PrioritizeNodes( results := make([]schedulerapi.HostPriorityList, len(priorityConfigs), len(priorityConfigs)) - for i, priorityConfig := range priorityConfigs { - if priorityConfig.Function != nil { - // DEPRECATED - wg.Add(1) - go func(index int, config algorithm.PriorityConfig) { - defer wg.Done() - var err error - results[index], err = config.Function(pod, nodeNameToInfo, nodes) - if err != nil { - appendError(err) - } - }(i, priorityConfig) - } else { - results[i] = make(schedulerapi.HostPriorityList, len(nodes)) - } + for i := range priorityConfigs { + results[i] = make(schedulerapi.HostPriorityList, len(nodes)) } processNode := func(index int) { nodeInfo := nodeNameToInfo[nodes[index].Name] var err error - for i := range priorityConfigs { + for i, priorityConfig := range priorityConfigs { + // DEPRECATED when ALL priorityConfigs have Map-Reduce pattern. if priorityConfigs[i].Function != nil { + // Make sure that the old-style priority function only runs once. + if results[i][0].Host == "" { + results[i], err = priorityConfig.Function(pod, nodeNameToInfo, nodes) + if err != nil { + appendError(err) + } + } continue } results[i][index], err = priorityConfigs[i].Map(pod, meta, nodeInfo) @@ -749,7 +744,7 @@ func PrioritizeNodes( if glog.V(10) { for i := range result { - glog.V(10).Infof("Host %s => Score %d", result[i].Host, result[i].Score) + glog.Infof("Host %s => Score %d", result[i].Host, result[i].Score) } } return result, nil diff --git a/pkg/scheduler/core/generic_scheduler_test.go b/pkg/scheduler/core/generic_scheduler_test.go index eae28ac6e9527..cfc1ea86f2223 100644 --- a/pkg/scheduler/core/generic_scheduler_test.go +++ b/pkg/scheduler/core/generic_scheduler_test.go @@ -706,15 +706,15 @@ func TestZeroRequest(t *testing.T) { nodeNameToInfo := schedulercache.CreateNodeNameToInfoMap(test.pods, test.nodes) - mataDataProducer := algorithmpriorities.NewPriorityMetadataFactory( + metaDataProducer := algorithmpriorities.NewPriorityMetadataFactory( schedulertesting.FakeServiceLister([]*v1.Service{}), schedulertesting.FakeControllerLister([]*v1.ReplicationController{}), schedulertesting.FakeReplicaSetLister([]*apps.ReplicaSet{}), schedulertesting.FakeStatefulSetLister([]*apps.StatefulSet{})) - mataData := mataDataProducer(test.pod, nodeNameToInfo) + metaData := metaDataProducer(test.pod, nodeNameToInfo) list, err := PrioritizeNodes( - test.pod, nodeNameToInfo, mataData, priorityConfigs, + test.pod, nodeNameToInfo, metaData, priorityConfigs, schedulertesting.FakeNodeLister(test.nodes), []algorithm.SchedulerExtender{}) if err != nil { t.Errorf("unexpected error: %v", err) diff --git a/pkg/scheduler/factory/BUILD b/pkg/scheduler/factory/BUILD index 9c3a25dd73028..6530261291693 100644 --- a/pkg/scheduler/factory/BUILD +++ b/pkg/scheduler/factory/BUILD @@ -23,7 +23,7 @@ go_library( "//pkg/scheduler/core:go_default_library", "//pkg/scheduler/core/equivalence:go_default_library", "//pkg/scheduler/internal/cache:go_default_library", - "//pkg/scheduler/internal/cache/comparer:go_default_library", + "//pkg/scheduler/internal/cache/debugger:go_default_library", "//pkg/scheduler/internal/queue:go_default_library", "//pkg/scheduler/util:go_default_library", "//pkg/scheduler/volumebinder:go_default_library", @@ -62,6 +62,7 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/api/testing:go_default_library", + "//pkg/apis/core:go_default_library", "//pkg/scheduler/algorithm:go_default_library", "//pkg/scheduler/algorithm/priorities:go_default_library", "//pkg/scheduler/api:go_default_library", @@ -72,6 +73,7 @@ go_test( "//pkg/scheduler/testing:go_default_library", "//pkg/scheduler/util:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", diff --git a/pkg/scheduler/factory/factory.go b/pkg/scheduler/factory/factory.go index bcc36fd869ee4..f77362465b81f 100644 --- a/pkg/scheduler/factory/factory.go +++ b/pkg/scheduler/factory/factory.go @@ -60,7 +60,7 @@ import ( "k8s.io/kubernetes/pkg/scheduler/core" "k8s.io/kubernetes/pkg/scheduler/core/equivalence" schedulerinternalcache "k8s.io/kubernetes/pkg/scheduler/internal/cache" - cachecomparer "k8s.io/kubernetes/pkg/scheduler/internal/cache/comparer" + cachedebugger "k8s.io/kubernetes/pkg/scheduler/internal/cache/debugger" internalqueue "k8s.io/kubernetes/pkg/scheduler/internal/queue" "k8s.io/kubernetes/pkg/scheduler/util" "k8s.io/kubernetes/pkg/scheduler/volumebinder" @@ -398,7 +398,7 @@ func NewConfigFactory(args *ConfigFactoryArgs) Configurator { } // Setup cache comparer - comparer := cachecomparer.New( + debugger := cachedebugger.New( args.NodeInformer.Lister(), args.PodInformer.Lister(), c.schedulerCache, @@ -415,7 +415,8 @@ func NewConfigFactory(args *ConfigFactoryArgs) Configurator { c.podQueue.Close() return case <-ch: - comparer.Compare() + debugger.Comparer.Compare() + debugger.Dumper.DumpAll() } } }() @@ -983,7 +984,10 @@ func (c *configFactory) updateNodeInCache(oldObj, newObj interface{}) { } c.invalidateCachedPredicatesOnNodeUpdate(newNode, oldNode) - c.podQueue.MoveAllToActiveQueue() + // Only activate unschedulable pods if the node became more schedulable. + if nodeSchedulingPropertiesChanged(newNode, oldNode) { + c.podQueue.MoveAllToActiveQueue() + } } func (c *configFactory) invalidateCachedPredicatesOnNodeUpdate(newNode *v1.Node, oldNode *v1.Node) { @@ -1055,6 +1059,64 @@ func (c *configFactory) invalidateCachedPredicatesOnNodeUpdate(newNode *v1.Node, } } +func nodeSchedulingPropertiesChanged(newNode *v1.Node, oldNode *v1.Node) bool { + if nodeAllocatableChanged(newNode, oldNode) { + glog.V(4).Infof("Allocatable resource of node %s changed", newNode.Name) + return true + } + if nodeLabelsChanged(newNode, oldNode) { + glog.V(4).Infof("Labels of node %s changed", newNode.Name) + return true + } + if nodeTaintsChanged(newNode, oldNode) { + glog.V(4).Infof("Taints of node %s changed", newNode.Name) + return true + } + if nodeConditionsChanged(newNode, oldNode) { + glog.V(4).Infof("Conditions of node %s changed", newNode.Name) + return true + } + if newNode.Spec.Unschedulable != oldNode.Spec.Unschedulable && newNode.Spec.Unschedulable == false { + glog.V(4).Infof("Node %s changed to schedulable", newNode.Name) + return true + } + return false +} + +func nodeAllocatableChanged(newNode *v1.Node, oldNode *v1.Node) bool { + return !reflect.DeepEqual(oldNode.Status.Allocatable, newNode.Status.Allocatable) +} + +func nodeLabelsChanged(newNode *v1.Node, oldNode *v1.Node) bool { + return !reflect.DeepEqual(oldNode.GetLabels(), newNode.GetLabels()) +} + +func nodeTaintsChanged(newNode *v1.Node, oldNode *v1.Node) bool { + if !reflect.DeepEqual(newNode.Spec.Taints, oldNode.Spec.Taints) { + return true + } + oldTaints, oldErr := helper.GetTaintsFromNodeAnnotations(oldNode.GetAnnotations()) + if oldErr != nil { + // If parse old node's taint annotation failed, we assume node's taint changed. + glog.Errorf("Failed to get taints from annotation of old node %s: %v", oldNode.Name, oldErr) + return true + } + newTaints, newErr := helper.GetTaintsFromNodeAnnotations(newNode.GetAnnotations()) + if newErr != nil { + // If parse new node's taint annotation failed, we assume node's taint changed. + glog.Errorf("Failed to get taints from annotation of new node %s: %v", newNode.Name, newErr) + return true + } + if !reflect.DeepEqual(oldTaints, newTaints) { + return true + } + return false +} + +func nodeConditionsChanged(newNode *v1.Node, oldNode *v1.Node) bool { + return !reflect.DeepEqual(oldNode.Status.Conditions, newNode.Status.Conditions) +} + func (c *configFactory) deleteNodeFromCache(obj interface{}) { var node *v1.Node switch t := obj.(type) { @@ -1096,7 +1158,6 @@ func (c *configFactory) CreateFromProvider(providerName string) (*Config, error) if err != nil { return nil, err } - return c.CreateFromKeys(provider.FitPredicateKeys, provider.PriorityFunctionKeys, []algorithm.SchedulerExtender{}) } diff --git a/pkg/scheduler/factory/factory_test.go b/pkg/scheduler/factory/factory_test.go index 346d964110ea5..2e7d4256e7821 100644 --- a/pkg/scheduler/factory/factory_test.go +++ b/pkg/scheduler/factory/factory_test.go @@ -24,6 +24,7 @@ import ( "time" "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/sets" @@ -34,6 +35,7 @@ import ( clienttesting "k8s.io/client-go/testing" "k8s.io/client-go/tools/cache" apitesting "k8s.io/kubernetes/pkg/api/testing" + "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/scheduler/algorithm" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" latestschedulerapi "k8s.io/kubernetes/pkg/scheduler/api/latest" @@ -634,3 +636,130 @@ func testGetBinderFunc(expectedBinderType, podName string, extenders []algorithm t.Errorf("Expected binder %q but got %q", expectedBinderType, binderType) } } + +func TestNodeAllocatableChanged(t *testing.T) { + newQuantity := func(value int64) resource.Quantity { + return *resource.NewQuantity(value, resource.BinarySI) + } + for _, c := range []struct { + Changed bool + OldAllocatable v1.ResourceList + NewAllocatable v1.ResourceList + }{ + // No allocatable resources changed. + { + Changed: false, + OldAllocatable: v1.ResourceList{v1.ResourceMemory: newQuantity(1024)}, + NewAllocatable: v1.ResourceList{v1.ResourceMemory: newQuantity(1024)}, + }, + // New node has more allocatable resources. + { + Changed: true, + OldAllocatable: v1.ResourceList{v1.ResourceMemory: newQuantity(1024)}, + NewAllocatable: v1.ResourceList{v1.ResourceMemory: newQuantity(1024), v1.ResourceStorage: newQuantity(1024)}, + }, + } { + oldNode := &v1.Node{Status: v1.NodeStatus{Allocatable: c.OldAllocatable}} + newNode := &v1.Node{Status: v1.NodeStatus{Allocatable: c.NewAllocatable}} + changed := nodeAllocatableChanged(newNode, oldNode) + if changed != c.Changed { + t.Errorf("nodeAllocatableChanged should be %t, got %t", c.Changed, changed) + } + } +} + +func TestNodeLabelsChanged(t *testing.T) { + for _, c := range []struct { + Changed bool + OldLabels map[string]string + NewLabels map[string]string + }{ + // No labels changed. + {Changed: false, OldLabels: map[string]string{"foo": "bar"}, NewLabels: map[string]string{"foo": "bar"}}, + // Labels changed. + {Changed: true, OldLabels: map[string]string{"foo": "bar"}, NewLabels: map[string]string{"foo": "bar", "test": "value"}}, + } { + oldNode := &v1.Node{ObjectMeta: metav1.ObjectMeta{Labels: c.OldLabels}} + newNode := &v1.Node{ObjectMeta: metav1.ObjectMeta{Labels: c.NewLabels}} + changed := nodeLabelsChanged(newNode, oldNode) + if changed != c.Changed { + t.Errorf("nodeLabelsChanged should be %t, got %t", c.Changed, changed) + } + } +} + +func TestNodeTaintsChanged(t *testing.T) { + for _, c := range []struct { + Changed bool + OldTaints []v1.Taint + NewTaints []v1.Taint + OldAnnotations map[string]string + NewAnnotations map[string]string + }{ + // Taints use annotation and no change. + { + Changed: false, + OldAnnotations: map[string]string{core.TaintsAnnotationKey: `[{"key":"value"}]`}, + NewAnnotations: map[string]string{core.TaintsAnnotationKey: `[{"key":"value"}]`}, + }, + // Taints use annotation and changed. + { + Changed: true, + OldAnnotations: map[string]string{core.TaintsAnnotationKey: `[{"key":"value1"}]`}, + NewAnnotations: map[string]string{core.TaintsAnnotationKey: `[{"key":"value2"}]`}, + }, + // Taints use Spec.Taints and no change. + { + Changed: false, + OldTaints: []v1.Taint{{Key: "key", Value: "value"}}, + NewTaints: []v1.Taint{{Key: "key", Value: "value"}}, + }, + // Taints use Spec.Taints and changed. + { + Changed: true, + OldTaints: []v1.Taint{{Key: "key", Value: "value1"}}, + NewTaints: []v1.Taint{{Key: "key", Value: "value2"}}, + }, + } { + oldNode := &v1.Node{ObjectMeta: metav1.ObjectMeta{Annotations: c.OldAnnotations}, Spec: v1.NodeSpec{Taints: c.OldTaints}} + newNode := &v1.Node{ObjectMeta: metav1.ObjectMeta{Annotations: c.NewAnnotations}, Spec: v1.NodeSpec{Taints: c.NewTaints}} + changed := nodeTaintsChanged(newNode, oldNode) + if changed != c.Changed { + t.Errorf("nodeTaintsChanged should be %t, not %t", c.Changed, changed) + } + } +} + +func TestNodeConditionsChanged(t *testing.T) { + for _, c := range []struct { + Changed bool + OldConditions []v1.NodeCondition + NewConditions []v1.NodeCondition + }{ + // No conditions changed. + { + Changed: false, + OldConditions: []v1.NodeCondition{{Type: v1.NodeOutOfDisk, Status: v1.ConditionTrue}}, + NewConditions: []v1.NodeCondition{{Type: v1.NodeOutOfDisk, Status: v1.ConditionTrue}}, + }, + // New node has more healthy conditions. + { + Changed: true, + OldConditions: []v1.NodeCondition{}, + NewConditions: []v1.NodeCondition{{Type: v1.NodeReady, Status: v1.ConditionTrue}}, + }, + // NodeReady False -> True + { + Changed: true, + OldConditions: []v1.NodeCondition{{Type: v1.NodeReady, Status: v1.ConditionFalse}}, + NewConditions: []v1.NodeCondition{{Type: v1.NodeReady, Status: v1.ConditionTrue}}, + }, + } { + oldNode := &v1.Node{Status: v1.NodeStatus{Conditions: c.OldConditions}} + newNode := &v1.Node{Status: v1.NodeStatus{Conditions: c.NewConditions}} + changed := nodeConditionsChanged(newNode, oldNode) + if changed != c.Changed { + t.Errorf("nodeConditionsChanged should be %t, got %t", c.Changed, changed) + } + } +} diff --git a/pkg/scheduler/factory/plugins.go b/pkg/scheduler/factory/plugins.go index 8c586bb978c47..a83cf78e5ec4e 100644 --- a/pkg/scheduler/factory/plugins.go +++ b/pkg/scheduler/factory/plugins.go @@ -167,6 +167,17 @@ func InsertPredicateKeyToAlgorithmProviderMap(key string) { return } +// InsertPriorityKeyToAlgorithmProviderMap inserts a priority function to all algorithmProviders which are in algorithmProviderMap. +func InsertPriorityKeyToAlgorithmProviderMap(key string) { + schedulerFactoryMutex.Lock() + defer schedulerFactoryMutex.Unlock() + + for _, provider := range algorithmProviderMap { + provider.PriorityFunctionKeys.Insert(key) + } + return +} + // RegisterMandatoryFitPredicate registers a fit predicate with the algorithm registry, the predicate is used by // kubelet, DaemonSet; it is always included in configuration. Returns the name with which the predicate was // registered. diff --git a/pkg/scheduler/internal/cache/BUILD b/pkg/scheduler/internal/cache/BUILD index cce14ec53bc1e..53f7681782cf4 100644 --- a/pkg/scheduler/internal/cache/BUILD +++ b/pkg/scheduler/internal/cache/BUILD @@ -54,7 +54,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", - "//pkg/scheduler/internal/cache/comparer:all-srcs", + "//pkg/scheduler/internal/cache/debugger:all-srcs", "//pkg/scheduler/internal/cache/fake:all-srcs", ], tags = ["automanaged"], diff --git a/pkg/scheduler/internal/cache/comparer/BUILD b/pkg/scheduler/internal/cache/debugger/BUILD similarity index 92% rename from pkg/scheduler/internal/cache/comparer/BUILD rename to pkg/scheduler/internal/cache/debugger/BUILD index c35831fbb8369..42c9c060614a9 100644 --- a/pkg/scheduler/internal/cache/comparer/BUILD +++ b/pkg/scheduler/internal/cache/debugger/BUILD @@ -2,8 +2,12 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", - srcs = ["comparer.go"], - importpath = "k8s.io/kubernetes/pkg/scheduler/internal/cache/comparer", + srcs = [ + "comparer.go", + "debugger.go", + "dumper.go", + ], + importpath = "k8s.io/kubernetes/pkg/scheduler/internal/cache/debugger", visibility = ["//pkg/scheduler:__subpackages__"], deps = [ "//pkg/scheduler/cache:go_default_library", diff --git a/pkg/scheduler/internal/cache/comparer/comparer.go b/pkg/scheduler/internal/cache/debugger/comparer.go similarity index 91% rename from pkg/scheduler/internal/cache/comparer/comparer.go rename to pkg/scheduler/internal/cache/debugger/comparer.go index bf043fa3f9242..00a1b0c3d618e 100644 --- a/pkg/scheduler/internal/cache/comparer/comparer.go +++ b/pkg/scheduler/internal/cache/debugger/comparer.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package comparer +package debugger import ( "sort" @@ -37,21 +37,6 @@ type CacheComparer struct { PodQueue internalqueue.SchedulingQueue } -// New creates a CacheComparer. -func New( - nodeLister corelisters.NodeLister, - podLister corelisters.PodLister, - cache schedulerinternalcache.Cache, - podQueue internalqueue.SchedulingQueue, -) *CacheComparer { - return &CacheComparer{ - NodeLister: nodeLister, - PodLister: podLister, - Cache: cache, - PodQueue: podQueue, - } -} - // Compare compares the nodes and pods of NodeLister with Cache.Snapshot. func (c *CacheComparer) Compare() error { glog.V(3).Info("cache comparer started") diff --git a/pkg/scheduler/internal/cache/comparer/comparer_test.go b/pkg/scheduler/internal/cache/debugger/comparer_test.go similarity index 99% rename from pkg/scheduler/internal/cache/comparer/comparer_test.go rename to pkg/scheduler/internal/cache/debugger/comparer_test.go index 701bd87ada10d..967b4027b5dda 100644 --- a/pkg/scheduler/internal/cache/comparer/comparer_test.go +++ b/pkg/scheduler/internal/cache/debugger/comparer_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package comparer +package debugger import ( "reflect" diff --git a/pkg/scheduler/internal/cache/debugger/debugger.go b/pkg/scheduler/internal/cache/debugger/debugger.go new file mode 100644 index 0000000000000..64428d5693ef1 --- /dev/null +++ b/pkg/scheduler/internal/cache/debugger/debugger.go @@ -0,0 +1,50 @@ +/* +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 debugger + +import ( + corelisters "k8s.io/client-go/listers/core/v1" + internalcache "k8s.io/kubernetes/pkg/scheduler/internal/cache" + internalqueue "k8s.io/kubernetes/pkg/scheduler/internal/queue" +) + +// CacheDebugger provides ways to check and write cache information for debugging. +type CacheDebugger struct { + Comparer CacheComparer + Dumper CacheDumper +} + +// New creates a CacheDebugger. +func New( + nodeLister corelisters.NodeLister, + podLister corelisters.PodLister, + cache internalcache.Cache, + podQueue internalqueue.SchedulingQueue, +) *CacheDebugger { + return &CacheDebugger{ + Comparer: CacheComparer{ + NodeLister: nodeLister, + PodLister: podLister, + Cache: cache, + PodQueue: podQueue, + }, + Dumper: CacheDumper{ + cache: cache, + podQueue: podQueue, + }, + } +} diff --git a/pkg/scheduler/internal/cache/debugger/dumper.go b/pkg/scheduler/internal/cache/debugger/dumper.go new file mode 100644 index 0000000000000..213468c789c8e --- /dev/null +++ b/pkg/scheduler/internal/cache/debugger/dumper.go @@ -0,0 +1,78 @@ +/* +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 debugger + +import ( + "fmt" + "strings" + + "github.com/golang/glog" + + "k8s.io/api/core/v1" + "k8s.io/kubernetes/pkg/scheduler/cache" + internalcache "k8s.io/kubernetes/pkg/scheduler/internal/cache" + "k8s.io/kubernetes/pkg/scheduler/internal/queue" +) + +// CacheDumper writes some information from the scheduler cache and the scheduling queue to the +// scheduler logs for debugging purposes. +type CacheDumper struct { + cache internalcache.Cache + podQueue queue.SchedulingQueue +} + +// DumpAll writes cached nodes and scheduling queue information to the scheduler logs. +func (d *CacheDumper) DumpAll() { + d.dumpNodes() + d.dumpSchedulingQueue() +} + +// dumpNodes writes NodeInfo to the scheduler logs. +func (d *CacheDumper) dumpNodes() { + snapshot := d.cache.Snapshot() + glog.Info("Dump of cached NodeInfo") + for _, nodeInfo := range snapshot.Nodes { + glog.Info(printNodeInfo(nodeInfo)) + } +} + +// dumpSchedulingQueue writes pods in the scheduling queue to the scheduler logs. +func (d *CacheDumper) dumpSchedulingQueue() { + waitingPods := d.podQueue.WaitingPods() + var podData strings.Builder + for _, p := range waitingPods { + podData.WriteString(printPod(p)) + } + glog.Infof("Dump of scheduling queue:\n%s", podData.String()) +} + +// printNodeInfo writes parts of NodeInfo to a string. +func printNodeInfo(n *cache.NodeInfo) string { + var nodeData strings.Builder + nodeData.WriteString(fmt.Sprintf("\nNode name: %+v\nRequested Resources: %+v\nAllocatable Resources:%+v\nNumber of Pods: %v\nPods:\n", + n.Node().Name, n.RequestedResource(), n.AllocatableResource(), len(n.Pods()))) + // Dumping Pod Info + for _, p := range n.Pods() { + nodeData.WriteString(printPod(p)) + } + return nodeData.String() +} + +// printPod writes parts of a Pod object to a string. +func printPod(p *v1.Pod) string { + return fmt.Sprintf("name: %v, namespace: %v, uid: %v, phase: %v, nominated node: %v\n", p.Name, p.Namespace, p.UID, p.Status.Phase, p.Status.NominatedNodeName) +} diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go index 79219115fedaf..699418ac8402d 100644 --- a/pkg/scheduler/scheduler_test.go +++ b/pkg/scheduler/scheduler_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/sets" @@ -34,6 +35,7 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" clientsetfake "k8s.io/client-go/kubernetes/fake" + corelister "k8s.io/client-go/listers/core/v1" clientcache "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -47,7 +49,6 @@ import ( "k8s.io/kubernetes/pkg/scheduler/factory" schedulerinternalcache "k8s.io/kubernetes/pkg/scheduler/internal/cache" fakecache "k8s.io/kubernetes/pkg/scheduler/internal/cache/fake" - schedulertesting "k8s.io/kubernetes/pkg/scheduler/testing" "k8s.io/kubernetes/pkg/scheduler/volumebinder" ) @@ -81,12 +82,20 @@ func (fp fakePodPreemptor) RemoveNominatedNodeName(pod *v1.Pod) error { return nil } +type nodeLister struct { + corelister.NodeLister +} + +func (n *nodeLister) List() ([]*v1.Node, error) { + return n.NodeLister.List(labels.Everything()) +} + func podWithID(id, desiredHost string) *v1.Pod { return &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: id, UID: types.UID(id), - SelfLink: schedulertesting.Test.SelfLink(string(v1.ResourcePods), id), + SelfLink: fmt.Sprintf("/api/v1/%s/%s", string(v1.ResourcePods), id), }, Spec: v1.PodSpec{ NodeName: desiredHost, @@ -100,8 +109,8 @@ func deletingPod(id string) *v1.Pod { ObjectMeta: metav1.ObjectMeta{ Name: id, UID: types.UID(id), - SelfLink: schedulertesting.Test.SelfLink(string(v1.ResourcePods), id), DeletionTimestamp: &deletionTimestamp, + SelfLink: fmt.Sprintf("/api/v1/%s/%s", string(v1.ResourcePods), id), }, Spec: v1.PodSpec{ NodeName: "", @@ -239,6 +248,15 @@ func TestScheduler(t *testing.T) { }, } + stop := make(chan struct{}) + defer close(stop) + client := clientsetfake.NewSimpleClientset(&testNode) + informerFactory := informers.NewSharedInformerFactory(client, 0) + nl := informerFactory.Core().V1().Nodes().Lister() + + informerFactory.Start(stop) + informerFactory.WaitForCacheSync(stop) + for _, item := range table { t.Run(item.name, func(t *testing.T) { var gotError error @@ -256,10 +274,8 @@ func TestScheduler(t *testing.T) { gotAssumedPod = pod }, }, - NodeLister: schedulertesting.FakeNodeLister( - []*v1.Node{&testNode}, - ), - Algorithm: item.algo, + NodeLister: &nodeLister{nl}, + Algorithm: item.algo, GetBinder: func(pod *v1.Pod) factory.Binder { return fakeBinder{func(b *v1.Binding) error { gotBinding = b @@ -317,9 +333,10 @@ func TestSchedulerNoPhantomPodAfterExpire(t *testing.T) { pod := podWithPort("pod.Name", "", 8080) node := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}} scache.AddNode(&node) - nodeLister := schedulertesting.FakeNodeLister([]*v1.Node{&node}) + client := clientsetfake.NewSimpleClientset(&node) + informerFactory := informers.NewSharedInformerFactory(client, 0) predicateMap := map[string]algorithm.FitPredicate{"PodFitsHostPorts": predicates.PodFitsHostPorts} - scheduler, bindingChan, _ := setupTestSchedulerWithOnePodOnNode(t, queuedPodStore, scache, nodeLister, predicateMap, pod, &node) + scheduler, bindingChan, _ := setupTestSchedulerWithOnePodOnNode(t, queuedPodStore, scache, informerFactory, stop, predicateMap, pod, &node) waitPodExpireChan := make(chan struct{}) timeout := make(chan struct{}) @@ -375,9 +392,10 @@ func TestSchedulerNoPhantomPodAfterDelete(t *testing.T) { firstPod := podWithPort("pod.Name", "", 8080) node := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}} scache.AddNode(&node) - nodeLister := schedulertesting.FakeNodeLister([]*v1.Node{&node}) + client := clientsetfake.NewSimpleClientset(&node) + informerFactory := informers.NewSharedInformerFactory(client, 0) predicateMap := map[string]algorithm.FitPredicate{"PodFitsHostPorts": predicates.PodFitsHostPorts} - scheduler, bindingChan, errChan := setupTestSchedulerWithOnePodOnNode(t, queuedPodStore, scache, nodeLister, predicateMap, firstPod, &node) + scheduler, bindingChan, errChan := setupTestSchedulerWithOnePodOnNode(t, queuedPodStore, scache, informerFactory, stop, predicateMap, firstPod, &node) // We use conflicted pod ports to incur fit predicate failure. secondPod := podWithPort("bar", "", 8080) @@ -463,11 +481,16 @@ func TestSchedulerErrorWithLongBinding(t *testing.T) { node := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}} scache.AddNode(&node) - nodeLister := schedulertesting.FakeNodeLister([]*v1.Node{&node}) + client := clientsetfake.NewSimpleClientset(&node) + informerFactory := informers.NewSharedInformerFactory(client, 0) predicateMap := map[string]algorithm.FitPredicate{"PodFitsHostPorts": predicates.PodFitsHostPorts} scheduler, bindingChan := setupTestSchedulerLongBindingWithRetry( - queuedPodStore, scache, nodeLister, predicateMap, stop, test.BindingDuration) + queuedPodStore, scache, informerFactory, predicateMap, stop, test.BindingDuration) + + informerFactory.Start(stop) + informerFactory.WaitForCacheSync(stop) + scheduler.Run() queuedPodStore.Add(firstPod) queuedPodStore.Add(conflictPod) @@ -495,9 +518,12 @@ func TestSchedulerErrorWithLongBinding(t *testing.T) { // queuedPodStore: pods queued before processing. // cache: scheduler cache that might contain assumed pods. func setupTestSchedulerWithOnePodOnNode(t *testing.T, queuedPodStore *clientcache.FIFO, scache schedulerinternalcache.Cache, - nodeLister schedulertesting.FakeNodeLister, predicateMap map[string]algorithm.FitPredicate, pod *v1.Pod, node *v1.Node) (*Scheduler, chan *v1.Binding, chan error) { + informerFactory informers.SharedInformerFactory, stop chan struct{}, predicateMap map[string]algorithm.FitPredicate, pod *v1.Pod, node *v1.Node) (*Scheduler, chan *v1.Binding, chan error) { - scheduler, bindingChan, errChan := setupTestScheduler(queuedPodStore, scache, nodeLister, predicateMap, nil) + scheduler, bindingChan, errChan := setupTestScheduler(queuedPodStore, scache, informerFactory, predicateMap, nil) + + informerFactory.Start(stop) + informerFactory.WaitForCacheSync(stop) queuedPodStore.Add(pod) // queuedPodStore: [foo:8080] @@ -540,7 +566,8 @@ func TestSchedulerFailedSchedulingReasons(t *testing.T) { }) // create several nodes which cannot schedule the above pod - nodes := []*v1.Node{} + var nodes []*v1.Node + var objects []runtime.Object for i := 0; i < 100; i++ { uid := fmt.Sprintf("machine%v", i) node := v1.Node{ @@ -559,8 +586,10 @@ func TestSchedulerFailedSchedulingReasons(t *testing.T) { } scache.AddNode(&node) nodes = append(nodes, &node) + objects = append(objects, &node) } - nodeLister := schedulertesting.FakeNodeLister(nodes) + client := clientsetfake.NewSimpleClientset(objects...) + informerFactory := informers.NewSharedInformerFactory(client, 0) predicateMap := map[string]algorithm.FitPredicate{ "PodFitsResources": predicates.PodFitsResources, } @@ -573,7 +602,10 @@ func TestSchedulerFailedSchedulingReasons(t *testing.T) { predicates.NewInsufficientResourceError(v1.ResourceMemory, 500, 0, 100), } } - scheduler, _, errChan := setupTestScheduler(queuedPodStore, scache, nodeLister, predicateMap, nil) + scheduler, _, errChan := setupTestScheduler(queuedPodStore, scache, informerFactory, predicateMap, nil) + + informerFactory.Start(stop) + informerFactory.WaitForCacheSync(stop) queuedPodStore.Add(podWithTooBigResourceRequests) scheduler.scheduleOne() @@ -597,7 +629,7 @@ func TestSchedulerFailedSchedulingReasons(t *testing.T) { // queuedPodStore: pods queued before processing. // scache: scheduler cache that might contain assumed pods. -func setupTestScheduler(queuedPodStore *clientcache.FIFO, scache schedulerinternalcache.Cache, nodeLister schedulertesting.FakeNodeLister, predicateMap map[string]algorithm.FitPredicate, recorder record.EventRecorder) (*Scheduler, chan *v1.Binding, chan error) { +func setupTestScheduler(queuedPodStore *clientcache.FIFO, scache schedulerinternalcache.Cache, informerFactory informers.SharedInformerFactory, predicateMap map[string]algorithm.FitPredicate, recorder record.EventRecorder) (*Scheduler, chan *v1.Binding, chan error) { algo := core.NewGenericScheduler( scache, nil, @@ -608,8 +640,8 @@ func setupTestScheduler(queuedPodStore *clientcache.FIFO, scache schedulerintern algorithm.EmptyPriorityMetadataProducer, []algorithm.SchedulerExtender{}, nil, - schedulertesting.FakePersistentVolumeClaimLister{}, - schedulertesting.FakePDBLister{}, + informerFactory.Core().V1().PersistentVolumeClaims().Lister(), + informerFactory.Policy().V1beta1().PodDisruptionBudgets().Lister(), false, false, api.DefaultPercentageOfNodesToScore) @@ -618,7 +650,7 @@ func setupTestScheduler(queuedPodStore *clientcache.FIFO, scache schedulerintern configurator := &FakeConfigurator{ Config: &factory.Config{ SchedulerCache: scache, - NodeLister: nodeLister, + NodeLister: &nodeLister{informerFactory.Core().V1().Nodes().Lister()}, Algorithm: algo, GetBinder: func(pod *v1.Pod) factory.Binder { return fakeBinder{func(b *v1.Binding) error { @@ -648,7 +680,7 @@ func setupTestScheduler(queuedPodStore *clientcache.FIFO, scache schedulerintern return sched, bindingChan, errChan } -func setupTestSchedulerLongBindingWithRetry(queuedPodStore *clientcache.FIFO, scache schedulerinternalcache.Cache, nodeLister schedulertesting.FakeNodeLister, predicateMap map[string]algorithm.FitPredicate, stop chan struct{}, bindingTime time.Duration) (*Scheduler, chan *v1.Binding) { +func setupTestSchedulerLongBindingWithRetry(queuedPodStore *clientcache.FIFO, scache schedulerinternalcache.Cache, informerFactory informers.SharedInformerFactory, predicateMap map[string]algorithm.FitPredicate, stop chan struct{}, bindingTime time.Duration) (*Scheduler, chan *v1.Binding) { algo := core.NewGenericScheduler( scache, nil, @@ -659,8 +691,8 @@ func setupTestSchedulerLongBindingWithRetry(queuedPodStore *clientcache.FIFO, sc algorithm.EmptyPriorityMetadataProducer, []algorithm.SchedulerExtender{}, nil, - schedulertesting.FakePersistentVolumeClaimLister{}, - schedulertesting.FakePDBLister{}, + informerFactory.Core().V1().PersistentVolumeClaims().Lister(), + informerFactory.Policy().V1beta1().PodDisruptionBudgets().Lister(), false, false, api.DefaultPercentageOfNodesToScore) @@ -668,7 +700,7 @@ func setupTestSchedulerLongBindingWithRetry(queuedPodStore *clientcache.FIFO, sc configurator := &FakeConfigurator{ Config: &factory.Config{ SchedulerCache: scache, - NodeLister: nodeLister, + NodeLister: &nodeLister{informerFactory.Core().V1().Nodes().Lister()}, Algorithm: algo, GetBinder: func(pod *v1.Pod) factory.Binder { return fakeBinder{func(b *v1.Binding) error { @@ -701,18 +733,21 @@ func setupTestSchedulerLongBindingWithRetry(queuedPodStore *clientcache.FIFO, sc func setupTestSchedulerWithVolumeBinding(fakeVolumeBinder *volumebinder.VolumeBinder, stop <-chan struct{}, broadcaster record.EventBroadcaster) (*Scheduler, chan *v1.Binding, chan error) { testNode := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}} - nodeLister := schedulertesting.FakeNodeLister([]*v1.Node{&testNode}) queuedPodStore := clientcache.NewFIFO(clientcache.MetaNamespaceKeyFunc) queuedPodStore.Add(podWithID("foo", "")) scache := schedulerinternalcache.New(10*time.Minute, stop) scache.AddNode(&testNode) + client := clientsetfake.NewSimpleClientset(&testNode) + informerFactory := informers.NewSharedInformerFactory(client, 0) predicateMap := map[string]algorithm.FitPredicate{ predicates.CheckVolumeBindingPred: predicates.NewVolumeBindingPredicate(fakeVolumeBinder), } recorder := broadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "scheduler"}) - s, bindingChan, errChan := setupTestScheduler(queuedPodStore, scache, nodeLister, predicateMap, recorder) + s, bindingChan, errChan := setupTestScheduler(queuedPodStore, scache, informerFactory, predicateMap, recorder) + informerFactory.Start(stop) + informerFactory.WaitForCacheSync(stop) s.config.VolumeBinder = fakeVolumeBinder return s, bindingChan, errChan } diff --git a/pkg/security/podsecuritypolicy/OWNERS b/pkg/security/podsecuritypolicy/OWNERS index 10c4b132f5e90..787630abd2fd2 100644 --- a/pkg/security/podsecuritypolicy/OWNERS +++ b/pkg/security/podsecuritypolicy/OWNERS @@ -1,10 +1,7 @@ approvers: - - deads2k - - liggitt - - pweil- - - tallclair +- sig-auth-policy-approvers reviewers: - - deads2k - - liggitt - - pweil- - - tallclair +- sig-auth-policy-reviewers +labels: +- sig/auth + diff --git a/pkg/serviceaccount/OWNERS b/pkg/serviceaccount/OWNERS index af89d3e6d6542..d914c0d7195a7 100644 --- a/pkg/serviceaccount/OWNERS +++ b/pkg/serviceaccount/OWNERS @@ -1,9 +1,7 @@ approvers: -- liggitt -- deads2k -- mikedanese +- sig-auth-serviceaccounts-approvers reviewers: -- liggitt -- deads2k -- mikedanese -- enj +- sig-auth-serviceaccounts-reviewers +labels: +- sig/auth + diff --git a/pkg/util/ipconfig/ipconfig.go b/pkg/util/ipconfig/ipconfig.go index 907c087f8eaf1..924c20b94a6f8 100644 --- a/pkg/util/ipconfig/ipconfig.go +++ b/pkg/util/ipconfig/ipconfig.go @@ -28,8 +28,8 @@ import ( // Interface is an injectable interface for running ipconfig commands. Implementations must be goroutine-safe. type Interface interface { - // GetDnsSuffixSearchList returns the list of DNS suffix to search - GetDnsSuffixSearchList() ([]string, error) + // GetDNSSuffixSearchList returns the list of DNS suffix to search + GetDNSSuffixSearchList() ([]string, error) } const ( @@ -54,8 +54,8 @@ func New(exec utilexec.Interface) Interface { return runner } -// GetDnsSuffixSearchList returns the list of DNS suffix to search -func (runner *runner) GetDnsSuffixSearchList() ([]string, error) { +// GetDNSSuffixSearchList returns the list of DNS suffix to search +func (runner *runner) GetDNSSuffixSearchList() ([]string, error) { // Parse the DNS suffix search list from ipconfig output // ipconfig /all on Windows displays the entry of DNS suffix search list // An example output contains: diff --git a/pkg/util/ipconfig/ipconfig_test.go b/pkg/util/ipconfig/ipconfig_test.go index d598d961d7815..a047311813416 100644 --- a/pkg/util/ipconfig/ipconfig_test.go +++ b/pkg/util/ipconfig/ipconfig_test.go @@ -22,11 +22,11 @@ import ( "k8s.io/utils/exec" ) -func TestGetDnsSuffixSearchList(t *testing.T) { +func TestGetDNSSuffixSearchList(t *testing.T) { // Simple test ipconfigInterface := New(exec.New()) - _, err := ipconfigInterface.GetDnsSuffixSearchList() + _, err := ipconfigInterface.GetDNSSuffixSearchList() if err != nil { t.Errorf("expected success, got %v", err) } diff --git a/pkg/util/ipvs/BUILD b/pkg/util/ipvs/BUILD index 9e487e4968acb..28ef80b71226d 100644 --- a/pkg/util/ipvs/BUILD +++ b/pkg/util/ipvs/BUILD @@ -34,42 +34,14 @@ go_library( "kernelcheck_unsupported.go", ], importpath = "k8s.io/kubernetes/pkg/util/ipvs", - deps = select({ - "@io_bazel_rules_go//go/platform:android": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:darwin": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:dragonfly": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:freebsd": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], + deps = [ + "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", + "//vendor/k8s.io/utils/exec:go_default_library", + ] + select({ "@io_bazel_rules_go//go/platform:linux": [ "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/github.com/docker/libnetwork/ipvs:go_default_library", "//vendor/github.com/golang/glog:go_default_library", - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:nacl": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:netbsd": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:openbsd": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:plan9": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:solaris": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], - "@io_bazel_rules_go//go/platform:windows": [ - "//vendor/k8s.io/utils/exec:go_default_library", ], "//conditions:default": [], }), diff --git a/pkg/util/ipvs/ipvs.go b/pkg/util/ipvs/ipvs.go index 5bfa3b1a2182f..6cd081851cee3 100644 --- a/pkg/util/ipvs/ipvs.go +++ b/pkg/util/ipvs/ipvs.go @@ -19,6 +19,11 @@ package ipvs import ( "net" "strconv" + "strings" + + "fmt" + "k8s.io/apimachinery/pkg/util/version" + "k8s.io/utils/exec" ) // Interface is an injectable interface for running ipvs commands. Implementations must be goroutine-safe. @@ -67,14 +72,21 @@ const ( IPVSProxyMode = "ipvs" ) -// Sets of IPVS required kernel modules. -var ipvsModules = []string{ - "ip_vs", - "ip_vs_rr", - "ip_vs_wrr", - "ip_vs_sh", - "nf_conntrack_ipv4", -} +// IPVS required kernel modules. +const ( + // ModIPVS is the kernel module "ip_vs" + ModIPVS string = "ip_vs" + // ModIPVSRR is the kernel module "ip_vs_rr" + ModIPVSRR string = "ip_vs_rr" + // ModIPVSWRR is the kernel module "ip_vs_wrr" + ModIPVSWRR string = "ip_vs_wrr" + // ModIPVSSH is the kernel module "ip_vs_sh" + ModIPVSSH string = "ip_vs_sh" + // ModNfConntrackIPV4 is the module "nf_conntrack_ipv4" + ModNfConntrackIPV4 string = "nf_conntrack_ipv4" + // ModNfConntrack is the kernel module "nf_conntrack" + ModNfConntrack string = "nf_conntrack" +) // Equal check the equality of virtual server. // We don't use struct == since it doesn't work because of slice. @@ -110,3 +122,29 @@ func (rs *RealServer) Equal(other *RealServer) bool { return rs.Address.Equal(other.Address) && rs.Port == other.Port } + +// GetKernelVersionAndIPVSMods returns the linux kernel version and the required ipvs modules +func GetKernelVersionAndIPVSMods(Executor exec.Interface) (kernelVersion string, ipvsModules []string, err error) { + kernelVersionFile := "/proc/sys/kernel/osrelease" + out, err := Executor.Command("cut", "-f1", "-d", " ", kernelVersionFile).CombinedOutput() + if err != nil { + return "", nil, fmt.Errorf("error getting os release kernel version: %v(%s)", err, out) + } + kernelVersion = strings.TrimSpace(string(out)) + // parse kernel version + ver1, err := version.ParseGeneric(kernelVersion) + if err != nil { + return kernelVersion, nil, fmt.Errorf("error parsing kernel version: %v(%s)", err, kernelVersion) + } + // "nf_conntrack_ipv4" has been removed since v4.19 + // see https://github.com/torvalds/linux/commit/a0ae2562c6c4b2721d9fddba63b7286c13517d9f + ver2, _ := version.ParseGeneric("4.19") + // get required ipvs modules + if ver1.LessThan(ver2) { + ipvsModules = append(ipvsModules, ModIPVS, ModIPVSRR, ModIPVSWRR, ModIPVSSH, ModNfConntrackIPV4) + } else { + ipvsModules = append(ipvsModules, ModIPVS, ModIPVSRR, ModIPVSWRR, ModIPVSSH, ModNfConntrack) + } + + return kernelVersion, ipvsModules, nil +} diff --git a/pkg/util/ipvs/kernelcheck_linux.go b/pkg/util/ipvs/kernelcheck_linux.go index 83c3e6b0fe90b..726606b97e062 100644 --- a/pkg/util/ipvs/kernelcheck_linux.go +++ b/pkg/util/ipvs/kernelcheck_linux.go @@ -44,6 +44,11 @@ func (r RequiredIPVSKernelModulesAvailableCheck) Name() string { func (r RequiredIPVSKernelModulesAvailableCheck) Check() (warnings, errors []error) { glog.V(1).Infoln("validating the kernel module IPVS required exists in machine or not") + kernelVersion, ipvsModules, err := GetKernelVersionAndIPVSMods(r.Executor) + if err != nil { + errors = append(errors, err) + } + // Find out loaded kernel modules out, err := r.Executor.Command("cut", "-f1", "-d", " ", "/proc/modules").CombinedOutput() if err != nil { @@ -60,14 +65,6 @@ func (r RequiredIPVSKernelModulesAvailableCheck) Check() (warnings, errors []err // Check builtin modules exist or not if len(modules) != 0 { - kernelVersionFile := "/proc/sys/kernel/osrelease" - b, err := r.Executor.Command("cut", "-f1", "-d", " ", kernelVersionFile).CombinedOutput() - if err != nil { - errors = append(errors, fmt.Errorf("error getting os release kernel version: %v(%s)", err, out)) - return nil, errors - } - - kernelVersion := strings.TrimSpace(string(b)) builtinModsFilePath := fmt.Sprintf("/lib/modules/%s/modules.builtin", kernelVersion) out, err := r.Executor.Command("cut", "-f1", "-d", " ", builtinModsFilePath).CombinedOutput() if err != nil { diff --git a/pkg/util/ipvs/kernelcheck_linux_test.go b/pkg/util/ipvs/kernelcheck_linux_test.go index 1f87a9239019c..8d2eb76465b09 100644 --- a/pkg/util/ipvs/kernelcheck_linux_test.go +++ b/pkg/util/ipvs/kernelcheck_linux_test.go @@ -97,8 +97,8 @@ func TestRequiredIPVSKernelModulesAvailableCheck(t *testing.T) { for i, tc := range cases { fcmd := fakeexec.FakeCmd{ CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{ - func() ([]byte, error) { return []byte(cases[i].loadedKernel), nil }, func() ([]byte, error) { return []byte(cases[i].kernelVersion), nil }, + func() ([]byte, error) { return []byte(cases[i].loadedKernel), nil }, func() ([]byte, error) { return []byte(cases[i].builtinKernel), nil }, }, } diff --git a/pkg/util/procfs/procfs_linux.go b/pkg/util/procfs/procfs_linux.go index fefc25bfbd682..0741b617efe80 100644 --- a/pkg/util/procfs/procfs_linux.go +++ b/pkg/util/procfs/procfs_linux.go @@ -21,6 +21,7 @@ package procfs import ( "bytes" "fmt" + "io" "io/ioutil" "os" "path" @@ -105,47 +106,60 @@ func PidOf(name string) ([]int, error) { func getPids(re *regexp.Regexp) []int { pids := []int{} - filepath.Walk("/proc", func(path string, info os.FileInfo, err error) error { + + dirFD, err := os.Open("/proc") + if err != nil { + return nil + } + defer dirFD.Close() + + for { + // Read a small number at a time in case there are many entries, we don't want to + // allocate a lot here. + ls, err := dirFD.Readdir(10) + if err == io.EOF { + break + } if err != nil { - // We should continue processing other directories/files return nil } - base := filepath.Base(path) - // Traverse only the directories we are interested in - if info.IsDir() && path != "/proc" { + + for _, entry := range ls { + if !entry.IsDir() { + continue + } + // If the directory is not a number (i.e. not a PID), skip it - if _, err := strconv.Atoi(base); err != nil { - return filepath.SkipDir + pid, err := strconv.Atoi(entry.Name()) + if err != nil { + continue + } + + cmdline, err := ioutil.ReadFile(filepath.Join("/proc", entry.Name(), "cmdline")) + if err != nil { + glog.V(4).Infof("Error reading file %s: %+v", filepath.Join("/proc", entry.Name(), "cmdline"), err) + continue + } + + // The bytes we read have '\0' as a separator for the command line + parts := bytes.SplitN(cmdline, []byte{0}, 2) + if len(parts) == 0 { + continue + } + // Split the command line itself we are interested in just the first part + exe := strings.FieldsFunc(string(parts[0]), func(c rune) bool { + return unicode.IsSpace(c) || c == ':' + }) + if len(exe) == 0 { + continue + } + // Check if the name of the executable is what we are looking for + if re.MatchString(exe[0]) { + // Grab the PID from the directory path + pids = append(pids, pid) } } - if base != "cmdline" { - return nil - } - cmdline, err := ioutil.ReadFile(path) - if err != nil { - glog.V(4).Infof("Error reading file %s: %+v", path, err) - return nil - } - // The bytes we read have '\0' as a separator for the command line - parts := bytes.SplitN(cmdline, []byte{0}, 2) - if len(parts) == 0 { - return nil - } - // Split the command line itself we are interested in just the first part - exe := strings.FieldsFunc(string(parts[0]), func(c rune) bool { - return unicode.IsSpace(c) || c == ':' - }) - if len(exe) == 0 { - return nil - } - // Check if the name of the executable is what we are looking for - if re.MatchString(exe[0]) { - dirname := filepath.Base(filepath.Dir(path)) - // Grab the PID from the directory path - pid, _ := strconv.Atoi(dirname) - pids = append(pids, pid) - } - return nil - }) + } + return pids } diff --git a/pkg/util/procfs/procfs_linux_test.go b/pkg/util/procfs/procfs_linux_test.go index c268ec6ae0614..71ef8f4142dbf 100644 --- a/pkg/util/procfs/procfs_linux_test.go +++ b/pkg/util/procfs/procfs_linux_test.go @@ -23,6 +23,7 @@ import ( "os" "os/signal" "path/filepath" + "regexp" "runtime" "syscall" "testing" @@ -95,3 +96,21 @@ func TestPKill(t *testing.T) { t.Fatalf("timeout waiting for %v", sig) } } + +func BenchmarkGetPids(b *testing.B) { + if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { + b.Skipf("not supported on GOOS=%s", runtime.GOOS) + } + + re, err := regexp.Compile("(^|/)" + filepath.Base(os.Args[0]) + "$") + assert.Empty(b, err) + + for i := 0; i < b.N; i++ { + pids := getPids(re) + + b.StopTimer() + assert.NotZero(b, pids) + assert.Contains(b, pids, os.Getpid()) + b.StartTimer() + } +} diff --git a/pkg/util/resourcecontainer/resource_container_linux.go b/pkg/util/resourcecontainer/resource_container_linux.go index 86477c5aa2ed1..efb6546857686 100644 --- a/pkg/util/resourcecontainer/resource_container_linux.go +++ b/pkg/util/resourcecontainer/resource_container_linux.go @@ -25,7 +25,7 @@ import ( "github.com/opencontainers/runc/libcontainer/configs" ) -// Creates resource-only containerName if it does not already exist and moves +// RunInResourceContainer creates resource-only containerName if it does not already exist and moves // the current process to it. // // containerName must be an absolute container name. diff --git a/pkg/util/resourcecontainer/resource_container_unsupported.go b/pkg/util/resourcecontainer/resource_container_unsupported.go index da47131265105..2c9db7b064ce3 100644 --- a/pkg/util/resourcecontainer/resource_container_unsupported.go +++ b/pkg/util/resourcecontainer/resource_container_unsupported.go @@ -22,6 +22,7 @@ import ( "errors" ) +// RunInResourceContainer creates resource-only containerName unsupported. func RunInResourceContainer(containerName string) error { return errors.New("resource-only containers unsupported in this platform") } diff --git a/pkg/util/taints/taints.go b/pkg/util/taints/taints.go index 0cf6212eb8fea..0777f6d69223c 100644 --- a/pkg/util/taints/taints.go +++ b/pkg/util/taints/taints.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// package taints implements utilites for working with taints +// package taints implements utilities for working with taints package taints import ( diff --git a/pkg/volume/BUILD b/pkg/volume/BUILD index 39419f90d3587..4d77d6073264b 100644 --- a/pkg/volume/BUILD +++ b/pkg/volume/BUILD @@ -9,6 +9,7 @@ go_library( "metrics_errors.go", "metrics_nil.go", "metrics_statfs.go", + "noop_expandable_plugin.go", "plugins.go", "volume.go", "volume_linux.go", diff --git a/pkg/volume/awsebs/attacher.go b/pkg/volume/awsebs/attacher.go index 81f9411217d50..6d325b978cf2a 100644 --- a/pkg/volume/awsebs/attacher.go +++ b/pkg/volume/awsebs/attacher.go @@ -24,6 +24,7 @@ import ( "time" "github.com/golang/glog" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" diff --git a/pkg/volume/awsebs/attacher_test.go b/pkg/volume/awsebs/attacher_test.go index 7fc397cc89af5..ae5fc9c8527a1 100644 --- a/pkg/volume/awsebs/attacher_test.go +++ b/pkg/volume/awsebs/attacher_test.go @@ -20,14 +20,14 @@ import ( "errors" "testing" + "github.com/golang/glog" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" - - "github.com/golang/glog" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" ) func TestGetVolumeName_Volume(t *testing.T) { diff --git a/pkg/volume/awsebs/aws_ebs.go b/pkg/volume/awsebs/aws_ebs.go index d668bb7962da5..31e61eb3264eb 100644 --- a/pkg/volume/awsebs/aws_ebs.go +++ b/pkg/volume/awsebs/aws_ebs.go @@ -26,6 +26,7 @@ import ( "strings" "github.com/golang/glog" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -311,6 +312,12 @@ func (plugin *awsElasticBlockStorePlugin) ExpandVolumeDevice( return awsVolume.ResizeDisk(volumeID, oldSize, newSize) } +func (plugin *awsElasticBlockStorePlugin) ExpandFS(spec *volume.Spec, devicePath, deviceMountPath string, _, _ resource.Quantity) error { + _, err := util.GenericResizeFS(plugin.host, plugin.GetPluginName(), devicePath, deviceMountPath) + return err +} + +var _ volume.FSResizableVolumePlugin = &awsElasticBlockStorePlugin{} var _ volume.ExpandableVolumePlugin = &awsElasticBlockStorePlugin{} var _ volume.VolumePluginWithAttachLimits = &awsElasticBlockStorePlugin{} diff --git a/pkg/volume/awsebs/aws_ebs_block.go b/pkg/volume/awsebs/aws_ebs_block.go index 10b5e42284653..efe52a470b8a6 100644 --- a/pkg/volume/awsebs/aws_ebs_block.go +++ b/pkg/volume/awsebs/aws_ebs_block.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/golang/glog" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" diff --git a/pkg/volume/awsebs/aws_util.go b/pkg/volume/awsebs/aws_util.go index 50fc701efede4..ce5b0b1bc415a 100644 --- a/pkg/volume/awsebs/aws_util.go +++ b/pkg/volume/awsebs/aws_util.go @@ -25,6 +25,7 @@ import ( "time" "github.com/golang/glog" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/sets" diff --git a/pkg/volume/azure_dd/BUILD b/pkg/volume/azure_dd/BUILD index 582c878f8a3ac..8330a7ab74086 100644 --- a/pkg/volume/azure_dd/BUILD +++ b/pkg/volume/azure_dd/BUILD @@ -39,7 +39,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/cloud-provider:go_default_library", - "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute:go_default_library", + "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute:go_default_library", "//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage:go_default_library", "//vendor/github.com/golang/glog:go_default_library", ], @@ -75,8 +75,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library", - "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute:go_default_library", - "//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage:go_default_library", + "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute:go_default_library", "//vendor/github.com/Azure/go-autorest/autorest/to:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", ], diff --git a/pkg/volume/azure_dd/attacher.go b/pkg/volume/azure_dd/attacher.go index e23a07290b9e1..5fd911f3724bc 100644 --- a/pkg/volume/azure_dd/attacher.go +++ b/pkg/volume/azure_dd/attacher.go @@ -25,7 +25,7 @@ import ( "strconv" "time" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/golang/glog" "k8s.io/api/core/v1" @@ -152,8 +152,6 @@ func (a *azureDiskAttacher) VolumesAreAttached(specs []*volume.Spec, nodeName ty } func (a *azureDiskAttacher) WaitForAttach(spec *volume.Spec, devicePath string, _ *v1.Pod, timeout time.Duration) (string, error) { - var err error - volumeSource, _, err := getVolumeSource(spec) if err != nil { return "", err @@ -167,13 +165,22 @@ func (a *azureDiskAttacher) WaitForAttach(spec *volume.Spec, devicePath string, nodeName := types.NodeName(a.plugin.host.GetHostName()) diskName := volumeSource.DiskName - glog.V(2).Infof("azureDisk - WaitForAttach: begin to GetDiskLun by diskName(%s), DataDiskURI(%s), nodeName(%s), devicePath(%s)", - diskName, volumeSource.DataDiskURI, nodeName, devicePath) - lun, err := diskController.GetDiskLun(diskName, volumeSource.DataDiskURI, nodeName) - if err != nil { - return "", err + var lun int32 + if runtime.GOOS == "windows" { + glog.V(2).Infof("azureDisk - WaitForAttach: begin to GetDiskLun by diskName(%s), DataDiskURI(%s), nodeName(%s), devicePath(%s)", + diskName, volumeSource.DataDiskURI, nodeName, devicePath) + lun, err = diskController.GetDiskLun(diskName, volumeSource.DataDiskURI, nodeName) + if err != nil { + return "", err + } + glog.V(2).Infof("azureDisk - WaitForAttach: GetDiskLun succeeded, got lun(%v)", lun) + } else { + lun, err = getDiskLUN(devicePath) + if err != nil { + return "", err + } } - glog.V(2).Infof("azureDisk - WaitForAttach: GetDiskLun succeeded, got lun(%v)", lun) + exec := a.plugin.host.GetExec(a.plugin.GetPluginName()) io := &osIOHandler{} diff --git a/pkg/volume/azure_dd/azure_common.go b/pkg/volume/azure_dd/azure_common.go index d7a8e2d0cbe53..9de53fe3368e0 100644 --- a/pkg/volume/azure_dd/azure_common.go +++ b/pkg/volume/azure_dd/azure_common.go @@ -21,9 +21,11 @@ import ( "io/ioutil" "os" "path/filepath" + "regexp" + "strconv" libstrings "strings" - "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -36,7 +38,7 @@ import ( ) const ( - defaultStorageAccountType = storage.StandardLRS + defaultStorageAccountType = compute.StandardLRS defaultAzureDiskKind = v1.AzureManagedDisk defaultAzureDataDiskCachingMode = v1.AzureDataDiskCachingNone ) @@ -59,6 +61,8 @@ var ( string(api.AzureSharedBlobDisk), string(api.AzureDedicatedBlobDisk), string(api.AzureManagedDisk)) + + lunPathRE = regexp.MustCompile(`/dev/disk/azure/scsi(?:.*)/lun(.+)`) ) func getPath(uid types.UID, volName string, host volume.VolumeHost) string { @@ -120,13 +124,13 @@ func normalizeKind(kind string) (v1.AzureDataDiskKind, error) { return v1.AzureDataDiskKind(kind), nil } -func normalizeStorageAccountType(storageAccountType string) (storage.SkuName, error) { +func normalizeStorageAccountType(storageAccountType string) (compute.DiskStorageAccountTypes, error) { if storageAccountType == "" { return defaultStorageAccountType, nil } - sku := storage.SkuName(storageAccountType) - supportedSkuNames := storage.PossibleSkuNameValues() + sku := compute.DiskStorageAccountTypes(storageAccountType) + supportedSkuNames := compute.PossibleDiskStorageAccountTypesValues() for _, s := range supportedSkuNames { if sku == s { return sku, nil @@ -201,3 +205,25 @@ func strFirstLetterToUpper(str string) string { } return libstrings.ToUpper(string(str[0])) + str[1:] } + +// getDiskLUN : deviceInfo could be a LUN number or a device path, e.g. /dev/disk/azure/scsi1/lun2 +func getDiskLUN(deviceInfo string) (int32, error) { + var diskLUN string + if len(deviceInfo) <= 2 { + diskLUN = deviceInfo + } else { + // extract the LUN num from a device path + matches := lunPathRE.FindStringSubmatch(deviceInfo) + if len(matches) == 2 { + diskLUN = matches[1] + } else { + return -1, fmt.Errorf("cannot parse deviceInfo: %s", deviceInfo) + } + } + + lun, err := strconv.Atoi(diskLUN) + if err != nil { + return -1, err + } + return int32(lun), nil +} diff --git a/pkg/volume/azure_dd/azure_common_test.go b/pkg/volume/azure_dd/azure_common_test.go index ec197ed873cd8..f100d1792b412 100644 --- a/pkg/volume/azure_dd/azure_common_test.go +++ b/pkg/volume/azure_dd/azure_common_test.go @@ -24,7 +24,7 @@ import ( "testing" "time" - "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/stretchr/testify/assert" "k8s.io/kubernetes/pkg/util/mount" @@ -141,12 +141,12 @@ func TestIoHandler(t *testing.T) { func TestNormalizeStorageAccountType(t *testing.T) { tests := []struct { storageAccountType string - expectedAccountType storage.SkuName + expectedAccountType compute.DiskStorageAccountTypes expectError bool }{ { storageAccountType: "", - expectedAccountType: storage.StandardLRS, + expectedAccountType: compute.StandardLRS, expectError: false, }, { @@ -156,27 +156,22 @@ func TestNormalizeStorageAccountType(t *testing.T) { }, { storageAccountType: "Standard_LRS", - expectedAccountType: storage.StandardLRS, + expectedAccountType: compute.StandardLRS, expectError: false, }, { storageAccountType: "Premium_LRS", - expectedAccountType: storage.PremiumLRS, + expectedAccountType: compute.PremiumLRS, expectError: false, }, { - storageAccountType: "Standard_GRS", - expectedAccountType: storage.StandardGRS, + storageAccountType: "StandardSSD_LRS", + expectedAccountType: compute.StandardSSDLRS, expectError: false, }, { - storageAccountType: "Standard_RAGRS", - expectedAccountType: storage.StandardRAGRS, - expectError: false, - }, - { - storageAccountType: "Standard_ZRS", - expectedAccountType: storage.StandardZRS, + storageAccountType: "UltraSSD_LRS", + expectedAccountType: compute.UltraSSDLRS, expectError: false, }, } @@ -187,3 +182,58 @@ func TestNormalizeStorageAccountType(t *testing.T) { assert.Equal(t, err != nil, test.expectError, fmt.Sprintf("error msg: %v", err)) } } + +func TestGetDiskLUN(t *testing.T) { + tests := []struct { + deviceInfo string + expectedLUN int32 + expectError bool + }{ + { + deviceInfo: "0", + expectedLUN: 0, + expectError: false, + }, + { + deviceInfo: "10", + expectedLUN: 10, + expectError: false, + }, + { + deviceInfo: "11d", + expectedLUN: -1, + expectError: true, + }, + { + deviceInfo: "999", + expectedLUN: -1, + expectError: true, + }, + { + deviceInfo: "", + expectedLUN: -1, + expectError: true, + }, + { + deviceInfo: "/dev/disk/azure/scsi1/lun2", + expectedLUN: 2, + expectError: false, + }, + { + deviceInfo: "/dev/disk/azure/scsi0/lun12", + expectedLUN: 12, + expectError: false, + }, + { + deviceInfo: "/dev/disk/by-id/scsi1/lun2", + expectedLUN: -1, + expectError: true, + }, + } + + for _, test := range tests { + result, err := getDiskLUN(test.deviceInfo) + assert.Equal(t, result, test.expectedLUN) + assert.Equal(t, err != nil, test.expectError, fmt.Sprintf("error msg: %v", err)) + } +} diff --git a/pkg/volume/azure_dd/azure_dd.go b/pkg/volume/azure_dd/azure_dd.go index 68e326bddfaff..f5e4c206d63a5 100644 --- a/pkg/volume/azure_dd/azure_dd.go +++ b/pkg/volume/azure_dd/azure_dd.go @@ -21,7 +21,7 @@ import ( "fmt" "strings" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage" "github.com/golang/glog" @@ -301,6 +301,13 @@ func (plugin *azureDataDiskPlugin) ExpandVolumeDevice( return diskController.ResizeDisk(spec.PersistentVolume.Spec.AzureDisk.DataDiskURI, oldSize, newSize) } +func (plugin *azureDataDiskPlugin) ExpandFS(spec *volume.Spec, devicePath, deviceMountPath string, _, _ resource.Quantity) error { + _, err := util.GenericResizeFS(plugin.host, plugin.GetPluginName(), devicePath, deviceMountPath) + return err +} + +var _ volume.FSResizableVolumePlugin = &azureDataDiskPlugin{} + func (plugin *azureDataDiskPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) { mounter := plugin.host.GetMounter(plugin.GetPluginName()) pluginDir := plugin.host.GetPluginDir(plugin.GetPluginName()) diff --git a/pkg/volume/azure_dd/azure_dd_test.go b/pkg/volume/azure_dd/azure_dd_test.go index fa97c4951e42b..965e9d3207c75 100644 --- a/pkg/volume/azure_dd/azure_dd_test.go +++ b/pkg/volume/azure_dd/azure_dd_test.go @@ -20,7 +20,7 @@ import ( "os" "testing" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" "github.com/Azure/go-autorest/autorest/to" "github.com/stretchr/testify/assert" diff --git a/pkg/volume/azure_dd/azure_provision.go b/pkg/volume/azure_dd/azure_provision.go index 519e7eb4b3dce..ca49550a5c481 100644 --- a/pkg/volume/azure_dd/azure_provision.go +++ b/pkg/volume/azure_dd/azure_provision.go @@ -22,6 +22,7 @@ import ( "strconv" "strings" + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -127,6 +128,9 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie availabilityZone string availabilityZones sets.String selectedAvailabilityZone string + + diskIopsReadWrite string + diskMbpsReadWrite string ) // maxLength = 79 - (4 for ".vhd") = 75 name := util.GenerateVolumeName(p.options.ClusterName, p.options.PVName, 75) @@ -165,6 +169,10 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie } case "zoned": strZoned = v + case "diskiopsreadwrite": + diskIopsReadWrite = v + case "diskmbpsreadwrite": + diskMbpsReadWrite = v default: return nil, fmt.Errorf("AzureDisk - invalid option %s in storage class", k) } @@ -241,6 +249,8 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie SizeGB: requestGiB, Tags: tags, AvailabilityZone: selectedAvailabilityZone, + DiskIOPSReadWrite: diskIopsReadWrite, + DiskMBpsReadWrite: diskMbpsReadWrite, } diskURI, err = diskController.CreateManagedDisk(volumeOptions) if err != nil { @@ -257,7 +267,7 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie return nil, err } } else { - diskURI, err = diskController.CreateBlobDisk(name, skuName, requestGiB) + diskURI, err = diskController.CreateBlobDisk(name, storage.SkuName(storageAccountType), requestGiB) if err != nil { return nil, err } diff --git a/pkg/volume/cephfs/cephfs.go b/pkg/volume/cephfs/cephfs.go index e1f506c0a9c9a..c78fbee8c36a3 100644 --- a/pkg/volume/cephfs/cephfs.go +++ b/pkg/volume/cephfs/cephfs.go @@ -34,7 +34,7 @@ import ( "k8s.io/kubernetes/pkg/volume/util" ) -// This is the primary entrypoint for volume plugins. +// ProbeVolumePlugins is the primary entrypoint for volume plugins. func ProbeVolumePlugins() []volume.VolumePlugin { return []volume.VolumePlugin{&cephfsPlugin{nil}} } @@ -144,7 +144,7 @@ func (plugin *cephfsPlugin) newMounterInternal(spec *volume.Spec, podUID types.U path: path, secret: secret, id: id, - secret_file: secretFile, + secretFile: secretFile, readonly: readOnly, mounter: mounter, plugin: plugin, @@ -182,16 +182,16 @@ func (plugin *cephfsPlugin) ConstructVolumeSpec(volumeName, mountPath string) (* // CephFS volumes represent a bare host file or directory mount of an CephFS export. type cephfs struct { - volName string - podUID types.UID - mon []string - path string - id string - secret string - secret_file string - readonly bool - mounter mount.Interface - plugin *cephfsPlugin + volName string + podUID types.UID + mon []string + path string + id string + secret string + secretFile string + readonly bool + mounter mount.Interface + plugin *cephfsPlugin volume.MetricsNil mountOptions []string } @@ -213,7 +213,7 @@ func (cephfsVolume *cephfsMounter) GetAttributes() volume.Attributes { // Checks prior to mount operations to verify that the required components (binaries, etc.) // to mount the volume are available on the underlying node. // If not, it returns an error -func (cephfsMounter *cephfsMounter) CanMount() error { +func (cephfsVolume *cephfsMounter) CanMount() error { return nil } @@ -250,10 +250,10 @@ func (cephfsVolume *cephfsMounter) SetUpAt(dir string, fsGroup *int64) error { if err == nil { // cephfs fuse mount succeeded. return nil - } else { - // if cephfs fuse mount failed, fallback to kernel mount. - glog.V(4).Infof("CephFS fuse mount failed: %v, fallback to kernel mount.", err) } + // if cephfs fuse mount failed, fallback to kernel mount. + glog.V(2).Infof("CephFS fuse mount failed: %v, fallback to kernel mount.", err) + } glog.V(4).Info("CephFS kernel mount.") @@ -298,19 +298,19 @@ func (cephfsVolume *cephfs) GetKeyringPath() string { func (cephfsVolume *cephfs) execMount(mountpoint string) error { // cephfs mount option - ceph_opt := "" + cephOpt := "" // override secretfile if secret is provided if cephfsVolume.secret != "" { - ceph_opt = "name=" + cephfsVolume.id + ",secret=" + cephfsVolume.secret + cephOpt = "name=" + cephfsVolume.id + ",secret=" + cephfsVolume.secret } else { - ceph_opt = "name=" + cephfsVolume.id + ",secretfile=" + cephfsVolume.secret_file + cephOpt = "name=" + cephfsVolume.id + ",secretfile=" + cephfsVolume.secretFile } // build option array opt := []string{} if cephfsVolume.readonly { opt = append(opt, "ro") } - opt = append(opt, ceph_opt) + opt = append(opt, cephOpt) // build src like mon1:6789,mon2:6789,mon3:6789:/ hosts := cephfsVolume.mon @@ -331,8 +331,8 @@ func (cephfsVolume *cephfs) execMount(mountpoint string) error { return nil } -func (cephfsMounter *cephfsMounter) checkFuseMount() bool { - execute := cephfsMounter.plugin.host.GetExec(cephfsMounter.plugin.GetPluginName()) +func (cephfsVolume *cephfsMounter) checkFuseMount() bool { + execute := cephfsVolume.plugin.host.GetExec(cephfsVolume.plugin.GetPluginName()) switch runtime.GOOS { case "linux": if _, err := execute.Run("/usr/bin/test", "-x", "/sbin/mount.fuse.ceph"); err == nil { @@ -346,7 +346,7 @@ func (cephfsMounter *cephfsMounter) checkFuseMount() bool { func (cephfsVolume *cephfs) execFuseMount(mountpoint string) error { // cephfs keyring file - keyring_file := "" + keyringFile := "" // override secretfile if secret is provided if cephfsVolume.secret != "" { // TODO: cephfs fuse currently doesn't support secret option, @@ -380,10 +380,10 @@ func (cephfsVolume *cephfs) execFuseMount(mountpoint string) error { return err } - keyring_file = path.Join(keyringPath, fileName) + keyringFile = path.Join(keyringPath, fileName) } else { - keyring_file = cephfsVolume.secret_file + keyringFile = cephfsVolume.secretFile } // build src like mon1:6789,mon2:6789,mon3:6789:/ @@ -399,7 +399,7 @@ func (cephfsVolume *cephfs) execFuseMount(mountpoint string) error { mountArgs := []string{} mountArgs = append(mountArgs, "-k") - mountArgs = append(mountArgs, keyring_file) + mountArgs = append(mountArgs, keyringFile) mountArgs = append(mountArgs, "-m") mountArgs = append(mountArgs, src) mountArgs = append(mountArgs, mountpoint) @@ -423,7 +423,7 @@ func (cephfsVolume *cephfs) execFuseMount(mountpoint string) error { command := exec.Command("ceph-fuse", mountArgs...) output, err := command.CombinedOutput() if err != nil || !(strings.Contains(string(output), "starting fuse")) { - return fmt.Errorf("Ceph-fuse failed: %v\narguments: %s\nOutput: %s\n", err, mountArgs, string(output)) + return fmt.Errorf("Ceph-fuse failed: %v\narguments: %s\nOutput: %s", err, mountArgs, string(output)) } return nil diff --git a/pkg/volume/cinder/cinder.go b/pkg/volume/cinder/cinder.go index e7d6b12750fd3..8e585338f02c0 100644 --- a/pkg/volume/cinder/cinder.go +++ b/pkg/volume/cinder/cinder.go @@ -267,6 +267,13 @@ func (plugin *cinderPlugin) ExpandVolumeDevice(spec *volume.Spec, newSize resour return expandedSize, nil } +func (plugin *cinderPlugin) ExpandFS(spec *volume.Spec, devicePath, deviceMountPath string, _, _ resource.Quantity) error { + _, err := util.GenericResizeFS(plugin.host, plugin.GetPluginName(), devicePath, deviceMountPath) + return err +} + +var _ volume.FSResizableVolumePlugin = &cinderPlugin{} + func (plugin *cinderPlugin) RequiresFSResize() bool { return true } diff --git a/pkg/volume/configmap/configmap.go b/pkg/volume/configmap/configmap.go index a1474d24595bb..4fd1a7332d85a 100644 --- a/pkg/volume/configmap/configmap.go +++ b/pkg/volume/configmap/configmap.go @@ -30,7 +30,7 @@ import ( volumeutil "k8s.io/kubernetes/pkg/volume/util" ) -// ProbeVolumePlugin is the entry point for plugin detection in a package. +// ProbeVolumePlugins is the entry point for plugin detection in a package. func ProbeVolumePlugins() []volume.VolumePlugin { return []volume.VolumePlugin{&configMapPlugin{}} } @@ -260,7 +260,7 @@ func (b *configMapVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { return nil } -// Note: this function is exported so that it can be called from the projection volume driver +// MakePayload function is exported so that it can be called from the projection volume driver func MakePayload(mappings []v1.KeyToPath, configMap *v1.ConfigMap, defaultMode *int32, optional bool) (map[string]volumeutil.FileProjection, error) { if defaultMode == nil { return nil, fmt.Errorf("No defaultMode used, not even the default value for it") diff --git a/pkg/volume/csi/csi_block.go b/pkg/volume/csi/csi_block.go index 6be3ec2494751..389b80a443d9a 100644 --- a/pkg/volume/csi/csi_block.go +++ b/pkg/volume/csi/csi_block.go @@ -276,6 +276,7 @@ func (m *csiBlockMapper) MapDevice(devicePath, globalMapPath, volumeMapPath, vol csiSource.VolumeAttributes, nodePublishSecrets, fsTypeBlockName, + []string{}, ) if err != nil { diff --git a/pkg/volume/csi/csi_client.go b/pkg/volume/csi/csi_client.go index a712105b41396..1d41400d1159b 100644 --- a/pkg/volume/csi/csi_client.go +++ b/pkg/volume/csi/csi_client.go @@ -49,6 +49,7 @@ type csiClient interface { volumeAttribs map[string]string, nodePublishSecrets map[string]string, fsType string, + mountOptions []string, ) error NodeUnpublishVolume( ctx context.Context, @@ -138,6 +139,7 @@ func (c *csiDriverClient) NodePublishVolume( volumeAttribs map[string]string, nodePublishSecrets map[string]string, fsType string, + mountOptions []string, ) error { glog.V(4).Info(log("calling NodePublishVolume rpc [volid=%s,target_path=%s]", volID, targetPath)) if volID == "" { @@ -177,7 +179,8 @@ func (c *csiDriverClient) NodePublishVolume( } else { req.VolumeCapability.AccessType = &csipb.VolumeCapability_Mount{ Mount: &csipb.VolumeCapability_MountVolume{ - FsType: fsType, + FsType: fsType, + MountFlags: mountOptions, }, } } diff --git a/pkg/volume/csi/csi_client_test.go b/pkg/volume/csi/csi_client_test.go index f589aeaa9a4c9..83ae82de993d0 100644 --- a/pkg/volume/csi/csi_client_test.go +++ b/pkg/volume/csi/csi_client_test.go @@ -60,6 +60,7 @@ func (c *fakeCsiDriverClient) NodePublishVolume( volumeAttribs map[string]string, nodePublishSecrets map[string]string, fsType string, + mountOptions []string, ) error { c.t.Log("calling fake.NodePublishVolume...") req := &csipb.NodePublishVolumeRequest{ @@ -75,7 +76,8 @@ func (c *fakeCsiDriverClient) NodePublishVolume( }, AccessType: &csipb.VolumeCapability_Mount{ Mount: &csipb.VolumeCapability_MountVolume{ - FsType: fsType, + FsType: fsType, + MountFlags: mountOptions, }, }, }, @@ -268,6 +270,7 @@ func TestClientNodePublishVolume(t *testing.T) { map[string]string{"attr0": "val0"}, map[string]string{}, tc.fsType, + []string{}, ) checkErr(t, tc.mustFail, err) diff --git a/pkg/volume/csi/csi_mounter.go b/pkg/volume/csi/csi_mounter.go index 28c0d9a93f019..dfc9cd4a86d7b 100644 --- a/pkg/volume/csi/csi_mounter.go +++ b/pkg/volume/csi/csi_mounter.go @@ -195,6 +195,7 @@ func (c *csiMountMgr) SetUpAt(dir string, fsGroup *int64) error { attribs, nodePublishSecrets, fsType, + c.spec.PersistentVolume.Spec.MountOptions, ) if err != nil { diff --git a/pkg/volume/csi/csi_mounter_test.go b/pkg/volume/csi/csi_mounter_test.go index b3b087281ac60..4aa1a44d79741 100644 --- a/pkg/volume/csi/csi_mounter_test.go +++ b/pkg/volume/csi/csi_mounter_test.go @@ -164,6 +164,7 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) { pv := makeTestPV("test-pv", 10, test.driver, testVol) pv.Spec.CSI.VolumeAttributes = test.attributes + pv.Spec.MountOptions = []string{"foo=bar", "baz=qux"} pvName := pv.GetName() mounter, err := plug.NewMounter( @@ -240,6 +241,9 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) { if vol.Path != csiMounter.GetPath() { t.Errorf("csi server expected path %s, got %s", csiMounter.GetPath(), vol.Path) } + if !reflect.DeepEqual(vol.MountFlags, pv.Spec.MountOptions) { + t.Errorf("csi server expected mount options %v, got %v", pv.Spec.MountOptions, vol.MountFlags) + } if podInfoEnabled { if !reflect.DeepEqual(vol.Attributes, test.expectedAttributes) { t.Errorf("csi server expected attributes %+v, got %+v", test.expectedAttributes, vol.Attributes) diff --git a/pkg/volume/csi/csi_plugin.go b/pkg/volume/csi/csi_plugin.go index a9083e5359445..4b8f97c3d6ddd 100644 --- a/pkg/volume/csi/csi_plugin.go +++ b/pkg/volume/csi/csi_plugin.go @@ -138,23 +138,34 @@ func (h *RegistrationHandler) RegisterPlugin(pluginName string, endpoint string) driverNodeID, maxVolumePerNode, accessibleTopology, err := csi.NodeGetInfo(ctx) if err != nil { - unregisterDriver(pluginName) - return fmt.Errorf("error during CSI NodeGetInfo() call: %v", err) + glog.Error(log("registrationHandler.RegisterPlugin failed at CSI.NodeGetInfo: %v", err)) + if unregErr := unregisterDriver(pluginName); unregErr != nil { + glog.Error(log("registrationHandler.RegisterPlugin failed to unregister plugin due to previous: %v", unregErr)) + return unregErr + } + return err } err = nim.AddNodeInfo(pluginName, driverNodeID, maxVolumePerNode, accessibleTopology) if err != nil { - unregisterDriver(pluginName) - return fmt.Errorf("error updating CSI node info in the cluster: %v", err) + glog.Error(log("registrationHandler.RegisterPlugin failed at AddNodeInfo: %v", err)) + if unregErr := unregisterDriver(pluginName); unregErr != nil { + glog.Error(log("registrationHandler.RegisterPlugin failed to unregister plugin due to previous error: %v", unregErr)) + return unregErr + } + return err } return nil } -// DeRegisterPlugin is called when a plugin removed it's socket, signaling +// DeRegisterPlugin is called when a plugin removed its socket, signaling // it is no longer available -// TODO: Handle DeRegistration func (h *RegistrationHandler) DeRegisterPlugin(pluginName string) { + glog.V(4).Info(log("registrationHandler.DeRegisterPlugin request for plugin %s", pluginName)) + if err := unregisterDriver(pluginName); err != nil { + glog.Error(log("registrationHandler.DeRegisterPlugin failed: %v", err)) + } } func (p *csiPlugin) Init(host volume.VolumeHost) error { @@ -333,7 +344,10 @@ func (p *csiPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.S func (p *csiPlugin) SupportsMountOption() bool { // TODO (vladimirvivien) use CSI VolumeCapability.MountVolume.mount_flags // to probe for the result for this method - return false + // (bswartz) Until the CSI spec supports probing, our only option is to + // make plugins register their support for mount options or lack thereof + // directly with kubernetes. + return true } func (p *csiPlugin) SupportsBulkVolumeVerification() bool { @@ -562,7 +576,7 @@ func (p *csiPlugin) getPublishVolumeInfo(client clientset.Interface, handle, dri return attachment.Status.AttachmentMetadata, nil } -func unregisterDriver(driverName string) { +func unregisterDriver(driverName string) error { func() { csiDrivers.Lock() defer csiDrivers.Unlock() @@ -571,5 +585,8 @@ func unregisterDriver(driverName string) { if err := nim.RemoveNodeInfo(driverName); err != nil { glog.Errorf("Error unregistering CSI driver: %v", err) + return err } + + return nil } diff --git a/pkg/volume/csi/fake/fake_client.go b/pkg/volume/csi/fake/fake_client.go index 40b08f264bbc4..775ff7ddfbf01 100644 --- a/pkg/volume/csi/fake/fake_client.go +++ b/pkg/volume/csi/fake/fake_client.go @@ -59,6 +59,7 @@ func (f *IdentityClient) Probe(ctx context.Context, in *csipb.ProbeRequest, opts type CSIVolume struct { Attributes map[string]string Path string + MountFlags []string } // NodeClient returns CSI node client @@ -126,6 +127,7 @@ func (f *NodeClient) NodePublishVolume(ctx context.Context, req *csipb.NodePubli f.nodePublishedVolumes[req.GetVolumeId()] = CSIVolume{ Path: req.GetTargetPath(), Attributes: req.GetVolumeAttributes(), + MountFlags: req.GetVolumeCapability().GetMount().MountFlags, } return &csipb.NodePublishVolumeResponse{}, nil } diff --git a/pkg/volume/csi/nodeinfomanager/BUILD b/pkg/volume/csi/nodeinfomanager/BUILD index 588871e29e4e7..3eadf06129b2f 100644 --- a/pkg/volume/csi/nodeinfomanager/BUILD +++ b/pkg/volume/csi/nodeinfomanager/BUILD @@ -7,6 +7,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/features:go_default_library", + "//pkg/util/node:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", @@ -53,12 +54,15 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1: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/apimachinery/pkg/util/strategicpatch:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", + "//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library", "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned/fake:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library", + "//vendor/github.com/stretchr/testify/assert:go_default_library", ], ) diff --git a/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go b/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go index bea909d6a5b1f..0a28d9c4ba946 100644 --- a/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go +++ b/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go @@ -34,6 +34,7 @@ import ( "k8s.io/client-go/util/retry" csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1" "k8s.io/kubernetes/pkg/features" + nodeutil "k8s.io/kubernetes/pkg/util/node" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" ) @@ -150,7 +151,8 @@ func (nim *nodeInfoManager) updateNode(updateFuncs ...nodeUpdateFunc) error { } nodeClient := kubeClient.CoreV1().Nodes() - node, err := nodeClient.Get(string(nim.nodeName), metav1.GetOptions{}) + originalNode, err := nodeClient.Get(string(nim.nodeName), metav1.GetOptions{}) + node := originalNode.DeepCopy() if err != nil { return err // do not wrap error } @@ -166,7 +168,9 @@ func (nim *nodeInfoManager) updateNode(updateFuncs ...nodeUpdateFunc) error { } if needUpdate { - _, updateErr := nodeClient.Update(node) + // PatchNodeStatus can update both node's status and labels or annotations + // Updating status by directly updating node does not work + _, _, updateErr := nodeutil.PatchNodeStatus(kubeClient.CoreV1(), types.NodeName(node.Name), originalNode, node) return updateErr // do not wrap error } diff --git a/pkg/volume/csi/nodeinfomanager/nodeinfomanager_test.go b/pkg/volume/csi/nodeinfomanager/nodeinfomanager_test.go index 6d5c299b3926b..8e42f77869a6b 100644 --- a/pkg/volume/csi/nodeinfomanager/nodeinfomanager_test.go +++ b/pkg/volume/csi/nodeinfomanager/nodeinfomanager_test.go @@ -18,18 +18,22 @@ package nodeinfomanager import ( "encoding/json" + "fmt" "testing" "github.com/container-storage-interface/spec/lib/go/csi/v0" + "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/strategicpatch" utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" "k8s.io/client-go/kubernetes/fake" + clienttesting "k8s.io/client-go/testing" utiltesting "k8s.io/client-go/util/testing" csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1" csifake "k8s.io/csi-api/pkg/client/clientset/versioned/fake" @@ -682,9 +686,18 @@ func test(t *testing.T, addNodeInfo bool, csiNodeInfoEnabled bool, testcases []t continue } - /* Node Validation */ - node, err := client.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{}) - if err != nil { + actions := client.Actions() + + var node *v1.Node + if hasPatchAction(actions) { + node, err = applyNodeStatusPatch(tc.existingNode, actions[1].(clienttesting.PatchActionImpl).GetPatch()) + assert.NoError(t, err) + } else { + node, err = client.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{}) + assert.NoError(t, err) + } + + if node == nil { t.Errorf("error getting node: %v", err) continue } @@ -807,3 +820,29 @@ func generateNodeInfo(nodeIDs map[string]string, topologyKeys map[string][]strin CSIDrivers: drivers, } } + +func applyNodeStatusPatch(originalNode *v1.Node, patch []byte) (*v1.Node, error) { + original, err := json.Marshal(originalNode) + if err != nil { + return nil, fmt.Errorf("failed to marshal original node %#v: %v", originalNode, err) + } + updated, err := strategicpatch.StrategicMergePatch(original, patch, v1.Node{}) + if err != nil { + return nil, fmt.Errorf("failed to apply strategic merge patch %q on node %#v: %v", + patch, originalNode, err) + } + updatedNode := &v1.Node{} + if err := json.Unmarshal(updated, updatedNode); err != nil { + return nil, fmt.Errorf("failed to unmarshal updated node %q: %v", updated, err) + } + return updatedNode, nil +} + +func hasPatchAction(actions []clienttesting.Action) bool { + for _, action := range actions { + if action.GetVerb() == "patch" { + return true + } + } + return false +} diff --git a/pkg/volume/downwardapi/downwardapi.go b/pkg/volume/downwardapi/downwardapi.go index 11fe62fc77735..801ed712e2f95 100644 --- a/pkg/volume/downwardapi/downwardapi.go +++ b/pkg/volume/downwardapi/downwardapi.go @@ -18,7 +18,6 @@ package downwardapi import ( "fmt" - "path" "path/filepath" "k8s.io/api/core/v1" @@ -299,10 +298,6 @@ func (c *downwardAPIVolumeUnmounter) TearDownAt(dir string) error { return volumeutil.UnmountViaEmptyDir(dir, c.plugin.host, c.volName, wrappedVolumeSpec(), c.podUID) } -func (b *downwardAPIVolumeMounter) getMetaDir() string { - return path.Join(b.plugin.host.GetPodPluginDir(b.podUID, utilstrings.EscapeQualifiedNameForDisk(downwardAPIPluginName)), b.volName) -} - func getVolumeSource(spec *volume.Spec) (*v1.DownwardAPIVolumeSource, bool) { var readOnly bool var volumeSource *v1.DownwardAPIVolumeSource diff --git a/pkg/volume/flexvolume/BUILD b/pkg/volume/flexvolume/BUILD index fff15f102eeab..38ff345cb350c 100644 --- a/pkg/volume/flexvolume/BUILD +++ b/pkg/volume/flexvolume/BUILD @@ -14,6 +14,8 @@ go_library( "detacher.go", "detacher-defaults.go", "driver-call.go", + "expander.go", + "expander-defaults.go", "fake_watcher.go", "mounter.go", "mounter-defaults.go", @@ -33,6 +35,7 @@ go_library( "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/github.com/fsnotify/fsnotify:go_default_library", @@ -64,6 +67,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library", + "//test/utils/harness:go_default_library", "//vendor/github.com/fsnotify/fsnotify:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", diff --git a/pkg/volume/flexvolume/attacher_test.go b/pkg/volume/flexvolume/attacher_test.go index 8472886dadd2e..f8e9f12cdb42e 100644 --- a/pkg/volume/flexvolume/attacher_test.go +++ b/pkg/volume/flexvolume/attacher_test.go @@ -22,12 +22,16 @@ import ( "k8s.io/api/core/v1" "k8s.io/kubernetes/pkg/volume" + "k8s.io/kubernetes/test/utils/harness" ) -func TestAttach(t *testing.T) { +func TestAttach(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + spec := fakeVolumeSpec() - plugin, _ := testPlugin() + plugin, _ := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, notSupportedOutput(), attachCmd, specJSON(plugin, spec, nil), "localhost"), @@ -37,10 +41,13 @@ func TestAttach(t *testing.T) { a.Attach(spec, "localhost") } -func TestWaitForAttach(t *testing.T) { +func TestWaitForAttach(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + spec := fakeVolumeSpec() var pod *v1.Pod - plugin, _ := testPlugin() + plugin, _ := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, notSupportedOutput(), waitForAttachCmd, "/dev/sdx", specJSON(plugin, spec, nil)), @@ -50,10 +57,13 @@ func TestWaitForAttach(t *testing.T) { a.WaitForAttach(spec, "/dev/sdx", pod, 1*time.Second) } -func TestMountDevice(t *testing.T) { +func TestMountDevice(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + spec := fakeVolumeSpec() - plugin, rootDir := testPlugin() + plugin, rootDir := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, notSupportedOutput(), mountDeviceCmd, rootDir+"/mount-dir", "/dev/sdx", specJSON(plugin, spec, nil)), @@ -63,10 +73,13 @@ func TestMountDevice(t *testing.T) { a.MountDevice(spec, "/dev/sdx", rootDir+"/mount-dir") } -func TestIsVolumeAttached(t *testing.T) { +func TestIsVolumeAttached(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + spec := fakeVolumeSpec() - plugin, _ := testPlugin() + plugin, _ := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, notSupportedOutput(), isAttached, specJSON(plugin, spec, nil), "localhost"), ) diff --git a/pkg/volume/flexvolume/common_test.go b/pkg/volume/flexvolume/common_test.go index fb99d1add4e36..45cbf267542e0 100644 --- a/pkg/volume/flexvolume/common_test.go +++ b/pkg/volume/flexvolume/common_test.go @@ -18,22 +18,18 @@ package flexvolume import ( "encoding/json" - "testing" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - utiltesting "k8s.io/client-go/util/testing" "k8s.io/kubernetes/pkg/volume" volumetesting "k8s.io/kubernetes/pkg/volume/testing" + "k8s.io/kubernetes/test/utils/harness" "k8s.io/utils/exec" fakeexec "k8s.io/utils/exec/testing" ) -func testPlugin() (*flexVolumeAttachablePlugin, string) { - rootDir, err := utiltesting.MkTmpdir("flexvolume_test") - if err != nil { - panic("error creating temp dir: " + err.Error()) - } +func testPlugin(h *harness.Harness) (*flexVolumeAttachablePlugin, string) { + rootDir := h.TempDir("", "flexvolume_test") return &flexVolumeAttachablePlugin{ flexVolumePlugin: &flexVolumePlugin{ driverName: "test", @@ -44,7 +40,7 @@ func testPlugin() (*flexVolumeAttachablePlugin, string) { }, rootDir } -func assertDriverCall(t *testing.T, output fakeexec.FakeCombinedOutputAction, expectedCommand string, expectedArgs ...string) fakeexec.FakeCommandAction { +func assertDriverCall(t *harness.Harness, output fakeexec.FakeCombinedOutputAction, expectedCommand string, expectedArgs ...string) fakeexec.FakeCommandAction { return func(cmd string, args ...string) exec.Cmd { if cmd != "/plugin/test" { t.Errorf("Wrong executable called: got %v, expected %v", cmd, "/plugin/test") @@ -80,11 +76,11 @@ func fakeResultOutput(result interface{}) fakeexec.FakeCombinedOutputAction { } func successOutput() fakeexec.FakeCombinedOutputAction { - return fakeResultOutput(&DriverStatus{StatusSuccess, "", "", "", true, nil}) + return fakeResultOutput(&DriverStatus{StatusSuccess, "", "", "", true, nil, 0}) } func notSupportedOutput() fakeexec.FakeCombinedOutputAction { - return fakeResultOutput(&DriverStatus{StatusNotSupported, "", "", "", false, nil}) + return fakeResultOutput(&DriverStatus{StatusNotSupported, "", "", "", false, nil, 0}) } func sameArgs(args, expectedArgs []string) bool { diff --git a/pkg/volume/flexvolume/detacher_test.go b/pkg/volume/flexvolume/detacher_test.go index a1bc27b37ab0b..6974feee2f05e 100644 --- a/pkg/volume/flexvolume/detacher_test.go +++ b/pkg/volume/flexvolume/detacher_test.go @@ -18,10 +18,15 @@ package flexvolume import ( "testing" + + "k8s.io/kubernetes/test/utils/harness" ) -func TestDetach(t *testing.T) { - plugin, _ := testPlugin() +func TestDetach(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + + plugin, _ := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, notSupportedOutput(), detachCmd, "sdx", "localhost"), @@ -31,8 +36,11 @@ func TestDetach(t *testing.T) { d.Detach("sdx", "localhost") } -func TestUnmountDevice(t *testing.T) { - plugin, rootDir := testPlugin() +func TestUnmountDevice(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + + plugin, rootDir := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, notSupportedOutput(), unmountDeviceCmd, rootDir+"/mount-dir"), diff --git a/pkg/volume/flexvolume/driver-call.go b/pkg/volume/flexvolume/driver-call.go index d2706ffa0e2b7..0a42a914247c1 100644 --- a/pkg/volume/flexvolume/driver-call.go +++ b/pkg/volume/flexvolume/driver-call.go @@ -44,6 +44,9 @@ const ( mountCmd = "mount" unmountCmd = "unmount" + expandVolumeCmd = "expandvolume" + expandFSCmd = "expandfs" + // Option keys optionFSType = "kubernetes.io/fsType" optionReadWrite = "kubernetes.io/readwrite" @@ -221,22 +224,26 @@ type DriverStatus struct { // By default we assume all the capabilities are supported. // If the plugin does not support a capability, it can return false for that capability. Capabilities *DriverCapabilities `json:",omitempty"` + // Returns the actual size of the volume after resizing is done, the size is in bytes. + ActualVolumeSize int64 `json:"volumeNewSize,omitempty"` } // DriverCapabilities represents what driver can do type DriverCapabilities struct { - Attach bool `json:"attach"` - SELinuxRelabel bool `json:"selinuxRelabel"` - SupportsMetrics bool `json:"supportsMetrics"` - FSGroup bool `json:"fsGroup"` + Attach bool `json:"attach"` + SELinuxRelabel bool `json:"selinuxRelabel"` + SupportsMetrics bool `json:"supportsMetrics"` + FSGroup bool `json:"fsGroup"` + RequiresFSResize bool `json:"requiresFSResize"` } func defaultCapabilities() *DriverCapabilities { return &DriverCapabilities{ - Attach: true, - SELinuxRelabel: true, - SupportsMetrics: false, - FSGroup: true, + Attach: true, + SELinuxRelabel: true, + SupportsMetrics: false, + FSGroup: true, + RequiresFSResize: true, } } diff --git a/pkg/volume/flexvolume/expander-defaults.go b/pkg/volume/flexvolume/expander-defaults.go new file mode 100644 index 0000000000000..e578cb32c63f1 --- /dev/null +++ b/pkg/volume/flexvolume/expander-defaults.go @@ -0,0 +1,45 @@ +/* +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 flexvolume + +import ( + "github.com/golang/glog" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/kubernetes/pkg/volume" + "k8s.io/kubernetes/pkg/volume/util" +) + +type expanderDefaults struct { + plugin *flexVolumePlugin +} + +func newExpanderDefaults(plugin *flexVolumePlugin) *expanderDefaults { + return &expanderDefaults{plugin} +} + +func (e *expanderDefaults) ExpandVolumeDevice(spec *volume.Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error) { + glog.Warning(logPrefix(e.plugin), "using default expand for volume ", spec.Name(), ", to size ", newSize, " from ", oldSize) + return newSize, nil +} + +// the defaults for ExpandFS return a generic resize indicator that will trigger the operation executor to go ahead with +// generic filesystem resize +func (e *expanderDefaults) ExpandFS(spec *volume.Spec, devicePath, deviceMountPath string, _, _ resource.Quantity) error { + glog.Warning(logPrefix(e.plugin), "using default filesystem resize for volume ", spec.Name(), ", at ", devicePath) + _, err := util.GenericResizeFS(e.plugin.host, e.plugin.GetPluginName(), devicePath, deviceMountPath) + return err +} diff --git a/pkg/volume/flexvolume/expander.go b/pkg/volume/flexvolume/expander.go new file mode 100644 index 0000000000000..345bad26d7b79 --- /dev/null +++ b/pkg/volume/flexvolume/expander.go @@ -0,0 +1,67 @@ +/* +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 flexvolume + +import ( + "fmt" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/kubernetes/pkg/volume" + "strconv" +) + +func (plugin *flexVolumePlugin) ExpandVolumeDevice(spec *volume.Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error) { + call := plugin.NewDriverCall(expandVolumeCmd) + call.AppendSpec(spec, plugin.host, nil) + + devicePath, err := plugin.getDeviceMountPath(spec) + if err != nil { + return newSize, err + } + call.Append(devicePath) + call.Append(strconv.FormatInt(newSize.Value(), 10)) + call.Append(strconv.FormatInt(oldSize.Value(), 10)) + + _, err = call.Run() + if isCmdNotSupportedErr(err) { + return newExpanderDefaults(plugin).ExpandVolumeDevice(spec, newSize, oldSize) + } + return newSize, err +} + +func (plugin *flexVolumePlugin) ExpandFS(spec *volume.Spec, devicePath, deviceMountPath string, newSize, oldSize resource.Quantity) error { + // This method is called after we spec.PersistentVolume.Spec.Capacity + // has been updated to the new size. The underlying driver thus sees + // the _new_ (requested) size and can find out the _current_ size from + // its underlying storage implementation + + if spec.PersistentVolume == nil { + return fmt.Errorf("PersistentVolume not found for spec: %s", spec.Name()) + } + + call := plugin.NewDriverCall(expandFSCmd) + call.AppendSpec(spec, plugin.host, nil) + call.Append(devicePath) + call.Append(deviceMountPath) + call.Append(strconv.FormatInt(newSize.Value(), 10)) + call.Append(strconv.FormatInt(oldSize.Value(), 10)) + + _, err := call.Run() + if isCmdNotSupportedErr(err) { + return newExpanderDefaults(plugin).ExpandFS(spec, devicePath, deviceMountPath, newSize, oldSize) + } + return err +} diff --git a/pkg/volume/flexvolume/mounter_test.go b/pkg/volume/flexvolume/mounter_test.go index 70dac00728dda..bf10fd74817fa 100644 --- a/pkg/volume/flexvolume/mounter_test.go +++ b/pkg/volume/flexvolume/mounter_test.go @@ -23,9 +23,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/test/utils/harness" ) -func TestSetUpAt(t *testing.T) { +func TestSetUpAt(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + spec := fakeVolumeSpec() pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -39,7 +43,7 @@ func TestSetUpAt(t *testing.T) { } mounter := &mount.FakeMounter{} - plugin, rootDir := testPlugin() + plugin, rootDir := testPlugin(t) plugin.unsupportedCommands = []string{"unsupportedCmd"} plugin.runner = fakeRunner( // first call without fsGroup diff --git a/pkg/volume/flexvolume/plugin.go b/pkg/volume/flexvolume/plugin.go index 9e59b5ccfe9be..8859bcb199911 100644 --- a/pkg/volume/flexvolume/plugin.go +++ b/pkg/volume/flexvolume/plugin.go @@ -57,6 +57,8 @@ type flexVolumeAttachablePlugin struct { var _ volume.AttachableVolumePlugin = &flexVolumeAttachablePlugin{} var _ volume.PersistentVolumePlugin = &flexVolumePlugin{} +var _ volume.FSResizableVolumePlugin = &flexVolumePlugin{} +var _ volume.ExpandableVolumePlugin = &flexVolumePlugin{} var _ volume.DeviceMountableVolumePlugin = &flexVolumeAttachablePlugin{} @@ -305,3 +307,7 @@ func (plugin *flexVolumePlugin) getDeviceMountPath(spec *volume.Spec) (string, e mountsDir := path.Join(plugin.host.GetPluginDir(flexVolumePluginName), plugin.driverName, "mounts") return path.Join(mountsDir, volumeName), nil } + +func (plugin *flexVolumePlugin) RequiresFSResize() bool { + return plugin.capabilities.RequiresFSResize +} diff --git a/pkg/volume/flexvolume/plugin_test.go b/pkg/volume/flexvolume/plugin_test.go index ae267fbd9f07f..f6afe704aa981 100644 --- a/pkg/volume/flexvolume/plugin_test.go +++ b/pkg/volume/flexvolume/plugin_test.go @@ -19,11 +19,15 @@ package flexvolume import ( "testing" + "k8s.io/kubernetes/test/utils/harness" exec "k8s.io/utils/exec/testing" ) -func TestInit(t *testing.T) { - plugin, _ := testPlugin() +func TestInit(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + + plugin, _ := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, successOutput(), "init"), ) @@ -37,9 +41,12 @@ func fakeVolumeNameOutput(name string) exec.FakeCombinedOutputAction { }) } -func TestGetVolumeName(t *testing.T) { +func TestGetVolumeName(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + spec := fakeVolumeSpec() - plugin, _ := testPlugin() + plugin, _ := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, fakeVolumeNameOutput(spec.Name()), getVolumeNameCmd, specJSON(plugin, spec, nil)), diff --git a/pkg/volume/flexvolume/unmounter_test.go b/pkg/volume/flexvolume/unmounter_test.go index fe7964a94aa5b..0f0991944cd7e 100644 --- a/pkg/volume/flexvolume/unmounter_test.go +++ b/pkg/volume/flexvolume/unmounter_test.go @@ -21,12 +21,16 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/test/utils/harness" ) -func TestTearDownAt(t *testing.T) { +func TestTearDownAt(tt *testing.T) { + t := harness.For(tt) + defer t.Close() + mounter := &mount.FakeMounter{} - plugin, rootDir := testPlugin() + plugin, rootDir := testPlugin(t) plugin.runner = fakeRunner( assertDriverCall(t, notSupportedOutput(), unmountCmd, rootDir+"/mount-dir"), diff --git a/pkg/volume/gcepd/gce_pd.go b/pkg/volume/gcepd/gce_pd.go index d69638f558a54..4cbe76d4d06e4 100644 --- a/pkg/volume/gcepd/gce_pd.go +++ b/pkg/volume/gcepd/gce_pd.go @@ -284,6 +284,13 @@ func (plugin *gcePersistentDiskPlugin) ExpandVolumeDevice( return updatedQuantity, nil } +func (plugin *gcePersistentDiskPlugin) ExpandFS(spec *volume.Spec, devicePath, deviceMountPath string, _, _ resource.Quantity) error { + _, err := util.GenericResizeFS(plugin.host, plugin.GetPluginName(), devicePath, deviceMountPath) + return err +} + +var _ volume.FSResizableVolumePlugin = &gcePersistentDiskPlugin{} + func (plugin *gcePersistentDiskPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) { mounter := plugin.host.GetMounter(plugin.GetPluginName()) pluginDir := plugin.host.GetPluginDir(plugin.GetPluginName()) diff --git a/pkg/volume/gcepd/gce_util.go b/pkg/volume/gcepd/gce_util.go index a01adf9807fc6..947cc13fe1481 100644 --- a/pkg/volume/gcepd/gce_util.go +++ b/pkg/volume/gcepd/gce_util.go @@ -284,10 +284,10 @@ func getDiskByIDPaths(pdName string, partition string) []string { } // Return cloud provider -func getCloudProvider(cloudProvider cloudprovider.Interface) (*gcecloud.GCECloud, error) { +func getCloudProvider(cloudProvider cloudprovider.Interface) (*gcecloud.Cloud, error) { var err error for numRetries := 0; numRetries < maxRetries; numRetries++ { - gceCloudProvider, ok := cloudProvider.(*gcecloud.GCECloud) + gceCloudProvider, ok := cloudProvider.(*gcecloud.Cloud) if !ok || gceCloudProvider == nil { // Retry on error. See issue #11321 glog.Errorf("Failed to get GCE Cloud Provider. plugin.host.GetCloudProvider returned %v instead", cloudProvider) diff --git a/pkg/volume/glusterfs/glusterfs.go b/pkg/volume/glusterfs/glusterfs.go index 9b6c75644285a..f5d2782111abd 100644 --- a/pkg/volume/glusterfs/glusterfs.go +++ b/pkg/volume/glusterfs/glusterfs.go @@ -67,7 +67,7 @@ var _ volume.Deleter = &glusterfsVolumeDeleter{} const ( glusterfsPluginName = "kubernetes.io/glusterfs" volPrefix = "vol_" - dynamicEpSvcPrefix = "glusterfs-dynamic-" + dynamicEpSvcPrefix = "glusterfs-dynamic" replicaCount = 3 durabilityType = "replicate" secretKeyName = "key" // key name used in secret @@ -75,6 +75,14 @@ const ( defaultGidMin = 2000 defaultGidMax = math.MaxInt32 + // maxCustomEpNamePrefix is the maximum number of chars. + // which can be used as ep/svc name prefix. This number is carved + // out from below formula. + // max length of name of an ep - length of pvc uuid + // where max length of name of an ep is 63 and length of uuid is 37 + + maxCustomEpNamePrefixLen = 26 + // absoluteGidMin/Max are currently the same as the // default values, but they play a different role and // could take a different value. Only thing we need is: @@ -443,6 +451,7 @@ type provisionerConfig struct { volumeOptions []string volumeNamePrefix string thinPoolSnapFactor float32 + customEpNamePrefix string } type glusterfsVolumeProvisioner struct { @@ -772,6 +781,8 @@ func (p *glusterfsVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTop func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolumeSource, size int, volID string, err error) { var clusterIDs []string customVolumeName := "" + epServiceName := "" + capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] // GlusterFS/heketi creates volumes in units of GiB. @@ -822,11 +833,11 @@ func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolum return nil, 0, "", fmt.Errorf("failed to get cluster nodes for volume %s: %v", volume, err) } - // The 'endpointname' is created in form of 'glusterfs-dynamic-'. - // createEndpointService() checks for this 'endpoint' existence in PVC's namespace and - // If not found, it create an endpoint and service using the IPs we dynamically picked at time - // of volume creation. - epServiceName := dynamicEpSvcPrefix + p.options.PVC.Name + if len(p.provisionerConfig.customEpNamePrefix) == 0 { + epServiceName = string(p.options.PVC.UID) + } else { + epServiceName = p.provisionerConfig.customEpNamePrefix + "-" + string(p.options.PVC.UID) + } epNamespace := p.options.PVC.Namespace endpoint, service, err := p.createEndpointService(epNamespace, epServiceName, dynamicHostIps, p.options.PVC.Name) if err != nil { @@ -845,6 +856,10 @@ func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolum }, sz, volID, nil } +// createEndpointService() makes sure an endpoint and service +// exist for the given namespace, PVC name, endpoint name, and +// set of IPs. I.e. the endpoint or service is only created +// if it does not exist yet. func (p *glusterfsVolumeProvisioner) createEndpointService(namespace string, epServiceName string, hostips []string, pvcname string) (endpoint *v1.Endpoints, service *v1.Service, err error) { addrlist := make([]v1.EndpointAddress, len(hostips)) @@ -970,6 +985,7 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa var err error cfg.gidMin = defaultGidMin cfg.gidMax = defaultGidMax + cfg.customEpNamePrefix = dynamicEpSvcPrefix authEnabled := true parseVolumeType := "" @@ -1037,7 +1053,16 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa if len(v) != 0 { parseThinPoolSnapFactor = v } - + case "customepnameprefix": + // If the string has > 'maxCustomEpNamePrefixLen' chars, the final endpoint name will + // exceed the limitation of 63 chars, so fail if prefix is > 'maxCustomEpNamePrefixLen' + // characters. This is only applicable for 'customepnameprefix' string and default ep name + // string will always pass. + if len(v) <= maxCustomEpNamePrefixLen { + cfg.customEpNamePrefix = v + } else { + return nil, fmt.Errorf("'customepnameprefix' value should be < %d characters", maxCustomEpNamePrefixLen) + } default: return nil, fmt.Errorf("invalid option %q for volume plugin %s", k, glusterfsPluginName) } diff --git a/pkg/volume/glusterfs/glusterfs_test.go b/pkg/volume/glusterfs/glusterfs_test.go index 2e8d0af83dc22..e2f13d3e71eaf 100644 --- a/pkg/volume/glusterfs/glusterfs_test.go +++ b/pkg/volume/glusterfs/glusterfs_test.go @@ -261,6 +261,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 2147483647, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "glusterfs-dynamic", }, }, { @@ -283,6 +284,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 2147483647, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "glusterfs-dynamic", }, }, { @@ -299,6 +301,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 2147483647, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "glusterfs-dynamic", }, }, { @@ -437,6 +440,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 2147483647, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "glusterfs-dynamic", }, }, { @@ -454,6 +458,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 5000, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "glusterfs-dynamic", }, }, { @@ -472,6 +477,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 5000, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "glusterfs-dynamic", }, }, @@ -492,6 +498,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 5000, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "glusterfs-dynamic", }, }, @@ -512,6 +519,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 5000, volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}}, thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "glusterfs-dynamic", }, }, { @@ -532,6 +540,7 @@ func TestParseClassParameters(t *testing.T) { gidMax: 5000, volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}}, thinPoolSnapFactor: float32(50), + customEpNamePrefix: "glusterfs-dynamic", }, }, @@ -555,6 +564,7 @@ func TestParseClassParameters(t *testing.T) { volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}}, thinPoolSnapFactor: float32(50), volumeNamePrefix: "dept-dev", + customEpNamePrefix: "glusterfs-dynamic", }, }, { @@ -645,6 +655,84 @@ func TestParseClassParameters(t *testing.T) { true, // expect error nil, }, + + { + "enable custom ep/svc name: customEpNamePrefix: myprefix", + map[string]string{ + "resturl": "https://localhost:8080", + "restauthenabled": "false", + "gidMin": "4000", + "gidMax": "5000", + "volumetype": "replicate:4", + "customEpNamePrefix": "myprefix", + }, + &secret, + false, // expect error + &provisionerConfig{ + url: "https://localhost:8080", + gidMin: 4000, + gidMax: 5000, + volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, + thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "myprefix", + }, + }, + { + "empty custom ep/svc name: customEpNamePrefix:''", + map[string]string{ + "resturl": "https://localhost:8080", + "restauthenabled": "false", + "gidMin": "4000", + "gidMax": "5000", + "volumetype": "replicate:4", + "customEpNamePrefix": "", + }, + &secret, + false, // expect error + &provisionerConfig{ + url: "https://localhost:8080", + gidMin: 4000, + gidMax: 5000, + volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, + thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "", + }, + }, + { + "custom ep/svc name with 26 chars: customEpNamePrefix:'charstringhastwentysixchar'", + map[string]string{ + "resturl": "https://localhost:8080", + "restauthenabled": "false", + "gidMin": "4000", + "gidMax": "5000", + "volumetype": "replicate:4", + "customEpNamePrefix": "charstringhastwentysixchar", + }, + &secret, + false, // expect error + &provisionerConfig{ + url: "https://localhost:8080", + gidMin: 4000, + gidMax: 5000, + volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, + thinPoolSnapFactor: float32(1.0), + customEpNamePrefix: "charstringhastwentysixchar", + }, + }, + { + "invalid customepnameprefix ( ie >26 chars) parameter", + map[string]string{ + "resturl": "https://localhost:8080", + "restauthenabled": "false", + "gidMin": "4000", + "gidMax": "5000", + "volumetype": "replicate:4", + "customEpNamePrefix": "myprefixhasmorethan26characters", + }, + &secret, + true, // expect error + nil, + }, } for _, test := range tests { diff --git a/pkg/volume/local/local.go b/pkg/volume/local/local.go index 3b0b59f563ec6..574534ed55973 100644 --- a/pkg/volume/local/local.go +++ b/pkg/volume/local/local.go @@ -322,10 +322,9 @@ func getVolumeSourceFSType(spec *volume.Spec) (string, error) { spec.PersistentVolume.Spec.Local != nil { if spec.PersistentVolume.Spec.Local.FSType != nil { return *spec.PersistentVolume.Spec.Local.FSType, nil - } else { - // if the FSType is not set in local PV spec, setting it to default ("ext4") - return defaultFSType, nil } + // if the FSType is not set in local PV spec, setting it to default ("ext4") + return defaultFSType, nil } return "", fmt.Errorf("spec does not reference a Local volume type") @@ -573,7 +572,7 @@ type localVolumeUnmapper struct { var _ volume.BlockVolumeUnmapper = &localVolumeUnmapper{} // TearDownDevice will undo SetUpDevice procedure. In local PV, all of this already handled by operation_generator. -func (u *localVolumeUnmapper) TearDownDevice(mapPath, devicePath string) error { +func (u *localVolumeUnmapper) TearDownDevice(mapPath, _ string) error { glog.V(4).Infof("local: TearDownDevice completed for: %s", mapPath) return nil } diff --git a/pkg/volume/local/local_test.go b/pkg/volume/local/local_test.go index c28c92dde0269..b59152ca95177 100644 --- a/pkg/volume/local/local_test.go +++ b/pkg/volume/local/local_test.go @@ -41,7 +41,6 @@ const ( testMountPath = "pods/poduid/volumes/kubernetes.io~local-volume/pvA" testGlobalPath = "plugins/kubernetes.io~local-volume/volumeDevices/pvA" testPodPath = "pods/poduid/volumeDevices/kubernetes.io~local-volume" - testNodeName = "fakeNodeName" testBlockFormattingToFSGlobalPath = "plugins/kubernetes.io/local-volume/mounts/pvA" ) diff --git a/pkg/volume/noop_expandable_plugin.go b/pkg/volume/noop_expandable_plugin.go new file mode 100644 index 0000000000000..3d3d5e1dfd75d --- /dev/null +++ b/pkg/volume/noop_expandable_plugin.go @@ -0,0 +1,77 @@ +/* +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 volume + +import ( + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/types" +) + +type noopExpandableVolumePluginInstance struct { + spec *Spec +} + +var _ ExpandableVolumePlugin = &noopExpandableVolumePluginInstance{} + +func (n *noopExpandableVolumePluginInstance) ExpandVolumeDevice(spec *Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error) { + return newSize, nil +} + +func (n *noopExpandableVolumePluginInstance) Init(host VolumeHost) error { + return nil +} + +func (n *noopExpandableVolumePluginInstance) GetPluginName() string { + return n.spec.KubeletExpandablePluginName() +} + +func (n *noopExpandableVolumePluginInstance) GetVolumeName(spec *Spec) (string, error) { + return n.spec.Name(), nil +} + +func (n *noopExpandableVolumePluginInstance) CanSupport(spec *Spec) bool { + return true +} + +func (n *noopExpandableVolumePluginInstance) RequiresRemount() bool { + return false +} + +func (n *noopExpandableVolumePluginInstance) NewMounter(spec *Spec, podRef *v1.Pod, opts VolumeOptions) (Mounter, error) { + return nil, nil +} + +func (n *noopExpandableVolumePluginInstance) NewUnmounter(name string, podUID types.UID) (Unmounter, error) { + return nil, nil +} + +func (n *noopExpandableVolumePluginInstance) ConstructVolumeSpec(volumeName, mountPath string) (*Spec, error) { + return n.spec, nil +} + +func (n *noopExpandableVolumePluginInstance) SupportsMountOption() bool { + return true +} + +func (n *noopExpandableVolumePluginInstance) SupportsBulkVolumeVerification() bool { + return false +} + +func (n *noopExpandableVolumePluginInstance) RequiresFSResize() bool { + return true +} diff --git a/pkg/volume/plugins.go b/pkg/volume/plugins.go index 453cbca7319be..abfb7bf8fd5ea 100644 --- a/pkg/volume/plugins.go +++ b/pkg/volume/plugins.go @@ -225,6 +225,13 @@ type ExpandableVolumePlugin interface { RequiresFSResize() bool } +// FSResizableVolumePlugin is an extension of ExpandableVolumePlugin and is used for volumes (flex) +// that require extra steps on nodes for expansion to complete +type FSResizableVolumePlugin interface { + ExpandableVolumePlugin + ExpandFS(spec *Spec, devicePath, deviceMountPath string, newSize, oldSize resource.Quantity) error +} + // VolumePluginWithAttachLimits is an extended interface of VolumePlugin that restricts number of // volumes that can be attached to a node. type VolumePluginWithAttachLimits interface { @@ -347,6 +354,8 @@ type VolumeHost interface { GetServiceAccountTokenFunc() func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) + DeleteServiceAccountTokenFunc() func(podUID types.UID) + // Returns an interface that should be used to execute any utilities in volume plugins GetExec(pluginName string) mount.Exec @@ -388,6 +397,36 @@ func (spec *Spec) Name() string { } } +// IsKubeletExpandable returns true for volume types that can be expanded only by the node +// and not the controller. Currently Flex volume is the only one in this category since +// it is typically not installed on the controller +func (spec *Spec) IsKubeletExpandable() bool { + switch { + case spec.Volume != nil: + return spec.Volume.FlexVolume != nil + case spec.PersistentVolume != nil: + return spec.PersistentVolume.Spec.FlexVolume != nil + default: + return false + + } +} + +// KubeletExpandablePluginName creates and returns a name for the plugin +// this is used in context on the controller where the plugin lookup fails +// as volume expansion on controller isn't supported, but a plugin name is +// required +func (spec *Spec) KubeletExpandablePluginName() string { + switch { + case spec.Volume != nil && spec.Volume.FlexVolume != nil: + return spec.Volume.FlexVolume.Driver + case spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FlexVolume != nil: + return spec.PersistentVolume.Spec.FlexVolume.Driver + default: + return "" + } +} + // VolumeConfig is how volume plugins receive configuration. An instance // specific to the plugin will be passed to the plugin's // ProbeVolumePlugins(config) func. Reasonable defaults will be provided by @@ -797,6 +836,13 @@ func (pm *VolumePluginMgr) FindDeviceMountablePluginByName(name string) (DeviceM func (pm *VolumePluginMgr) FindExpandablePluginBySpec(spec *Spec) (ExpandableVolumePlugin, error) { volumePlugin, err := pm.FindPluginBySpec(spec) if err != nil { + if spec.IsKubeletExpandable() { + // for kubelet expandable volumes, return a noop plugin that + // returns success for expand on the controller + glog.Warningf("FindExpandablePluginBySpec(%s) -> returning noopExpandableVolumePluginInstance", spec.Name()) + return &noopExpandableVolumePluginInstance{spec}, nil + } + glog.Warningf("FindExpandablePluginBySpec(%s) -> err:%v", spec.Name(), err) return nil, err } @@ -845,6 +891,32 @@ func (pm *VolumePluginMgr) FindMapperPluginByName(name string) (BlockVolumePlugi return nil, nil } +// FindFSResizablePluginBySpec fetches a persistent volume plugin by spec +func (pm *VolumePluginMgr) FindFSResizablePluginBySpec(spec *Spec) (FSResizableVolumePlugin, error) { + volumePlugin, err := pm.FindPluginBySpec(spec) + if err != nil { + return nil, err + } + if fsResizablePlugin, ok := volumePlugin.(FSResizableVolumePlugin); ok { + return fsResizablePlugin, nil + } + return nil, nil +} + +// FindFSResizablePluginByName fetches a persistent volume plugin by name +func (pm *VolumePluginMgr) FindFSResizablePluginByName(name string) (FSResizableVolumePlugin, error) { + volumePlugin, err := pm.FindPluginByName(name) + if err != nil { + return nil, err + } + + if fsResizablePlugin, ok := volumePlugin.(FSResizableVolumePlugin); ok { + return fsResizablePlugin, nil + } + + return nil, nil +} + // NewPersistentVolumeRecyclerPodTemplate creates a template for a recycler // pod. By default, a recycler pod simply runs "rm -rf" on a volume and tests // for emptiness. Most attributes of the template will be correct for most diff --git a/pkg/volume/projected/projected.go b/pkg/volume/projected/projected.go index 7c2f583e7fc92..376199e120e6b 100644 --- a/pkg/volume/projected/projected.go +++ b/pkg/volume/projected/projected.go @@ -47,10 +47,11 @@ const ( ) type projectedPlugin struct { - host volume.VolumeHost - getSecret func(namespace, name string) (*v1.Secret, error) - getConfigMap func(namespace, name string) (*v1.ConfigMap, error) - getServiceAccountToken func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) + host volume.VolumeHost + getSecret func(namespace, name string) (*v1.Secret, error) + getConfigMap func(namespace, name string) (*v1.ConfigMap, error) + getServiceAccountToken func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) + deleteServiceAccountToken func(podUID types.UID) } var _ volume.VolumePlugin = &projectedPlugin{} @@ -74,6 +75,7 @@ func (plugin *projectedPlugin) Init(host volume.VolumeHost) error { plugin.getSecret = host.GetSecretFunc() plugin.getConfigMap = host.GetConfigMapFunc() plugin.getServiceAccountToken = host.GetServiceAccountTokenFunc() + plugin.deleteServiceAccountToken = host.DeleteServiceAccountTokenFunc() return nil } @@ -368,7 +370,12 @@ func (c *projectedVolumeUnmounter) TearDownAt(dir string) error { if err != nil { return err } - return wrapped.TearDownAt(dir) + if err = wrapped.TearDownAt(dir); err != nil { + return err + } + + c.plugin.deleteServiceAccountToken(c.podUID) + return nil } func getVolumeSource(spec *volume.Spec) (*v1.ProjectedVolumeSource, bool, error) { diff --git a/pkg/volume/rbd/rbd.go b/pkg/volume/rbd/rbd.go index b7b52b4d9b153..4d4f61fbb263d 100644 --- a/pkg/volume/rbd/rbd.go +++ b/pkg/volume/rbd/rbd.go @@ -197,6 +197,13 @@ func (plugin *rbdPlugin) ExpandVolumeDevice(spec *volume.Spec, newSize resource. } } +func (plugin *rbdPlugin) ExpandFS(spec *volume.Spec, devicePath, deviceMountPath string, _, _ resource.Quantity) error { + _, err := volutil.GenericResizeFS(plugin.host, plugin.GetPluginName(), devicePath, deviceMountPath) + return err +} + +var _ volume.FSResizableVolumePlugin = &rbdPlugin{} + func (expander *rbdVolumeExpander) ResizeImage(oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) { return expander.manager.ExpandImage(expander, oldSize, newSize) } diff --git a/pkg/volume/scaleio/sio_client.go b/pkg/volume/scaleio/sio_client.go index de5b050019f5a..28d8ba79a4b5d 100644 --- a/pkg/volume/scaleio/sio_client.go +++ b/pkg/volume/scaleio/sio_client.go @@ -74,7 +74,7 @@ type sioClient struct { spClient *sio.StoragePool provisionMode string sdcPath string - sdcGuid string + sdcGUID string instanceID string inited bool diskRegex *regexp.Regexp @@ -301,11 +301,11 @@ func (c *sioClient) IID() (string, error) { // if instanceID not set, retrieve it if c.instanceID == "" { - guid, err := c.getGuid() + guid, err := c.getGUID() if err != nil { return "", err } - sdc, err := c.sysClient.FindSdc("SdcGuid", guid) + sdc, err := c.sysClient.FindSdc("SdcGUID", guid) if err != nil { glog.Error(log("failed to retrieve sdc info %s", err)) return "", err @@ -316,10 +316,10 @@ func (c *sioClient) IID() (string, error) { return c.instanceID, nil } -// getGuid returns instance GUID, if not set using resource labels +// getGUID returns instance GUID, if not set using resource labels // it attempts to fallback to using drv_cfg binary -func (c *sioClient) getGuid() (string, error) { - if c.sdcGuid == "" { +func (c *sioClient) getGUID() (string, error) { + if c.sdcGUID == "" { glog.V(4).Info(log("sdc guid label not set, falling back to using drv_cfg")) cmd := c.getSdcCmd() output, err := c.exec.Run(cmd, "--query_guid") @@ -327,9 +327,9 @@ func (c *sioClient) getGuid() (string, error) { glog.Error(log("drv_cfg --query_guid failed: %v", err)) return "", err } - c.sdcGuid = strings.TrimSpace(string(output)) + c.sdcGUID = strings.TrimSpace(string(output)) } - return c.sdcGuid, nil + return c.sdcGUID, nil } // getSioDiskPaths traverse local disk devices to retrieve device path @@ -342,10 +342,10 @@ func (c *sioClient) getSioDiskPaths() ([]os.FileInfo, error) { if os.IsNotExist(err) { // sioDiskIDPath may not exist yet which is fine return []os.FileInfo{}, nil - } else { - glog.Error(log("failed to ReadDir %s: %v", sioDiskIDPath, err)) - return nil, err } + glog.Error(log("failed to ReadDir %s: %v", sioDiskIDPath, err)) + return nil, err + } result := []os.FileInfo{} for _, file := range files { @@ -360,13 +360,13 @@ func (c *sioClient) getSioDiskPaths() ([]os.FileInfo, error) { // GetVolumeRefs counts the number of references an SIO volume has a disk device. // This is useful in preventing premature detach. -func (c *sioClient) GetVolumeRefs(volId sioVolumeID) (refs int, err error) { +func (c *sioClient) GetVolumeRefs(volID sioVolumeID) (refs int, err error) { files, err := c.getSioDiskPaths() if err != nil { return 0, err } for _, file := range files { - if strings.Contains(file.Name(), string(volId)) { + if strings.Contains(file.Name(), string(volID)) { refs++ } } diff --git a/pkg/volume/scaleio/sio_mgr.go b/pkg/volume/scaleio/sio_mgr.go index 711fa7fce5d54..02fbbee6eefb0 100644 --- a/pkg/volume/scaleio/sio_mgr.go +++ b/pkg/volume/scaleio/sio_mgr.go @@ -81,7 +81,7 @@ func (m *sioMgr) getClient() (sioInterface, error) { client.spName = configs[confKey.storagePool] client.sdcPath = configs[confKey.sdcRootPath] client.provisionMode = configs[confKey.storageMode] - client.sdcGuid = configs[confKey.sdcGuid] + client.sdcGUID = configs[confKey.sdcGUID] m.client = client diff --git a/pkg/volume/scaleio/sio_mgr_test.go b/pkg/volume/scaleio/sio_mgr_test.go index 49ff5d05a818b..b1dff3ca1a860 100644 --- a/pkg/volume/scaleio/sio_mgr_test.go +++ b/pkg/volume/scaleio/sio_mgr_test.go @@ -311,7 +311,7 @@ func (f *fakeSio) Devs() (map[string]string, error) { return f.devs, nil } -func (f *fakeSio) GetVolumeRefs(volId sioVolumeID) (int, error) { +func (f *fakeSio) GetVolumeRefs(volID sioVolumeID) (int, error) { if f.volume == nil { return 0, nil } diff --git a/pkg/volume/scaleio/sio_plugin.go b/pkg/volume/scaleio/sio_plugin.go index 367c9b9638da1..c82b6d0fb1378 100644 --- a/pkg/volume/scaleio/sio_plugin.go +++ b/pkg/volume/scaleio/sio_plugin.go @@ -36,6 +36,7 @@ type sioPlugin struct { volumeMtx keymutex.KeyMutex } +// ProbeVolumePlugins is the primary entrypoint for volume plugins. func ProbeVolumePlugins() []volume.VolumePlugin { p := &sioPlugin{ host: nil, diff --git a/pkg/volume/scaleio/sio_util.go b/pkg/volume/scaleio/sio_util.go index de0c581166572..d4a1edcd8f79c 100644 --- a/pkg/volume/scaleio/sio_util.go +++ b/pkg/volume/scaleio/sio_util.go @@ -54,7 +54,7 @@ var ( username, password, secretNamespace, - sdcGuid string + sdcGUID string }{ gateway: "gateway", sslEnabled: "sslEnabled", @@ -71,9 +71,9 @@ var ( readOnly: "readOnly", username: "username", password: "password", - sdcGuid: "sdcGuid", + sdcGUID: "sdcGUID", } - sdcGuidLabelName = "scaleio.sdcGuid" + sdcGUIDLabelName = "scaleio.sdcGUID" sdcRootPath = "/opt/emc/scaleio/sdc/bin" secretNotFoundErr = errors.New("secret not found") @@ -232,30 +232,30 @@ func attachSecret(plug *sioPlugin, namespace string, configData map[string]strin return nil } -// attachSdcGuid injects the sdc guid node label value into config -func attachSdcGuid(plug *sioPlugin, conf map[string]string) error { - guid, err := getSdcGuidLabel(plug) +// attachSdcGUID injects the sdc guid node label value into config +func attachSdcGUID(plug *sioPlugin, conf map[string]string) error { + guid, err := getSdcGUIDLabel(plug) if err != nil { return err } - conf[confKey.sdcGuid] = guid + conf[confKey.sdcGUID] = guid return nil } -// getSdcGuidLabel fetches the scaleio.sdcGuid node label +// getSdcGUIDLabel fetches the scaleio.sdcGuid node label // associated with the node executing this code. -func getSdcGuidLabel(plug *sioPlugin) (string, error) { +func getSdcGUIDLabel(plug *sioPlugin) (string, error) { nodeLabels, err := plug.host.GetNodeLabels() if err != nil { return "", err } - label, ok := nodeLabels[sdcGuidLabelName] + label, ok := nodeLabels[sdcGUIDLabelName] if !ok { - glog.V(4).Info(log("node label %s not found", sdcGuidLabelName)) + glog.V(4).Info(log("node label %s not found", sdcGUIDLabelName)) return "", nil } - glog.V(4).Info(log("found node label %s=%s", sdcGuidLabelName, label)) + glog.V(4).Info(log("found node label %s=%s", sdcGUIDLabelName, label)) return label, nil } diff --git a/pkg/volume/scaleio/sio_volume.go b/pkg/volume/scaleio/sio_volume.go index 0f10dfa1e8356..420afb36ba940 100644 --- a/pkg/volume/scaleio/sio_volume.go +++ b/pkg/volume/scaleio/sio_volume.go @@ -266,7 +266,7 @@ func (v *sioVolume) Provision(selectedNode *api.Node, allowedTopologies []api.To // setup volume attrributes genName := v.generateName("k8svol", 11) var oneGig int64 = 1024 * 1024 * 1024 - var eightGig int64 = 8 * oneGig + eightGig := 8 * oneGig capacity := v.options.PVC.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)] volSizeBytes := capacity.Value() @@ -393,7 +393,7 @@ func (v *sioVolume) setSioMgr() error { } // merge in Sdc Guid label value - if err := attachSdcGuid(v.plugin, configData); err != nil { + if err := attachSdcGUID(v.plugin, configData); err != nil { glog.Error(log("failed to retrieve sdc guid: %v", err)) return err } @@ -432,7 +432,7 @@ func (v *sioVolume) resetSioMgr() error { } // merge in Sdc Guid label value - if err := attachSdcGuid(v.plugin, configData); err != nil { + if err := attachSdcGUID(v.plugin, configData); err != nil { glog.Error(log("failed to retrieve sdc guid: %v", err)) return err } diff --git a/pkg/volume/scaleio/sio_volume_test.go b/pkg/volume/scaleio/sio_volume_test.go index 7f122143f516d..dbc7b8361e815 100644 --- a/pkg/volume/scaleio/sio_volume_test.go +++ b/pkg/volume/scaleio/sio_volume_test.go @@ -56,7 +56,7 @@ func newPluginMgr(t *testing.T, apiObject runtime.Object) (*volume.VolumePluginM tmpDir, fakeClient, nil, - map[string]string{sdcGuidLabelName: "abc-123"}, + map[string]string{sdcGUIDLabelName: "abc-123"}, ) plugMgr := &volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) @@ -206,9 +206,9 @@ func TestVolumeMounterUnmounter(t *testing.T) { t.Errorf("SetUp() - expecting multiple volume disabled by default") } - // did we read sdcGuid label - if _, ok := sioVol.sioMgr.configData[confKey.sdcGuid]; !ok { - t.Errorf("Expected to find node label scaleio.sdcGuid, but did not find it") + // did we read sdcGUID label + if _, ok := sioVol.sioMgr.configData[confKey.sdcGUID]; !ok { + t.Errorf("Expected to find node label scaleio.sdcGUID, but did not find it") } // rebuild spec @@ -349,9 +349,9 @@ func TestVolumeProvisioner(t *testing.T) { t.Fatalf("Expected success, got: %v", err) } - // did we read sdcGuid label - if _, ok := sioVol.sioMgr.configData[confKey.sdcGuid]; !ok { - t.Errorf("Expected to find node label scaleio.sdcGuid, but did not find it") + // did we read sdcGUID label + if _, ok := sioVol.sioMgr.configData[confKey.sdcGUID]; !ok { + t.Errorf("Expected to find node label scaleio.sdcGUID, but did not find it") } // isMultiMap applied diff --git a/pkg/volume/secret/secret.go b/pkg/volume/secret/secret.go index 065b9bfb5af6d..92445b8d0581c 100644 --- a/pkg/volume/secret/secret.go +++ b/pkg/volume/secret/secret.go @@ -30,7 +30,7 @@ import ( volumeutil "k8s.io/kubernetes/pkg/volume/util" ) -// ProbeVolumePlugin is the entry point for plugin detection in a package. +// ProbeVolumePlugins is the entry point for plugin detection in a package. func ProbeVolumePlugins() []volume.VolumePlugin { return []volume.VolumePlugin{&secretPlugin{}} } @@ -259,7 +259,7 @@ func (b *secretVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { return nil } -// Note: this function is exported so that it can be called from the projection volume driver +// MakePayload function is exported so that it can be called from the projection volume driver func MakePayload(mappings []v1.KeyToPath, secret *v1.Secret, defaultMode *int32, optional bool) (map[string]volumeutil.FileProjection, error) { if defaultMode == nil { return nil, fmt.Errorf("No defaultMode used, not even the default value for it") @@ -281,9 +281,9 @@ func MakePayload(mappings []v1.KeyToPath, secret *v1.Secret, defaultMode *int32, if optional { continue } - err_msg := "references non-existent secret key" - glog.Errorf(err_msg) - return nil, fmt.Errorf(err_msg) + errMsg := "references non-existent secret key" + glog.Errorf(errMsg) + return nil, fmt.Errorf(errMsg) } fileProjection.Data = []byte(content) diff --git a/pkg/volume/storageos/storageos_util_test.go b/pkg/volume/storageos/storageos_util_test.go index 598bfd5a21213..e4800cbe51ee1 100644 --- a/pkg/volume/storageos/storageos_util_test.go +++ b/pkg/volume/storageos/storageos_util_test.go @@ -30,7 +30,7 @@ import ( "testing" ) -var testApiSecretName = "storageos-api" +var testAPISecretName = "storageos-api" var testVolName = "storageos-test-vol" var testPVName = "storageos-test-pv" var testNamespace = "storageos-test-namespace" diff --git a/pkg/volume/testing/testing.go b/pkg/volume/testing/testing.go index 7edd8d0f7fdec..224db3e3b8670 100644 --- a/pkg/volume/testing/testing.go +++ b/pkg/volume/testing/testing.go @@ -201,6 +201,10 @@ func (f *fakeVolumeHost) GetServiceAccountTokenFunc() func(string, string, *auth } } +func (f *fakeVolumeHost) DeleteServiceAccountTokenFunc() func(types.UID) { + return func(types.UID) {} +} + func (f *fakeVolumeHost) GetNodeLabels() (map[string]string, error) { if f.nodeLabels == nil { f.nodeLabels = map[string]string{"test-label": "test-value"} @@ -262,6 +266,7 @@ var _ ProvisionableVolumePlugin = &FakeVolumePlugin{} var _ AttachableVolumePlugin = &FakeVolumePlugin{} var _ VolumePluginWithAttachLimits = &FakeVolumePlugin{} var _ DeviceMountableVolumePlugin = &FakeVolumePlugin{} +var _ FSResizableVolumePlugin = &FakeVolumePlugin{} func (plugin *FakeVolumePlugin) getFakeVolume(list *[]*FakeVolume) *FakeVolume { volume := &FakeVolume{} @@ -480,6 +485,10 @@ func (plugin *FakeVolumePlugin) RequiresFSResize() bool { return true } +func (plugin *FakeVolumePlugin) ExpandFS(spec *Spec, devicePath, deviceMountPath string, _, _ resource.Quantity) error { + return nil +} + func (plugin *FakeVolumePlugin) GetVolumeLimits() (map[string]int64, error) { return plugin.VolumeLimits, plugin.VolumeLimitsError } diff --git a/pkg/volume/util/BUILD b/pkg/volume/util/BUILD index a6b371ede0f9c..cafe94a22356d 100644 --- a/pkg/volume/util/BUILD +++ b/pkg/volume/util/BUILD @@ -25,6 +25,7 @@ go_library( "//pkg/features:go_default_library", "//pkg/kubelet/apis:go_default_library", "//pkg/util/mount:go_default_library", + "//pkg/util/resizefs:go_default_library", "//pkg/util/strings:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util/types:go_default_library", diff --git a/pkg/volume/util/operationexecutor/BUILD b/pkg/volume/util/operationexecutor/BUILD index f07c3863afd72..2f42e04ea9f0f 100644 --- a/pkg/volume/util/operationexecutor/BUILD +++ b/pkg/volume/util/operationexecutor/BUILD @@ -18,7 +18,6 @@ go_library( "//pkg/features:go_default_library", "//pkg/kubelet/events:go_default_library", "//pkg/util/mount:go_default_library", - "//pkg/util/resizefs:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", "//pkg/volume/util/nestedpendingoperations:go_default_library", diff --git a/pkg/volume/util/operationexecutor/operation_generator.go b/pkg/volume/util/operationexecutor/operation_generator.go index 95e478246ab6a..67ba7f6d04c4f 100644 --- a/pkg/volume/util/operationexecutor/operation_generator.go +++ b/pkg/volume/util/operationexecutor/operation_generator.go @@ -34,7 +34,6 @@ import ( "k8s.io/kubernetes/pkg/features" kevents "k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/util/mount" - "k8s.io/kubernetes/pkg/util/resizefs" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" @@ -604,10 +603,9 @@ func (og *operationGenerator) resizeFileSystem(volumeToMount VolumeToMount, devi return nil, nil } - mounter := og.volumePluginMgr.Host.GetMounter(pluginName) // Get expander, if possible expandableVolumePlugin, _ := - og.volumePluginMgr.FindExpandablePluginBySpec(volumeToMount.VolumeSpec) + og.volumePluginMgr.FindFSResizablePluginBySpec(volumeToMount.VolumeSpec) if expandableVolumePlugin != nil && expandableVolumePlugin.RequiresFSResize() && @@ -631,25 +629,12 @@ func (og *operationGenerator) resizeFileSystem(volumeToMount VolumeToMount, devi og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FileSystemResizeFailed, simpleMsg) return nil, nil } - - diskFormatter := &mount.SafeFormatAndMount{ - Interface: mounter, - Exec: og.volumePluginMgr.Host.GetExec(expandableVolumePlugin.GetPluginName()), - } - - resizer := resizefs.NewResizeFs(diskFormatter) - resizeStatus, resizeErr := resizer.Resize(devicePath, deviceMountPath) - - if resizeErr != nil { + if resizeErr := expandableVolumePlugin.ExpandFS(volumeToMount.VolumeSpec, devicePath, deviceMountPath, pvSpecCap, pvcStatusCap); resizeErr != nil { return volumeToMount.GenerateError("MountVolume.resizeFileSystem failed", resizeErr) } - - if resizeStatus { - simpleMsg, detailedMsg := volumeToMount.GenerateMsg("MountVolume.resizeFileSystem succeeded", "") - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, simpleMsg) - glog.Infof(detailedMsg) - } - + simpleMsg, detailedMsg := volumeToMount.GenerateMsg("MountVolume.resizeFileSystem succeeded", "") + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, simpleMsg) + glog.Infof(detailedMsg) // File system resize succeeded, now update the PVC's Capacity to match the PV's err = util.MarkFSResizeFinished(pvc, pv.Spec.Capacity, og.kubeClient) if err != nil { @@ -1270,6 +1255,7 @@ func (og *operationGenerator) GenerateExpandVolumeFunc( if err != nil { return volumetypes.GeneratedOperations{}, fmt.Errorf("Error finding plugin for expanding volume: %q with error %v", pvcWithResizeRequest.QualifiedName(), err) } + if volumePlugin == nil { return volumetypes.GeneratedOperations{}, fmt.Errorf("Can not find plugin for expanding volume: %q", pvcWithResizeRequest.QualifiedName()) } @@ -1284,9 +1270,10 @@ func (og *operationGenerator) GenerateExpandVolumeFunc( pvcWithResizeRequest.CurrentSize) if expandErr != nil { - detailedErr := fmt.Errorf("Error expanding volume %q of plugin %s : %v", pvcWithResizeRequest.QualifiedName(), volumePlugin.GetPluginName(), expandErr) + detailedErr := fmt.Errorf("error expanding volume %q of plugin %q: %v", pvcWithResizeRequest.QualifiedName(), volumePlugin.GetPluginName(), expandErr) return detailedErr, detailedErr } + glog.Infof("ExpandVolume succeeded for volume %s", pvcWithResizeRequest.QualifiedName()) newSize = updatedSize // k8s doesn't have transactions, we can't guarantee that after updating PV - updating PVC will be @@ -1371,6 +1358,7 @@ func (og *operationGenerator) GenerateExpandVolumeFSWithoutUnmountingFunc( fsResizeFunc := func() (error, error) { resizeSimpleError, resizeDetailedError := og.resizeFileSystem(volumeToMount, volumeToMount.DevicePath, deviceMountPath, volumePlugin.GetPluginName()) + if resizeSimpleError != nil || resizeDetailedError != nil { return resizeSimpleError, resizeDetailedError } diff --git a/pkg/volume/util/resize_util.go b/pkg/volume/util/resize_util.go index c1d2a1c82acdc..9090ff868623a 100644 --- a/pkg/volume/util/resize_util.go +++ b/pkg/volume/util/resize_util.go @@ -24,10 +24,13 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/strategicpatch" clientset "k8s.io/client-go/kubernetes" + "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/util/resizefs" + "k8s.io/kubernetes/pkg/volume" ) var ( - knownResizeConditions map[v1.PersistentVolumeClaimConditionType]bool = map[v1.PersistentVolumeClaimConditionType]bool{ + knownResizeConditions = map[v1.PersistentVolumeClaimConditionType]bool{ v1.PersistentVolumeClaimFileSystemResizePending: true, v1.PersistentVolumeClaimResizing: true, } @@ -123,3 +126,14 @@ func MergeResizeConditionOnPVC( pvc.Status.Conditions = newConditions return pvc } + +// GenericResizeFS : call generic filesystem resizer for plugins that don't have any special filesystem resize requirements +func GenericResizeFS(host volume.VolumeHost, pluginName, devicePath, deviceMountPath string) (bool, error) { + mounter := host.GetMounter(pluginName) + diskFormatter := &mount.SafeFormatAndMount{ + Interface: mounter, + Exec: host.GetExec(pluginName), + } + resizer := resizefs.NewResizeFs(diskFormatter) + return resizer.Resize(devicePath, deviceMountPath) +} diff --git a/pkg/volume/util/util.go b/pkg/volume/util/util.go index 7106b6c1f7a6b..faf0d34b61d63 100644 --- a/pkg/volume/util/util.go +++ b/pkg/volume/util/util.go @@ -947,6 +947,38 @@ func CheckPersistentVolumeClaimModeBlock(pvc *v1.PersistentVolumeClaim) bool { return utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && pvc.Spec.VolumeMode != nil && *pvc.Spec.VolumeMode == v1.PersistentVolumeBlock } +// IsWindowsUNCPath checks if path is prefixed with \\ +// This can be used to skip any processing of paths +// that point to SMB shares, local named pipes and local UNC path +func IsWindowsUNCPath(goos, path string) bool { + if goos != "windows" { + return false + } + // Check for UNC prefix \\ + if strings.HasPrefix(path, `\\`) { + return true + } + return false +} + +// IsWindowsLocalPath checks if path is a local path +// prefixed with "/" or "\" like "/foo/bar" or "\foo\bar" +func IsWindowsLocalPath(goos, path string) bool { + if goos != "windows" { + return false + } + if IsWindowsUNCPath(goos, path) { + return false + } + if strings.Contains(path, ":") { + return false + } + if !(strings.HasPrefix(path, `/`) || strings.HasPrefix(path, `\`)) { + return false + } + return true +} + // MakeAbsolutePath convert path to absolute path according to GOOS func MakeAbsolutePath(goos, path string) string { if goos != "windows" { diff --git a/pkg/volume/util/util_test.go b/pkg/volume/util/util_test.go index 30d980921ea1f..c5e4e8574f3e0 100644 --- a/pkg/volume/util/util_test.go +++ b/pkg/volume/util/util_test.go @@ -2373,6 +2373,148 @@ func TestGetWindowsPath(t *testing.T) { } } +func TestIsWindowsUNCPath(t *testing.T) { + tests := []struct { + goos string + path string + isUNCPath bool + }{ + { + goos: "linux", + path: `/usr/bin`, + isUNCPath: false, + }, + { + goos: "linux", + path: `\\.\pipe\foo`, + isUNCPath: false, + }, + { + goos: "windows", + path: `C:\foo`, + isUNCPath: false, + }, + { + goos: "windows", + path: `\\server\share\foo`, + isUNCPath: true, + }, + { + goos: "windows", + path: `\\?\server\share`, + isUNCPath: true, + }, + { + goos: "windows", + path: `\\?\c:\`, + isUNCPath: true, + }, + { + goos: "windows", + path: `\\.\pipe\valid_pipe`, + isUNCPath: true, + }, + } + + for _, test := range tests { + result := IsWindowsUNCPath(test.goos, test.path) + if result != test.isUNCPath { + t.Errorf("IsWindowsUNCPath(%v) returned (%v), expected (%v)", test.path, result, test.isUNCPath) + } + } +} + +func TestIsWindowsLocalPath(t *testing.T) { + tests := []struct { + goos string + path string + isWindowsLocalPath bool + }{ + { + goos: "linux", + path: `/usr/bin`, + isWindowsLocalPath: false, + }, + { + goos: "linux", + path: `\\.\pipe\foo`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `C:\foo`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `:\foo`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `X:\foo`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `\\server\share\foo`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `\\?\server\share`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `\\?\c:\`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `\\.\pipe\valid_pipe`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `foo`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `:foo`, + isWindowsLocalPath: false, + }, + { + goos: "windows", + path: `\foo`, + isWindowsLocalPath: true, + }, + { + goos: "windows", + path: `\foo\bar`, + isWindowsLocalPath: true, + }, + { + goos: "windows", + path: `/foo`, + isWindowsLocalPath: true, + }, + { + goos: "windows", + path: `/foo/bar`, + isWindowsLocalPath: true, + }, + } + + for _, test := range tests { + result := IsWindowsLocalPath(test.goos, test.path) + if result != test.isWindowsLocalPath { + t.Errorf("isWindowsLocalPath(%v) returned (%v), expected (%v)", test.path, result, test.isWindowsLocalPath) + } + } +} + func TestMakeAbsolutePath(t *testing.T) { tests := []struct { goos string diff --git a/pkg/volume/vsphere_volume/BUILD b/pkg/volume/vsphere_volume/BUILD index 087276bcad51d..c78d097eb0462 100644 --- a/pkg/volume/vsphere_volume/BUILD +++ b/pkg/volume/vsphere_volume/BUILD @@ -11,21 +11,25 @@ go_library( srcs = [ "attacher.go", "vsphere_volume.go", + "vsphere_volume_block.go", "vsphere_volume_util.go", ], importpath = "k8s.io/kubernetes/pkg/volume/vsphere_volume", deps = [ "//pkg/cloudprovider/providers/vsphere:go_default_library", "//pkg/cloudprovider/providers/vsphere/vclib:go_default_library", + "//pkg/features:go_default_library", "//pkg/util/keymutex:go_default_library", "//pkg/util/mount:go_default_library", "//pkg/util/strings:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/volumepathhandler:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/cloud-provider:go_default_library", "//vendor/github.com/golang/glog:go_default_library", ], @@ -35,6 +39,7 @@ go_test( name = "go_default_test", srcs = [ "attacher_test.go", + "vsphere_volume_block_test.go", "vsphere_volume_test.go", ], embed = [":go_default_library"], @@ -46,6 +51,7 @@ go_test( "//pkg/volume:go_default_library", "//pkg/volume/testing:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library", "//staging/src/k8s.io/cloud-provider:go_default_library", diff --git a/pkg/volume/vsphere_volume/vsphere_volume.go b/pkg/volume/vsphere_volume/vsphere_volume.go index be896d22d8c35..07c9ff47d8709 100644 --- a/pkg/volume/vsphere_volume/vsphere_volume.go +++ b/pkg/volume/vsphere_volume/vsphere_volume.go @@ -27,6 +27,8 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/util/mount" utilstrings "k8s.io/kubernetes/pkg/util/strings" "k8s.io/kubernetes/pkg/volume" @@ -356,9 +358,6 @@ func (v *vsphereVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopol if !util.AccessModesContainedInAll(v.plugin.GetAccessModes(), v.options.PVC.Spec.AccessModes) { return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", v.options.PVC.Spec.AccessModes, v.plugin.GetAccessModes()) } - if util.CheckPersistentVolumeClaimModeBlock(v.options.PVC) { - return nil, fmt.Errorf("%s does not support block volume provisioning", v.plugin.GetPluginName()) - } volSpec, err := v.manager.CreateVolume(v) if err != nil { @@ -369,6 +368,15 @@ func (v *vsphereVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopol volSpec.Fstype = "ext4" } + var volumeMode *v1.PersistentVolumeMode + if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) { + volumeMode = v.options.PVC.Spec.VolumeMode + if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock { + glog.V(5).Infof("vSphere block volume should not have any FSType") + volSpec.Fstype = "" + } + } + pv := &v1.PersistentVolume{ ObjectMeta: metav1.ObjectMeta{ Name: v.options.PVName, @@ -383,6 +391,7 @@ func (v *vsphereVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopol Capacity: v1.ResourceList{ v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dKi", volSpec.Size)), }, + VolumeMode: volumeMode, PersistentVolumeSource: v1.PersistentVolumeSource{ VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{ VolumePath: volSpec.Path, diff --git a/pkg/volume/vsphere_volume/vsphere_volume_block.go b/pkg/volume/vsphere_volume/vsphere_volume_block.go new file mode 100644 index 0000000000000..bb01da9af1925 --- /dev/null +++ b/pkg/volume/vsphere_volume/vsphere_volume_block.go @@ -0,0 +1,161 @@ +/* +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 vsphere_volume + +import ( + "fmt" + "path" + "path/filepath" + "strings" + + "github.com/golang/glog" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/kubernetes/pkg/util/mount" + kstrings "k8s.io/kubernetes/pkg/util/strings" + "k8s.io/kubernetes/pkg/volume" + "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/volumepathhandler" +) + +var _ volume.BlockVolumePlugin = &vsphereVolumePlugin{} + +func (plugin *vsphereVolumePlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, mapPath string) (*volume.Spec, error) { + + pluginDir := plugin.host.GetPluginDir(plugin.GetPluginName()) + blkUtil := volumepathhandler.NewBlockVolumePathHandler() + globalMapPathUUID, err := blkUtil.FindGlobalMapPathUUIDFromPod(pluginDir, mapPath, podUID) + if err != nil { + glog.Errorf("Failed to find GlobalMapPathUUID from Pod: %s with error: %+v", podUID, err) + return nil, err + } + glog.V(5).Infof("globalMapPathUUID: %v", globalMapPathUUID) + globalMapPath := filepath.Dir(globalMapPathUUID) + if len(globalMapPath) <= 1 { + return nil, fmt.Errorf("failed to get volume plugin information from globalMapPathUUID: %v", globalMapPathUUID) + } + return getVolumeSpecFromGlobalMapPath(globalMapPath) +} + +func getVolumeSpecFromGlobalMapPath(globalMapPath string) (*volume.Spec, error) { + // Construct volume spec from globalMapPath + // globalMapPath example: + // plugins/kubernetes.io/{PluginName}/{DefaultKubeletVolumeDevicesDirName}/{volumeID} + // plugins/kubernetes.io/vsphere-volume/volumeDevices/[datastore1]\\040volumes/myDisk + volPath := filepath.Base(globalMapPath) + volPath = strings.Replace(volPath, "\\040", "", -1) + if len(volPath) <= 1 { + return nil, fmt.Errorf("failed to get volume path from global path=%s", globalMapPath) + } + block := v1.PersistentVolumeBlock + vsphereVolume := &v1.PersistentVolume{ + Spec: v1.PersistentVolumeSpec{ + PersistentVolumeSource: v1.PersistentVolumeSource{ + VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{ + VolumePath: volPath, + }, + }, + VolumeMode: &block, + }, + } + return volume.NewSpecFromPersistentVolume(vsphereVolume, true), nil +} + +func (plugin *vsphereVolumePlugin) NewBlockVolumeMapper(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.BlockVolumeMapper, error) { + // If this called via GenerateUnmapDeviceFunc(), pod is nil. + // Pass empty string as dummy uid since uid isn't used in the case. + var uid types.UID + if pod != nil { + uid = pod.UID + } + return plugin.newBlockVolumeMapperInternal(spec, uid, &VsphereDiskUtil{}, plugin.host.GetMounter(plugin.GetPluginName())) +} + +func (plugin *vsphereVolumePlugin) newBlockVolumeMapperInternal(spec *volume.Spec, podUID types.UID, manager vdManager, mounter mount.Interface) (volume.BlockVolumeMapper, error) { + volumeSource, _, err := getVolumeSource(spec) + if err != nil { + glog.Errorf("Failed to get Volume source from volume Spec: %+v with error: %+v", *spec, err) + return nil, err + } + volPath := volumeSource.VolumePath + return &vsphereBlockVolumeMapper{ + vsphereVolume: &vsphereVolume{ + volName: spec.Name(), + podUID: podUID, + volPath: volPath, + manager: manager, + mounter: mounter, + plugin: plugin, + MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, spec.Name(), plugin.host)), + }, + }, nil + +} + +func (plugin *vsphereVolumePlugin) NewBlockVolumeUnmapper(volName string, podUID types.UID) (volume.BlockVolumeUnmapper, error) { + return plugin.newUnmapperInternal(volName, podUID, &VsphereDiskUtil{}) +} + +func (plugin *vsphereVolumePlugin) newUnmapperInternal(volName string, podUID types.UID, manager vdManager) (volume.BlockVolumeUnmapper, error) { + return &vsphereBlockVolumeUnmapper{ + vsphereVolume: &vsphereVolume{ + volName: volName, + podUID: podUID, + volPath: volName, + manager: manager, + plugin: plugin, + }, + }, nil +} + +var _ volume.BlockVolumeMapper = &vsphereBlockVolumeMapper{} + +type vsphereBlockVolumeMapper struct { + *vsphereVolume +} + +func (v vsphereBlockVolumeMapper) SetUpDevice() (string, error) { + return "", nil +} + +func (v vsphereBlockVolumeMapper) MapDevice(devicePath, globalMapPath, volumeMapPath, volumeMapName string, podUID types.UID) error { + return util.MapBlockVolume(devicePath, globalMapPath, volumeMapPath, volumeMapName, podUID) +} + +var _ volume.BlockVolumeUnmapper = &vsphereBlockVolumeUnmapper{} + +type vsphereBlockVolumeUnmapper struct { + *vsphereVolume +} + +func (v *vsphereBlockVolumeUnmapper) TearDownDevice(mapPath, devicePath string) error { + return nil +} + +// GetGlobalMapPath returns global map path and error +// path: plugins/kubernetes.io/{PluginName}/volumeDevices/volumePath +func (v *vsphereVolume) GetGlobalMapPath(spec *volume.Spec) (string, error) { + volumeSource, _, err := getVolumeSource(spec) + if err != nil { + return "", err + } + return path.Join(v.plugin.host.GetVolumeDevicePluginDir(vsphereVolumePluginName), string(volumeSource.VolumePath)), nil +} + +func (v *vsphereVolume) GetPodDeviceMapPath() (string, string) { + return v.plugin.host.GetPodVolumeDeviceDir(v.podUID, kstrings.EscapeQualifiedNameForDisk(vsphereVolumePluginName)), v.volName +} diff --git a/pkg/volume/vsphere_volume/vsphere_volume_block_test.go b/pkg/volume/vsphere_volume/vsphere_volume_block_test.go new file mode 100644 index 0000000000000..4443e7bef7269 --- /dev/null +++ b/pkg/volume/vsphere_volume/vsphere_volume_block_test.go @@ -0,0 +1,147 @@ +/* +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 vsphere_volume + +import ( + "os" + "path" + "testing" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + utiltesting "k8s.io/client-go/util/testing" + "k8s.io/kubernetes/pkg/volume" + volumetest "k8s.io/kubernetes/pkg/volume/testing" +) + +var ( + testVolumePath = "volPath1" + testGlobalPath = "plugins/kubernetes.io/vsphere-volume/volumeDevices/volPath1" + testPodPath = "pods/poduid/volumeDevices/kubernetes.io~vsphere-volume" +) + +func TestGetVolumeSpecFromGlobalMapPath(t *testing.T) { + // make our test path for fake GlobalMapPath + // /tmp symbolized our pluginDir + // /tmp/testGlobalPathXXXXX/plugins/kubernetes.io/vsphere-volume/volumeDevices/ + tmpVDir, err := utiltesting.MkTmpdir("vsphereBlockVolume") + if err != nil { + t.Fatalf("cant' make a temp dir: %s", err) + } + // deferred clean up + defer os.RemoveAll(tmpVDir) + + expectedGlobalPath := path.Join(tmpVDir, testGlobalPath) + + // Bad Path + badspec, err := getVolumeSpecFromGlobalMapPath("") + if badspec != nil || err == nil { + t.Errorf("Expected not to get spec from GlobalMapPath but did") + } + + // Good Path + spec, err := getVolumeSpecFromGlobalMapPath(expectedGlobalPath) + if spec == nil || err != nil { + t.Fatalf("Failed to get spec from GlobalMapPath: %s", err) + } + if spec.PersistentVolume.Spec.VsphereVolume.VolumePath != testVolumePath { + t.Fatalf("Invalid volumePath from GlobalMapPath spec: %s", spec.PersistentVolume.Spec.VsphereVolume.VolumePath) + } + block := v1.PersistentVolumeBlock + specMode := spec.PersistentVolume.Spec.VolumeMode + if &specMode == nil { + t.Errorf("Invalid volumeMode from GlobalMapPath spec: %v expected: %v", &specMode, block) + } + if *specMode != block { + t.Errorf("Invalid volumeMode from GlobalMapPath spec: %v expected: %v", *specMode, block) + } +} + +func TestGetPodAndPluginMapPaths(t *testing.T) { + tmpVDir, err := utiltesting.MkTmpdir("vsphereBlockVolume") + if err != nil { + t.Fatalf("cant' make a temp dir: %s", err) + } + // deferred clean up + defer os.RemoveAll(tmpVDir) + + expectedGlobalPath := path.Join(tmpVDir, testGlobalPath) + expectedPodPath := path.Join(tmpVDir, testPodPath) + + spec := getTestVolume(true) // block volume + pluginMgr := volume.VolumePluginMgr{} + pluginMgr.InitPlugins(ProbeVolumePlugins(), nil, volumetest.NewFakeVolumeHost(tmpVDir, nil, nil)) + plugin, err := pluginMgr.FindMapperPluginByName(vsphereVolumePluginName) + if err != nil { + os.RemoveAll(tmpVDir) + t.Fatalf("Can't find the plugin by name: %q", vsphereVolumePluginName) + } + if plugin.GetPluginName() != vsphereVolumePluginName { + t.Fatalf("Wrong name: %s", plugin.GetPluginName()) + } + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + UID: types.UID("poduid"), + }, + } + mapper, err := plugin.NewBlockVolumeMapper(spec, pod, volume.VolumeOptions{}) + if err != nil { + t.Fatalf("Failed to make a new Mounter: %v", err) + } + if mapper == nil { + t.Fatalf("Got a nil Mounter") + } + + // GetGlobalMapPath + globalMapPath, err := mapper.GetGlobalMapPath(spec) + if err != nil || len(globalMapPath) == 0 { + t.Fatalf("Invalid GlobalMapPath from spec: %s", spec.PersistentVolume.Spec.VsphereVolume.VolumePath) + } + if globalMapPath != expectedGlobalPath { + t.Errorf("Failed to get GlobalMapPath: %s %s", globalMapPath, expectedGlobalPath) + } + + // GetPodDeviceMapPath + devicePath, volumeName := mapper.GetPodDeviceMapPath() + if devicePath != expectedPodPath { + t.Errorf("Got unexpected pod path: %s, expected %s", devicePath, expectedPodPath) + } + if volumeName != testVolumePath { + t.Errorf("Got unexpected volNamne: %s, expected %s", volumeName, testVolumePath) + } +} + +func getTestVolume(isBlock bool) *volume.Spec { + pv := &v1.PersistentVolume{ + ObjectMeta: metav1.ObjectMeta{ + Name: testVolumePath, + }, + Spec: v1.PersistentVolumeSpec{ + PersistentVolumeSource: v1.PersistentVolumeSource{ + VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{ + VolumePath: testVolumePath, + }, + }, + }, + } + if isBlock { + blockMode := v1.PersistentVolumeBlock + pv.Spec.VolumeMode = &blockMode + } + return volume.NewSpecFromPersistentVolume(pv, true) +} diff --git a/plugin/pkg/admission/gc/BUILD b/plugin/pkg/admission/gc/BUILD index 2f84e0cd0c84f..354e386505b55 100644 --- a/plugin/pkg/admission/gc/BUILD +++ b/plugin/pkg/admission/gc/BUILD @@ -27,10 +27,10 @@ go_test( srcs = ["gc_admission_test.go"], embed = [":go_default_library"], deps = [ - "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/kubeapiserver/admission:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", @@ -38,6 +38,9 @@ go_test( "//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", + "//staging/src/k8s.io/client-go/discovery/fake:go_default_library", + "//staging/src/k8s.io/client-go/restmapper:go_default_library", + "//staging/src/k8s.io/client-go/testing:go_default_library", ], ) diff --git a/plugin/pkg/admission/gc/gc_admission.go b/plugin/pkg/admission/gc/gc_admission.go index 1bfeaf0a170af..89122da5a68bf 100644 --- a/plugin/pkg/admission/gc/gc_admission.go +++ b/plugin/pkg/admission/gc/gc_admission.go @@ -186,11 +186,9 @@ func (a *gcPermissionsEnforcement) ownerRefToDeleteAttributeRecords(ref metav1.O return ret, err } for _, mapping := range mappings { - ret = append(ret, authorizer.AttributesRecord{ - User: attributes.GetUserInfo(), - Verb: "update", - // ownerReference can only refer to an object in the same namespace, so attributes.GetNamespace() equals to the owner's namespace - Namespace: attributes.GetNamespace(), + ar := authorizer.AttributesRecord{ + User: attributes.GetUserInfo(), + Verb: "update", APIGroup: mapping.Resource.Group, APIVersion: mapping.Resource.Version, Resource: mapping.Resource.Resource, @@ -198,7 +196,12 @@ func (a *gcPermissionsEnforcement) ownerRefToDeleteAttributeRecords(ref metav1.O Name: ref.Name, ResourceRequest: true, Path: "", - }) + } + if mapping.Scope.Name() == meta.RESTScopeNameNamespace { + // if the owner is namespaced, it must be in the same namespace as the dependent is. + ar.Namespace = attributes.GetNamespace() + } + ret = append(ret, ar) } return ret, nil } diff --git a/plugin/pkg/admission/gc/gc_admission_test.go b/plugin/pkg/admission/gc/gc_admission_test.go index 753d4dc3c82d2..034e5179e45bf 100644 --- a/plugin/pkg/admission/gc/gc_admission_test.go +++ b/plugin/pkg/admission/gc/gc_admission_test.go @@ -17,10 +17,12 @@ limitations under the License. package gc import ( + "fmt" "strings" "testing" - "k8s.io/apimachinery/pkg/api/meta/testrestmapper" + corev1 "k8s.io/api/core/v1" + extensionv1beta1 "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -28,7 +30,9 @@ import ( "k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" - "k8s.io/kubernetes/pkg/api/legacyscheme" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/restmapper" + coretesting "k8s.io/client-go/testing" api "k8s.io/kubernetes/pkg/apis/core" kubeadmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" ) @@ -68,6 +72,15 @@ func (fakeAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, s return authorizer.DecisionAllow, "", nil } + if username == "non-node-deleter" { + if a.GetVerb() == "delete" && a.GetResource() == "nodes" { + return authorizer.DecisionNoOpinion, "", nil + } + if a.GetVerb() == "update" && a.GetResource() == "nodes" && a.GetSubresource() == "finalizers" { + return authorizer.DecisionNoOpinion, "", nil + } + return authorizer.DecisionAllow, "", nil + } return authorizer.DecisionAllow, "", nil } @@ -88,7 +101,30 @@ func newGCPermissionsEnforcement() (*gcPermissionsEnforcement, error) { } genericPluginInitializer := initializer.New(nil, nil, fakeAuthorizer{}, nil) - pluginInitializer := kubeadmission.NewPluginInitializer(nil, nil, nil, testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Scheme), nil) + fakeDiscoveryClient := &fakediscovery.FakeDiscovery{Fake: &coretesting.Fake{}} + fakeDiscoveryClient.Resources = []*metav1.APIResourceList{ + { + GroupVersion: corev1.SchemeGroupVersion.String(), + APIResources: []metav1.APIResource{ + {Name: "nodes", Namespaced: false, Kind: "Node"}, + {Name: "pods", Namespaced: true, Kind: "Pod"}, + {Name: "replicationcontrollers", Namespaced: true, Kind: "ReplicationController"}, + }, + }, + { + GroupVersion: extensionv1beta1.SchemeGroupVersion.String(), + APIResources: []metav1.APIResource{ + {Name: "daemonsets", Namespaced: true, Kind: "DaemonSet"}, + }, + }, + } + + restMapperRes, err := restmapper.GetAPIGroupResources(fakeDiscoveryClient) + if err != nil { + return nil, fmt.Errorf("unexpected error while constructing resource list from fake discovery client: %v", err) + } + restMapper := restmapper.NewDiscoveryRESTMapper(restMapperRes) + pluginInitializer := kubeadmission.NewPluginInitializer(nil, restMapper, nil) initializersChain := admission.PluginInitializers{} initializersChain = append(initializersChain, genericPluginInitializer) initializersChain = append(initializersChain, pluginInitializer) @@ -347,6 +383,23 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { Name: "ds1", BlockOwnerDeletion: getFalseVar(), } + blockNode := metav1.OwnerReference{ + APIVersion: "v1", + Kind: "Node", + Name: "node1", + BlockOwnerDeletion: getTrueVar(), + } + notBlockNode := metav1.OwnerReference{ + APIVersion: "v1", + Kind: "Node", + Name: "node", + BlockOwnerDeletion: getFalseVar(), + } + nilBlockNode := metav1.OwnerReference{ + APIVersion: "v1", + Kind: "Node", + Name: "node", + } expectNoError := func(err error) bool { return err == nil @@ -386,7 +439,7 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { name: "super-user, create, some ownerReferences have blockOwnerDeletion=true", username: "super", resource: api.SchemeGroupVersion.WithResource("pods"), - newObj: podWithOwnerRefs(blockRC1, blockRC2), + newObj: podWithOwnerRefs(blockRC1, blockRC2, blockNode), checkError: expectNoError, }, { @@ -403,6 +456,13 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { newObj: podWithOwnerRefs(notBlockRC1, nilBlockRC2), checkError: expectNoError, }, + { + name: "non-node-deleter, create, all ownerReferences have blockOwnerDeletion=false", + username: "non-node-deleter", + resource: api.SchemeGroupVersion.WithResource("pods"), + newObj: podWithOwnerRefs(notBlockNode), + checkError: expectNoError, + }, { name: "non-rc-deleter, create, some ownerReferences have blockOwnerDeletion=true", username: "non-rc-deleter", @@ -417,21 +477,28 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { newObj: podWithOwnerRefs(blockDS1), checkError: expectNoError, }, + { + name: "non-node-deleter, create, some ownerReferences have blockOwnerDeletion=true", + username: "non-node-deleter", + resource: api.SchemeGroupVersion.WithResource("pods"), + newObj: podWithOwnerRefs(blockNode), + checkError: expectCantSetBlockOwnerDeletionError, + }, // cases are for update { name: "super-user, update, no ownerReferences change blockOwnerDeletion", username: "super", resource: api.SchemeGroupVersion.WithResource("pods"), - oldObj: podWithOwnerRefs(nilBlockRC1), - newObj: podWithOwnerRefs(notBlockRC1), + oldObj: podWithOwnerRefs(nilBlockRC1, nilBlockNode), + newObj: podWithOwnerRefs(notBlockRC1, notBlockNode), checkError: expectNoError, }, { name: "super-user, update, some ownerReferences change to blockOwnerDeletion=true", username: "super", resource: api.SchemeGroupVersion.WithResource("pods"), - oldObj: podWithOwnerRefs(notBlockRC1), - newObj: podWithOwnerRefs(blockRC1), + oldObj: podWithOwnerRefs(notBlockRC1, notBlockNode), + newObj: podWithOwnerRefs(blockRC1, blockNode), checkError: expectNoError, }, { @@ -439,7 +506,7 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { username: "super", resource: api.SchemeGroupVersion.WithResource("pods"), oldObj: podWithOwnerRefs(), - newObj: podWithOwnerRefs(blockRC1), + newObj: podWithOwnerRefs(blockRC1, blockNode), checkError: expectNoError, }, { @@ -466,6 +533,14 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { newObj: podWithOwnerRefs(blockRC1), checkError: expectCantSetBlockOwnerDeletionError, }, + { + name: "non-node-deleter, update, some ownerReferences change from blockOwnerDeletion=nil to true", + username: "non-node-deleter", + resource: api.SchemeGroupVersion.WithResource("pods"), + oldObj: podWithOwnerRefs(nilBlockNode), + newObj: podWithOwnerRefs(blockNode), + checkError: expectCantSetBlockOwnerDeletionError, + }, { name: "non-rc-deleter, update, some ownerReferences change from blockOwnerDeletion=true to false", username: "non-rc-deleter", @@ -474,6 +549,14 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { newObj: podWithOwnerRefs(notBlockRC1), checkError: expectNoError, }, + { + name: "non-node-deleter, update, some ownerReferences change from blockOwnerDeletion=true to false", + username: "non-node-deleter", + resource: api.SchemeGroupVersion.WithResource("pods"), + oldObj: podWithOwnerRefs(blockNode), + newObj: podWithOwnerRefs(notBlockNode), + checkError: expectNoError, + }, { name: "non-rc-deleter, update, some ownerReferences change blockOwnerDeletion, but all such references are to daemonset", username: "non-rc-deleter", @@ -506,6 +589,14 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { newObj: podWithOwnerRefs(blockDS1), checkError: expectNoError, }, + { + name: "non-node-deleter, update, add ownerReferences with blockOwnerDeletion=true", + username: "non-node-deleter", + resource: api.SchemeGroupVersion.WithResource("pods"), + oldObj: podWithOwnerRefs(), + newObj: podWithOwnerRefs(blockNode), + checkError: expectCantSetBlockOwnerDeletionError, + }, } gcAdmit, err := newGCPermissionsEnforcement() if err != nil { diff --git a/plugin/pkg/admission/noderestriction/OWNERS b/plugin/pkg/admission/noderestriction/OWNERS index 77eb1f5a7f62b..5a7794867cfaa 100644 --- a/plugin/pkg/admission/noderestriction/OWNERS +++ b/plugin/pkg/admission/noderestriction/OWNERS @@ -1,10 +1,7 @@ approvers: -- deads2k -- liggitt -- tallclair -- mikedanese +- sig-auth-node-isolation-approvers reviewers: -- deads2k -- liggitt -- tallclair -- mikedanese +- sig-auth-node-isolation-reviewers +labels: +- sig/auth + diff --git a/plugin/pkg/admission/podnodeselector/BUILD b/plugin/pkg/admission/podnodeselector/BUILD index 46fc503480f7e..c7ef7642951c8 100644 --- a/plugin/pkg/admission/podnodeselector/BUILD +++ b/plugin/pkg/admission/podnodeselector/BUILD @@ -12,16 +12,17 @@ go_library( importpath = "k8s.io/kubernetes/plugin/pkg/admission/podnodeselector", deps = [ "//pkg/apis/core:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", - "//pkg/client/listers/core/internalversion:go_default_library", - "//pkg/kubeapiserver/admission:go_default_library", "//pkg/kubeapiserver/admission/util:go_default_library", + "//staging/src/k8s.io/api/core/v1: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/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library", + "//staging/src/k8s.io/client-go/informers:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes:go_default_library", + "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", "//vendor/github.com/golang/glog:go_default_library", ], ) @@ -32,13 +33,14 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/apis/core:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/clientset_generated/internalclientset/fake:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", - "//pkg/kubeapiserver/admission:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library", + "//staging/src/k8s.io/client-go/informers:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", ], ) diff --git a/plugin/pkg/admission/podnodeselector/admission.go b/plugin/pkg/admission/podnodeselector/admission.go index 3e06fec3a5bb9..8dc1daa66c66d 100644 --- a/plugin/pkg/admission/podnodeselector/admission.go +++ b/plugin/pkg/admission/podnodeselector/admission.go @@ -23,16 +23,17 @@ import ( "github.com/golang/glog" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/apiserver/pkg/admission" + genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + corev1listers "k8s.io/client-go/listers/core/v1" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" - corelisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion" - kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" "k8s.io/kubernetes/pkg/kubeapiserver/admission/util" ) @@ -55,16 +56,14 @@ func Register(plugins *admission.Plugins) { // podNodeSelector is an implementation of admission.Interface. type podNodeSelector struct { *admission.Handler - client internalclientset.Interface - namespaceLister corelisters.NamespaceLister + client kubernetes.Interface + namespaceLister corev1listers.NamespaceLister // global default node selector and namespace whitelists in a cluster. clusterNodeSelectors map[string]string } -var _ admission.MutationInterface = &podNodeSelector{} -var _ admission.ValidationInterface = &podNodeSelector{} -var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&podNodeSelector{}) -var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&podNodeSelector{}) +var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&podNodeSelector{}) +var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&podNodeSelector{}) type pluginConfig struct { PodNodeSelectorPluginConfig map[string]string @@ -205,12 +204,12 @@ func NewPodNodeSelector(clusterNodeSelectors map[string]string) *podNodeSelector } } -func (a *podNodeSelector) SetInternalKubeClientSet(client internalclientset.Interface) { +func (a *podNodeSelector) SetExternalKubeClientSet(client kubernetes.Interface) { a.client = client } -func (p *podNodeSelector) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) { - namespaceInformer := f.Core().InternalVersion().Namespaces() +func (p *podNodeSelector) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { + namespaceInformer := f.Core().V1().Namespaces() p.namespaceLister = namespaceInformer.Lister() p.SetReadyFunc(namespaceInformer.Informer().HasSynced) } @@ -225,7 +224,7 @@ func (p *podNodeSelector) ValidateInitialization() error { return nil } -func (p *podNodeSelector) defaultGetNamespace(name string) (*api.Namespace, error) { +func (p *podNodeSelector) defaultGetNamespace(name string) (*corev1.Namespace, error) { namespace, err := p.client.Core().Namespaces().Get(name, metav1.GetOptions{}) if err != nil { return nil, fmt.Errorf("namespace %s does not exist", name) @@ -233,7 +232,7 @@ func (p *podNodeSelector) defaultGetNamespace(name string) (*api.Namespace, erro return namespace, nil } -func (p *podNodeSelector) getNodeSelectorMap(namespace *api.Namespace) (labels.Set, error) { +func (p *podNodeSelector) getNodeSelectorMap(namespace *corev1.Namespace) (labels.Set, error) { selector := labels.Set{} labelsMap := labels.Set{} var err error diff --git a/plugin/pkg/admission/podnodeselector/admission_test.go b/plugin/pkg/admission/podnodeselector/admission_test.go index c48c795ef7a3b..ba1d3f16a5266 100644 --- a/plugin/pkg/admission/podnodeselector/admission_test.go +++ b/plugin/pkg/admission/podnodeselector/admission_test.go @@ -20,26 +20,27 @@ import ( "testing" "time" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apiserver/pkg/admission" + genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" api "k8s.io/kubernetes/pkg/apis/core" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" - informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" - kubeadmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" ) // TestPodAdmission verifies various scenarios involving pod/namespace/global node label selectors func TestPodAdmission(t *testing.T) { - namespace := &api.Namespace{ + namespace := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "testNamespace", Namespace: "", }, } - mockClient := &fake.Clientset{} + mockClient := fake.NewSimpleClientset(namespace) handler, informerFactory, err := newHandlerForTest(mockClient) if err != nil { t.Errorf("unexpected error initializing handler: %v", err) @@ -159,7 +160,7 @@ func TestPodAdmission(t *testing.T) { for _, test := range tests { if !test.ignoreTestNamespaceNodeSelector { namespace.ObjectMeta.Annotations = map[string]string{"scheduler.alpha.kubernetes.io/node-selector": test.namespaceNodeSelector} - informerFactory.Core().InternalVersion().Namespaces().Informer().GetStore().Update(namespace) + informerFactory.Core().V1().Namespaces().Informer().GetStore().Update(namespace) } handler.clusterNodeSelectors = make(map[string]string) handler.clusterNodeSelectors["clusterDefaultNodeSelector"] = test.defaultNodeSelector @@ -216,7 +217,15 @@ func TestHandles(t *testing.T) { } func TestIgnoreUpdatingInitializedPod(t *testing.T) { - mockClient := &fake.Clientset{} + namespaceNodeSelector := "infra=true" + namespace := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testNamespace", + Namespace: "", + Annotations: map[string]string{"scheduler.alpha.kubernetes.io/node-selector": namespaceNodeSelector}, + }, + } + mockClient := fake.NewSimpleClientset(namespace) handler, informerFactory, err := newHandlerForTest(mockClient) if err != nil { t.Errorf("unexpected error initializing handler: %v", err) @@ -229,15 +238,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) { Spec: api.PodSpec{NodeSelector: podNodeSelector}, } // this conflicts with podNodeSelector - namespaceNodeSelector := "infra=true" - namespace := &api.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "testNamespace", - Namespace: "", - Annotations: map[string]string{"scheduler.alpha.kubernetes.io/node-selector": namespaceNodeSelector}, - }, - } - err = informerFactory.Core().InternalVersion().Namespaces().Informer().GetStore().Update(namespace) + err = informerFactory.Core().V1().Namespaces().Informer().GetStore().Update(namespace) if err != nil { t.Fatal(err) } @@ -250,10 +251,10 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) { } // newHandlerForTest returns the admission controller configured for testing. -func newHandlerForTest(c clientset.Interface) (*podNodeSelector, informers.SharedInformerFactory, error) { +func newHandlerForTest(c kubernetes.Interface) (*podNodeSelector, informers.SharedInformerFactory, error) { f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewPodNodeSelector(nil) - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil) + pluginInitializer := genericadmissioninitializer.New(c, f, nil, nil) pluginInitializer.Initialize(handler) err := admission.ValidateInitialization(handler) return handler, f, err diff --git a/plugin/pkg/admission/podtolerationrestriction/BUILD b/plugin/pkg/admission/podtolerationrestriction/BUILD index 5ad9563065465..d5652163389aa 100644 --- a/plugin/pkg/admission/podtolerationrestriction/BUILD +++ b/plugin/pkg/admission/podtolerationrestriction/BUILD @@ -12,17 +12,18 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/apis/core:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/clientset_generated/internalclientset/fake:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", - "//pkg/kubeapiserver/admission:go_default_library", "//pkg/scheduler/api:go_default_library", "//pkg/util/tolerations:go_default_library", "//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", + "//staging/src/k8s.io/client-go/informers:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", ], ) @@ -37,10 +38,6 @@ go_library( "//pkg/apis/core:go_default_library", "//pkg/apis/core/helper/qos:go_default_library", "//pkg/apis/core/v1:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", - "//pkg/client/listers/core/internalversion:go_default_library", - "//pkg/kubeapiserver/admission:go_default_library", "//pkg/kubeapiserver/admission/util:go_default_library", "//pkg/scheduler/api:go_default_library", "//pkg/util/tolerations:go_default_library", @@ -54,6 +51,10 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library", + "//staging/src/k8s.io/client-go/informers:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes:go_default_library", + "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", "//vendor/github.com/golang/glog:go_default_library", ], ) diff --git a/plugin/pkg/admission/podtolerationrestriction/admission.go b/plugin/pkg/admission/podtolerationrestriction/admission.go index 75feaeb8da3dd..6e75d8dc2bc2f 100644 --- a/plugin/pkg/admission/podtolerationrestriction/admission.go +++ b/plugin/pkg/admission/podtolerationrestriction/admission.go @@ -24,16 +24,17 @@ import ( "github.com/golang/glog" "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/admission" + genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + corev1listers "k8s.io/client-go/listers/core/v1" api "k8s.io/kubernetes/pkg/apis/core" qoshelper "k8s.io/kubernetes/pkg/apis/core/helper/qos" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" - corelisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion" - kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" "k8s.io/kubernetes/pkg/kubeapiserver/admission/util" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" "k8s.io/kubernetes/pkg/util/tolerations" @@ -61,12 +62,13 @@ const ( var _ admission.MutationInterface = &podTolerationsPlugin{} var _ admission.ValidationInterface = &podTolerationsPlugin{} -var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&podTolerationsPlugin{}) +var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&podTolerationsPlugin{}) +var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&podTolerationsPlugin{}) type podTolerationsPlugin struct { *admission.Handler - client clientset.Interface - namespaceLister corelisters.NamespaceLister + client kubernetes.Interface + namespaceLister corev1listers.NamespaceLister pluginConfig *pluginapi.Configuration } @@ -200,12 +202,12 @@ func NewPodTolerationsPlugin(pluginConfig *pluginapi.Configuration) *podTolerati } } -func (a *podTolerationsPlugin) SetInternalKubeClientSet(client clientset.Interface) { +func (a *podTolerationsPlugin) SetExternalKubeClientSet(client kubernetes.Interface) { a.client = client } -func (p *podTolerationsPlugin) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) { - namespaceInformer := f.Core().InternalVersion().Namespaces() +func (p *podTolerationsPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { + namespaceInformer := f.Core().V1().Namespaces() p.namespaceLister = namespaceInformer.Lister() p.SetReadyFunc(namespaceInformer.Informer().HasSynced) @@ -222,11 +224,11 @@ func (p *podTolerationsPlugin) ValidateInitialization() error { } // in exceptional cases, this can result in two live calls, but once the cache catches up, that will stop. -func (p *podTolerationsPlugin) getNamespace(nsName string) (*api.Namespace, error) { +func (p *podTolerationsPlugin) getNamespace(nsName string) (*corev1.Namespace, error) { namespace, err := p.namespaceLister.Get(nsName) if errors.IsNotFound(err) { // in case of latency in our caches, make a call direct to storage to verify that it truly exists or not - namespace, err = p.client.Core().Namespaces().Get(nsName, metav1.GetOptions{}) + namespace, err = p.client.CoreV1().Namespaces().Get(nsName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { return nil, err @@ -262,7 +264,7 @@ func (p *podTolerationsPlugin) getNamespaceTolerationsWhitelist(nsName string) ( // unset (nil), extractNSTolerations returns nil. If the value to these // keys are set to empty, an empty toleration is returned, otherwise // configured tolerations are returned. -func extractNSTolerations(ns *api.Namespace, key string) ([]api.Toleration, error) { +func extractNSTolerations(ns *corev1.Namespace, key string) ([]api.Toleration, error) { // if a namespace does not have any annotations if len(ns.Annotations) == 0 { return nil, nil diff --git a/plugin/pkg/admission/podtolerationrestriction/admission_test.go b/plugin/pkg/admission/podtolerationrestriction/admission_test.go index 45df727c07320..688c0671c862b 100644 --- a/plugin/pkg/admission/podtolerationrestriction/admission_test.go +++ b/plugin/pkg/admission/podtolerationrestriction/admission_test.go @@ -21,15 +21,16 @@ import ( "testing" "time" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/admission" + genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer" utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" api "k8s.io/kubernetes/pkg/apis/core" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" - informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" - kubeadmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" "k8s.io/kubernetes/pkg/util/tolerations" pluginapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction" @@ -216,7 +217,7 @@ func TestPodAdmission(t *testing.T) { } for _, test := range tests { t.Run(test.testName, func(t *testing.T) { - namespace := &api.Namespace{ + namespace := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "testNamespace", Namespace: "", @@ -335,14 +336,14 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) { if err != nil { t.Errorf("error in marshalling namespace tolerations %v", namespaceTolerations) } - namespace := &api.Namespace{ + namespace := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "testNamespace", Namespace: "", }, } namespace.Annotations = map[string]string{NSDefaultTolerations: string(tolerationsStr)} - err = informerFactory.Core().InternalVersion().Namespaces().Informer().GetStore().Update(namespace) + err = informerFactory.Core().V1().Namespaces().Informer().GetStore().Update(namespace) if err != nil { t.Fatal(err) } @@ -355,7 +356,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) { } // newHandlerForTest returns the admission controller configured for testing. -func newHandlerForTest(c clientset.Interface) (*podTolerationsPlugin, informers.SharedInformerFactory, error) { +func newHandlerForTest(c kubernetes.Interface) (*podTolerationsPlugin, informers.SharedInformerFactory, error) { f := informers.NewSharedInformerFactory(c, 5*time.Minute) pluginConfig, err := loadConfiguration(nil) // must not fail @@ -363,7 +364,7 @@ func newHandlerForTest(c clientset.Interface) (*podTolerationsPlugin, informers. return nil, nil, err } handler := NewPodTolerationsPlugin(pluginConfig) - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil) + pluginInitializer := genericadmissioninitializer.New(c, f, nil, nil) pluginInitializer.Initialize(handler) err = admission.ValidateInitialization(handler) return handler, f, err diff --git a/plugin/pkg/admission/security/podsecuritypolicy/OWNERS b/plugin/pkg/admission/security/podsecuritypolicy/OWNERS index f3ca3b7dd1432..787630abd2fd2 100644 --- a/plugin/pkg/admission/security/podsecuritypolicy/OWNERS +++ b/plugin/pkg/admission/security/podsecuritypolicy/OWNERS @@ -1,5 +1,7 @@ approvers: -- tallclair -- liggitt +- sig-auth-policy-approvers reviewers: -- pweil- +- sig-auth-policy-reviewers +labels: +- sig/auth + diff --git a/plugin/pkg/admission/serviceaccount/OWNERS b/plugin/pkg/admission/serviceaccount/OWNERS index af89d3e6d6542..d914c0d7195a7 100644 --- a/plugin/pkg/admission/serviceaccount/OWNERS +++ b/plugin/pkg/admission/serviceaccount/OWNERS @@ -1,9 +1,7 @@ approvers: -- liggitt -- deads2k -- mikedanese +- sig-auth-serviceaccounts-approvers reviewers: -- liggitt -- deads2k -- mikedanese -- enj +- sig-auth-serviceaccounts-reviewers +labels: +- sig/auth + diff --git a/plugin/pkg/admission/storage/persistentvolume/label/admission.go b/plugin/pkg/admission/storage/persistentvolume/label/admission.go index 8afe0190aa224..a1683e3d297e3 100644 --- a/plugin/pkg/admission/storage/persistentvolume/label/admission.go +++ b/plugin/pkg/admission/storage/persistentvolume/label/admission.go @@ -58,7 +58,7 @@ type persistentVolumeLabel struct { mutex sync.Mutex ebsVolumes aws.Volumes cloudConfig []byte - gceCloudProvider *gce.GCECloud + gceCloudProvider *gce.Cloud azureProvider *azure.Cloud } @@ -259,7 +259,7 @@ func (l *persistentVolumeLabel) findGCEPDLabels(volume *api.PersistentVolume) (m } // getGCECloudProvider returns the GCE cloud provider, for use for querying volume labels -func (l *persistentVolumeLabel) getGCECloudProvider() (*gce.GCECloud, error) { +func (l *persistentVolumeLabel) getGCECloudProvider() (*gce.Cloud, error) { l.mutex.Lock() defer l.mutex.Unlock() @@ -272,7 +272,7 @@ func (l *persistentVolumeLabel) getGCECloudProvider() (*gce.GCECloud, error) { if err != nil || cloudProvider == nil { return nil, err } - gceCloudProvider, ok := cloudProvider.(*gce.GCECloud) + gceCloudProvider, ok := cloudProvider.(*gce.Cloud) if !ok { // GetCloudProvider has gone very wrong return nil, fmt.Errorf("error retrieving GCE cloud provider") diff --git a/plugin/pkg/admission/storage/persistentvolume/resize/BUILD b/plugin/pkg/admission/storage/persistentvolume/resize/BUILD index 2c2db2da162f5..80368f05a4fef 100644 --- a/plugin/pkg/admission/storage/persistentvolume/resize/BUILD +++ b/plugin/pkg/admission/storage/persistentvolume/resize/BUILD @@ -12,14 +12,14 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/apis/core:go_default_library", - "//pkg/apis/storage:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", "//pkg/controller:go_default_library", + "//staging/src/k8s.io/api/storage/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", + "//staging/src/k8s.io/client-go/informers:go_default_library", ], ) @@ -30,11 +30,10 @@ go_library( deps = [ "//pkg/apis/core:go_default_library", "//pkg/apis/core/helper:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", - "//pkg/client/listers/core/internalversion:go_default_library", - "//pkg/client/listers/storage/internalversion:go_default_library", - "//pkg/kubeapiserver/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library", + "//staging/src/k8s.io/client-go/informers:go_default_library", + "//staging/src/k8s.io/client-go/listers/storage/v1:go_default_library", ], ) diff --git a/plugin/pkg/admission/storage/persistentvolume/resize/admission.go b/plugin/pkg/admission/storage/persistentvolume/resize/admission.go index 10398b1edd668..3a945ea9dcc40 100644 --- a/plugin/pkg/admission/storage/persistentvolume/resize/admission.go +++ b/plugin/pkg/admission/storage/persistentvolume/resize/admission.go @@ -21,12 +21,11 @@ import ( "io" "k8s.io/apiserver/pkg/admission" + genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer" + "k8s.io/client-go/informers" + storagev1listers "k8s.io/client-go/listers/storage/v1" api "k8s.io/kubernetes/pkg/apis/core" apihelper "k8s.io/kubernetes/pkg/apis/core/helper" - informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" - pvlister "k8s.io/kubernetes/pkg/client/listers/core/internalversion" - storagelisters "k8s.io/kubernetes/pkg/client/listers/storage/internalversion" - kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" ) const ( @@ -44,13 +43,12 @@ func Register(plugins *admission.Plugins) { var _ admission.Interface = &persistentVolumeClaimResize{} var _ admission.ValidationInterface = &persistentVolumeClaimResize{} -var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&persistentVolumeClaimResize{}) +var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&persistentVolumeClaimResize{}) type persistentVolumeClaimResize struct { *admission.Handler - pvLister pvlister.PersistentVolumeLister - scLister storagelisters.StorageClassLister + scLister storagev1listers.StorageClassLister } func newPlugin() *persistentVolumeClaimResize { @@ -59,21 +57,14 @@ func newPlugin() *persistentVolumeClaimResize { } } -func (pvcr *persistentVolumeClaimResize) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) { - pvcInformer := f.Core().InternalVersion().PersistentVolumes() - pvcr.pvLister = pvcInformer.Lister() - scInformer := f.Storage().InternalVersion().StorageClasses() +func (pvcr *persistentVolumeClaimResize) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { + scInformer := f.Storage().V1().StorageClasses() pvcr.scLister = scInformer.Lister() - pvcr.SetReadyFunc(func() bool { - return pvcInformer.Informer().HasSynced() && scInformer.Informer().HasSynced() - }) + pvcr.SetReadyFunc(scInformer.Informer().HasSynced) } // ValidateInitialization ensures lister is set. func (pvcr *persistentVolumeClaimResize) ValidateInitialization() error { - if pvcr.pvLister == nil { - return fmt.Errorf("missing persistent volume lister") - } if pvcr.scLister == nil { return fmt.Errorf("missing storageclass lister") } diff --git a/plugin/pkg/admission/storage/persistentvolume/resize/admission_test.go b/plugin/pkg/admission/storage/persistentvolume/resize/admission_test.go index 2f3d77140bcb6..0eed48a5c58ca 100644 --- a/plugin/pkg/admission/storage/persistentvolume/resize/admission_test.go +++ b/plugin/pkg/admission/storage/persistentvolume/resize/admission_test.go @@ -21,14 +21,14 @@ import ( "strings" "testing" + storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" + "k8s.io/client-go/informers" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/storage" - informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" "k8s.io/kubernetes/pkg/controller" ) @@ -44,7 +44,7 @@ func TestPVCResizeAdmission(t *testing.T) { goldClassName := "gold" trueVal := true falseVar := false - goldClass := &storage.StorageClass{ + goldClass := &storagev1.StorageClass{ TypeMeta: metav1.TypeMeta{ Kind: "StorageClass", }, @@ -55,7 +55,7 @@ func TestPVCResizeAdmission(t *testing.T) { AllowVolumeExpansion: &trueVal, } silverClassName := "silver" - silverClass := &storage.StorageClass{ + silverClass := &storagev1.StorageClass{ TypeMeta: metav1.TypeMeta{ Kind: "StorageClass", }, @@ -237,40 +237,16 @@ func TestPVCResizeAdmission(t *testing.T) { ctrl := newPlugin() informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) - ctrl.SetInternalKubeInformerFactory(informerFactory) + ctrl.SetExternalKubeInformerFactory(informerFactory) err := ctrl.ValidateInitialization() if err != nil { t.Fatalf("neither pv lister nor storageclass lister can be nil") } - pv1 := &api.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{Name: "volume1"}, - Spec: api.PersistentVolumeSpec{ - PersistentVolumeSource: api.PersistentVolumeSource{ - Glusterfs: &api.GlusterfsVolumeSource{ - EndpointsName: "http://localhost:8080/", - Path: "/heketi", - ReadOnly: false, - }, - }, - StorageClassName: goldClassName, - }, - } - - pvs := []*api.PersistentVolume{} - pvs = append(pvs, pv1) - - for _, pv := range pvs { - err := informerFactory.Core().InternalVersion().PersistentVolumes().Informer().GetStore().Add(pv) - if err != nil { - fmt.Println("add pv error: ", err) - } - } - - scs := []*storage.StorageClass{} + scs := []*storagev1.StorageClass{} scs = append(scs, goldClass, silverClass) for _, sc := range scs { - err := informerFactory.Storage().InternalVersion().StorageClasses().Informer().GetStore().Add(sc) + err := informerFactory.Storage().V1().StorageClasses().Informer().GetStore().Add(sc) if err != nil { fmt.Println("add storageclass error: ", err) } @@ -281,8 +257,6 @@ func TestPVCResizeAdmission(t *testing.T) { attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, nil) err := ctrl.Validate(attributes) - fmt.Println(tc.name) - fmt.Println(err) if !tc.checkError(err) { t.Errorf("%v: unexpected err: %v", tc.name, err) } diff --git a/plugin/pkg/auth/authenticator/OWNERS b/plugin/pkg/auth/authenticator/OWNERS new file mode 100644 index 0000000000000..c607d2aa8c5fe --- /dev/null +++ b/plugin/pkg/auth/authenticator/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers +reviewers: +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/plugin/pkg/auth/authenticator/token/bootstrap/BUILD b/plugin/pkg/auth/authenticator/token/bootstrap/BUILD index 5ef48a9f56bcc..15f6da5796943 100644 --- a/plugin/pkg/auth/authenticator/token/bootstrap/BUILD +++ b/plugin/pkg/auth/authenticator/token/bootstrap/BUILD @@ -11,7 +11,7 @@ go_test( srcs = ["bootstrap_test.go"], embed = [":go_default_library"], deps = [ - "//pkg/apis/core:go_default_library", + "//staging/src/k8s.io/api/core/v1: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/labels:go_default_library", @@ -26,12 +26,12 @@ go_library( srcs = ["bootstrap.go"], importpath = "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap", deps = [ - "//pkg/apis/core:go_default_library", - "//pkg/client/listers/core/internalversion:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", + "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library", "//vendor/github.com/golang/glog:go_default_library", diff --git a/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap.go b/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap.go index 163d758c4523a..93b4e1cddd82e 100644 --- a/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap.go +++ b/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap.go @@ -29,14 +29,14 @@ import ( "github.com/golang/glog" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/user" + corev1listers "k8s.io/client-go/listers/core/v1" bootstrapapi "k8s.io/cluster-bootstrap/token/api" bootstraputil "k8s.io/cluster-bootstrap/token/util" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/client/listers/core/internalversion" ) // TODO: A few methods in this package is copied from other sources. Either @@ -46,13 +46,13 @@ import ( // NewTokenAuthenticator initializes a bootstrap token authenticator. // // Lister is expected to be for the "kube-system" namespace. -func NewTokenAuthenticator(lister internalversion.SecretNamespaceLister) *TokenAuthenticator { +func NewTokenAuthenticator(lister corev1listers.SecretNamespaceLister) *TokenAuthenticator { return &TokenAuthenticator{lister} } // TokenAuthenticator authenticates bootstrap tokens from secrets in the API server. type TokenAuthenticator struct { - lister internalversion.SecretNamespaceLister + lister corev1listers.SecretNamespaceLister } // tokenErrorf prints a error message for a secret that has matched a bearer @@ -60,7 +60,7 @@ type TokenAuthenticator struct { // // tokenErrorf(secret, "has invalid value for key %s", key) // -func tokenErrorf(s *api.Secret, format string, i ...interface{}) { +func tokenErrorf(s *corev1.Secret, format string, i ...interface{}) { format = fmt.Sprintf("Bootstrap secret %s/%s matching bearer token ", s.Namespace, s.Name) + format glog.V(3).Infof(format, i...) } @@ -155,7 +155,7 @@ func (t *TokenAuthenticator) AuthenticateToken(ctx context.Context, token string } // Copied from k8s.io/cluster-bootstrap/token/api -func getSecretString(secret *api.Secret, key string) string { +func getSecretString(secret *corev1.Secret, key string) string { data, ok := secret.Data[key] if !ok { return "" @@ -165,7 +165,7 @@ func getSecretString(secret *api.Secret, key string) string { } // Copied from k8s.io/cluster-bootstrap/token/api -func isSecretExpired(secret *api.Secret) bool { +func isSecretExpired(secret *corev1.Secret) bool { expiration := getSecretString(secret, bootstrapapi.BootstrapTokenExpirationKey) if len(expiration) > 0 { expTime, err2 := time.Parse(time.RFC3339, expiration) @@ -205,7 +205,7 @@ func parseToken(s string) (string, string, error) { // getGroups loads and validates the bootstrapapi.BootstrapTokenExtraGroupsKey // key from the bootstrap token secret, returning a list of group names or an // error if any of the group names are invalid. -func getGroups(secret *api.Secret) ([]string, error) { +func getGroups(secret *corev1.Secret) ([]string, error) { // always include the default group groups := sets.NewString(bootstrapapi.BootstrapDefaultGroup) diff --git a/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap_test.go b/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap_test.go index ae408e8a9ded8..0613e1587a4d5 100644 --- a/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap_test.go +++ b/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap_test.go @@ -21,24 +21,24 @@ import ( "reflect" "testing" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/authentication/user" bootstrapapi "k8s.io/cluster-bootstrap/token/api" - api "k8s.io/kubernetes/pkg/apis/core" ) type lister struct { - secrets []*api.Secret + secrets []*corev1.Secret } -func (l *lister) List(selector labels.Selector) (ret []*api.Secret, err error) { +func (l *lister) List(selector labels.Selector) (ret []*corev1.Secret, err error) { return l.secrets, nil } -func (l *lister) Get(name string) (*api.Secret, error) { +func (l *lister) Get(name string) (*corev1.Secret, error) { for _, s := range l.secrets { if s.Name == name { return s, nil @@ -58,7 +58,7 @@ func TestTokenAuthenticator(t *testing.T) { tests := []struct { name string - secrets []*api.Secret + secrets []*corev1.Secret token string wantNotFound bool @@ -66,7 +66,7 @@ func TestTokenAuthenticator(t *testing.T) { }{ { name: "valid token", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID, @@ -87,7 +87,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "valid token with extra group", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID, @@ -109,7 +109,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "invalid group", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID, @@ -128,7 +128,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "invalid secret name", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: "bad-name", @@ -146,7 +146,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "no usage", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID, @@ -163,7 +163,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "wrong token", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID, @@ -181,7 +181,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "deleted token", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID, @@ -200,7 +200,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "expired token", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID, @@ -219,7 +219,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "not expired token", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID, @@ -241,7 +241,7 @@ func TestTokenAuthenticator(t *testing.T) { }, { name: "token id wrong length", - secrets: []*api.Secret{ + secrets: []*corev1.Secret{ { ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.BootstrapTokenSecretPrefix + "foo", @@ -292,13 +292,13 @@ func TestTokenAuthenticator(t *testing.T) { func TestGetGroups(t *testing.T) { tests := []struct { name string - secret *api.Secret + secret *corev1.Secret expectResult []string expectError bool }{ { name: "not set", - secret: &api.Secret{ + secret: &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{Name: "test"}, Data: map[string][]byte{}, }, @@ -306,7 +306,7 @@ func TestGetGroups(t *testing.T) { }, { name: "set to empty value", - secret: &api.Secret{ + secret: &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{Name: "test"}, Data: map[string][]byte{ bootstrapapi.BootstrapTokenExtraGroupsKey: []byte(""), @@ -316,7 +316,7 @@ func TestGetGroups(t *testing.T) { }, { name: "invalid prefix", - secret: &api.Secret{ + secret: &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{Name: "test"}, Data: map[string][]byte{ bootstrapapi.BootstrapTokenExtraGroupsKey: []byte("foo"), @@ -326,7 +326,7 @@ func TestGetGroups(t *testing.T) { }, { name: "valid", - secret: &api.Secret{ + secret: &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{Name: "test"}, Data: map[string][]byte{ bootstrapapi.BootstrapTokenExtraGroupsKey: []byte("system:bootstrappers:foo,system:bootstrappers:bar,system:bootstrappers:bar"), diff --git a/plugin/pkg/auth/authorizer/OWNERS b/plugin/pkg/auth/authorizer/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/plugin/pkg/auth/authorizer/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/plugin/pkg/auth/authorizer/node/OWNERS b/plugin/pkg/auth/authorizer/node/OWNERS index 00846326417bb..5a7794867cfaa 100644 --- a/plugin/pkg/auth/authorizer/node/OWNERS +++ b/plugin/pkg/auth/authorizer/node/OWNERS @@ -1,8 +1,7 @@ approvers: -- tallclair -- liggitt -- deads2k +- sig-auth-node-isolation-approvers reviewers: -- tallclair -- liggitt -- deads2k +- sig-auth-node-isolation-reviewers +labels: +- sig/auth + diff --git a/plugin/pkg/auth/authorizer/rbac/rbac.go b/plugin/pkg/auth/authorizer/rbac/rbac.go index 1701bbc3176ff..a0f173c393bfe 100644 --- a/plugin/pkg/auth/authorizer/rbac/rbac.go +++ b/plugin/pkg/auth/authorizer/rbac/rbac.go @@ -121,8 +121,6 @@ func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (aut reason := "" if len(ruleCheckingVisitor.errors) > 0 { reason = fmt.Sprintf("RBAC: %v", utilerrors.NewAggregate(ruleCheckingVisitor.errors)) - } else { - reason = "no RBAC policy matched" } return authorizer.DecisionNoOpinion, reason, nil } diff --git a/staging/src/k8s.io/api/Godeps/Godeps.json b/staging/src/k8s.io/api/Godeps/Godeps.json index a0dad5a5eea2d..36910c396c336 100644 --- a/staging/src/k8s.io/api/Godeps/Godeps.json +++ b/staging/src/k8s.io/api/Godeps/Godeps.json @@ -64,19 +64,19 @@ }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/text/secure/bidirule", diff --git a/staging/src/k8s.io/api/OWNERS b/staging/src/k8s.io/api/OWNERS index 7b9fd5dbf8a52..67952cace2915 100644 --- a/staging/src/k8s.io/api/OWNERS +++ b/staging/src/k8s.io/api/OWNERS @@ -2,54 +2,9 @@ options: no_parent_owners: true approvers: -- erictune -- lavalamp -- smarterclayton -- thockin -- liggitt -# - bgrant0607 # manual escalations only +- api-approvers reviewers: -- brendandburns -- caesarxuchao -- davidopp -- dchen1107 -- deads2k -- derekwaynecarr -- dims -- eparis -- erictune -- errordeveloper -- feiskyer -- gmarek -- janetkuo -- jbeda -- jsafrane -- jszczepkowski -- justinsb -- krousey -- lavalamp -- liggitt -- luxas -- madhusudancs -- mikedanese -- mwielgus -- ncdc -- nikhiljindal -- piosz -- pmorie -- pwittrock -- roberthbailey -- rootfs -- saad-ali -- smarterclayton -- soltysh -- sttts -- tallclair -- thockin -- vishh -- wojtek-t -- yifan-gu -- yujuhong -- zmerlynn +- api-reviewers labels: - sig/architecture +- kind/api-change diff --git a/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.proto b/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.proto index e17b559689d9e..98e9a571a2cf6 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.proto +++ b/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.proto @@ -88,7 +88,7 @@ message Rule { repeated string apiVersions = 2; // Resources is a list of resources this rule applies to. - // + // // For example: // 'pods' means pods. // 'pods/log' means the log subresource of pods. @@ -96,10 +96,10 @@ message Rule { // 'pods/*' means all subresources of pods. // '*/scale' means all scale subresources. // '*/*' means all resources and their subresources. - // + // // If wildcard is present, the validation rule will ensure resources do not // overlap with each other. - // + // // Depending on the enclosing object, subresources might not be allowed. // Required. repeated string resources = 3; diff --git a/staging/src/k8s.io/api/admissionregistration/v1beta1/generated.proto b/staging/src/k8s.io/api/admissionregistration/v1beta1/generated.proto index 2a23a370916b4..1c40ae530dea2 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/admissionregistration/v1beta1/generated.proto @@ -66,7 +66,7 @@ message Rule { repeated string apiVersions = 2; // Resources is a list of resources this rule applies to. - // + // // For example: // 'pods' means pods. // 'pods/log' means the log subresource of pods. @@ -74,10 +74,10 @@ message Rule { // 'pods/*' means all subresources of pods. // '*/scale' means all scale subresources. // '*/*' means all resources and their subresources. - // + // // If wildcard is present, the validation rule will ensure resources do not // overlap with each other. - // + // // Depending on the enclosing object, subresources might not be allowed. // Required. repeated string resources = 3; @@ -168,7 +168,7 @@ message Webhook { // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, // it never skips the webhook. - // + // // For example, to run the webhook on any objects whose namespace is not // associated with "runlevel" of "0" or "1"; you will set the selector as // follows: @@ -184,7 +184,7 @@ message Webhook { // } // ] // } - // + // // If instead you want to only run the webhook on any objects whose // namespace is associated with the "environment" of "prod" or "staging"; // you will set the selector as follows: @@ -200,11 +200,11 @@ message Webhook { // } // ] // } - // + // // See // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // for more examples of label selectors. - // + // // Default to the empty LabelSelector, which matches everything. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5; @@ -223,41 +223,41 @@ message Webhook { // connection with the webhook message WebhookClientConfig { // `url` gives the location of the webhook, in standard URL form - // (`[scheme://]host:port/path`). Exactly one of `url` or `service` + // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. - // + // // The `host` should not refer to a service running in the cluster; use // the `service` field instead. The host might be resolved via external // DNS in some apiservers (e.g., `kube-apiserver` cannot resolve // in-cluster DNS as that would be a layering violation). `host` may // also be an IP address. - // + // // Please note that using `localhost` or `127.0.0.1` as a `host` is // risky unless you take great care to run this webhook on all hosts // which run an apiserver which might need to make calls to this // webhook. Such installs are likely to be non-portable, i.e., not easy // to turn up in a new cluster. - // + // // The scheme must be "https"; the URL must begin with "https://". - // + // // A path is optional, and if present may be any string permissible in // a URL. You may use the path to pass an arbitrary string to the // webhook, for example, a cluster identifier. - // + // // Attempting to use a user or basic auth e.g. "user:password@" is not // allowed. Fragments ("#...") and query parameters ("?...") are not // allowed, either. - // + // // +optional optional string url = 3; // `service` is a reference to the service for this webhook. Either // `service` or `url` must be specified. - // + // // If the webhook is running within the cluster, then you should use `service`. - // + // // Port 443 will be used if it is open, otherwise it is an error. - // + // // +optional optional ServiceReference service = 1; diff --git a/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go b/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go index 1703ac71340bd..49d94ec0eb758 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go +++ b/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go @@ -246,7 +246,7 @@ const ( // connection with the webhook type WebhookClientConfig struct { // `url` gives the location of the webhook, in standard URL form - // (`[scheme://]host:port/path`). Exactly one of `url` or `service` + // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // // The `host` should not refer to a service running in the cluster; use diff --git a/staging/src/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go index 12c209b0b8a15..e97628aab7cf6 100644 --- a/staging/src/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go @@ -114,7 +114,7 @@ func (Webhook) SwaggerDoc() map[string]string { var map_WebhookClientConfig = map[string]string{ "": "WebhookClientConfig contains the information to make a TLS connection with the webhook", - "url": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", + "url": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", "service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.\n\nPort 443 will be used if it is open, otherwise it is an error.", "caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.", } diff --git a/staging/src/k8s.io/api/apps/v1/generated.proto b/staging/src/k8s.io/api/apps/v1/generated.proto index c8a957ac68086..fea81922f3b6b 100644 --- a/staging/src/k8s.io/api/apps/v1/generated.proto +++ b/staging/src/k8s.io/api/apps/v1/generated.proto @@ -280,6 +280,7 @@ message DeploymentSpec { // The deployment strategy to use to replace existing pods with new ones. // +optional + // +patchStrategy=retainKeys optional DeploymentStrategy strategy = 4; // Minimum number of seconds for which a newly created pod should be ready diff --git a/staging/src/k8s.io/api/apps/v1/types.go b/staging/src/k8s.io/api/apps/v1/types.go index 4431ca2c31709..68ac55bf17ab3 100644 --- a/staging/src/k8s.io/api/apps/v1/types.go +++ b/staging/src/k8s.io/api/apps/v1/types.go @@ -32,6 +32,8 @@ const ( ) // +genclient +// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/api/autoscaling/v1.Scale +// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/autoscaling/v1.Scale,result=k8s.io/api/autoscaling/v1.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // StatefulSet represents a set of pods with consistent identities. @@ -244,6 +246,8 @@ type StatefulSetList struct { } // +genclient +// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/api/autoscaling/v1.Scale +// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/autoscaling/v1.Scale,result=k8s.io/api/autoscaling/v1.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Deployment enables declarative updates for Pods and ReplicaSets. @@ -279,7 +283,8 @@ type DeploymentSpec struct { // The deployment strategy to use to replace existing pods with new ones. // +optional - Strategy DeploymentStrategy `json:"strategy,omitempty" protobuf:"bytes,4,opt,name=strategy"` + // +patchStrategy=retainKeys + Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" protobuf:"bytes,4,opt,name=strategy"` // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. @@ -653,6 +658,8 @@ type DaemonSetList struct { } // +genclient +// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/api/autoscaling/v1.Scale +// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/autoscaling/v1.Scale,result=k8s.io/api/autoscaling/v1.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ReplicaSet ensures that a specified number of pod replicas are running at any given time. diff --git a/staging/src/k8s.io/api/apps/v1beta1/generated.proto b/staging/src/k8s.io/api/apps/v1beta1/generated.proto index 6f41f06bcccef..f87f39fe94e94 100644 --- a/staging/src/k8s.io/api/apps/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/apps/v1beta1/generated.proto @@ -143,6 +143,7 @@ message DeploymentSpec { // The deployment strategy to use to replace existing pods with new ones. // +optional + // +patchStrategy=retainKeys optional DeploymentStrategy strategy = 4; // Minimum number of seconds for which a newly created pod should be ready diff --git a/staging/src/k8s.io/api/apps/v1beta1/types.go b/staging/src/k8s.io/api/apps/v1beta1/types.go index d462604d79eaa..326902fd0f860 100644 --- a/staging/src/k8s.io/api/apps/v1beta1/types.go +++ b/staging/src/k8s.io/api/apps/v1beta1/types.go @@ -55,8 +55,6 @@ type ScaleStatus struct { TargetSelector string `json:"targetSelector,omitempty" protobuf:"bytes,3,opt,name=targetSelector"` } -// +genclient -// +genclient:noVerbs // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Scale represents a scaling request for a resource. @@ -323,7 +321,8 @@ type DeploymentSpec struct { // The deployment strategy to use to replace existing pods with new ones. // +optional - Strategy DeploymentStrategy `json:"strategy,omitempty" protobuf:"bytes,4,opt,name=strategy"` + // +patchStrategy=retainKeys + Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" protobuf:"bytes,4,opt,name=strategy"` // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. diff --git a/staging/src/k8s.io/api/apps/v1beta2/generated.proto b/staging/src/k8s.io/api/apps/v1beta2/generated.proto index cc3656d284e95..5d11cbe8d810d 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/generated.proto +++ b/staging/src/k8s.io/api/apps/v1beta2/generated.proto @@ -286,6 +286,7 @@ message DeploymentSpec { // The deployment strategy to use to replace existing pods with new ones. // +optional + // +patchStrategy=retainKeys optional DeploymentStrategy strategy = 4; // Minimum number of seconds for which a newly created pod should be ready diff --git a/staging/src/k8s.io/api/apps/v1beta2/types.go b/staging/src/k8s.io/api/apps/v1beta2/types.go index e5525222a1ec1..e75589adc542a 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/types.go +++ b/staging/src/k8s.io/api/apps/v1beta2/types.go @@ -57,8 +57,6 @@ type ScaleStatus struct { TargetSelector string `json:"targetSelector,omitempty" protobuf:"bytes,3,opt,name=targetSelector"` } -// +genclient -// +genclient:noVerbs // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Scale represents a scaling request for a resource. @@ -331,7 +329,8 @@ type DeploymentSpec struct { // The deployment strategy to use to replace existing pods with new ones. // +optional - Strategy DeploymentStrategy `json:"strategy,omitempty" protobuf:"bytes,4,opt,name=strategy"` + // +patchStrategy=retainKeys + Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" protobuf:"bytes,4,opt,name=strategy"` // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. diff --git a/staging/src/k8s.io/api/auditregistration/OWNERS b/staging/src/k8s.io/api/auditregistration/OWNERS index df96f16bf05b0..c342e5e0cb71a 100644 --- a/staging/src/k8s.io/api/auditregistration/OWNERS +++ b/staging/src/k8s.io/api/auditregistration/OWNERS @@ -1,5 +1,6 @@ reviewers: -- lavalamp -- sttts -- tallclair -- pbarker \ No newline at end of file +- sig-auth-audit-approvers +- sig-auth-audit-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/api/auditregistration/v1alpha1/generated.proto b/staging/src/k8s.io/api/auditregistration/v1alpha1/generated.proto index 1b715f062e5d5..70801a6c515dc 100644 --- a/staging/src/k8s.io/api/auditregistration/v1alpha1/generated.proto +++ b/staging/src/k8s.io/api/auditregistration/v1alpha1/generated.proto @@ -99,41 +99,41 @@ message Webhook { // WebhookClientConfig contains the information to make a connection with the webhook message WebhookClientConfig { // `url` gives the location of the webhook, in standard URL form - // (`[scheme://]host:port/path`). Exactly one of `url` or `service` + // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. - // + // // The `host` should not refer to a service running in the cluster; use // the `service` field instead. The host might be resolved via external // DNS in some apiservers (e.g., `kube-apiserver` cannot resolve // in-cluster DNS as that would be a layering violation). `host` may // also be an IP address. - // + // // Please note that using `localhost` or `127.0.0.1` as a `host` is // risky unless you take great care to run this webhook on all hosts // which run an apiserver which might need to make calls to this // webhook. Such installs are likely to be non-portable, i.e., not easy // to turn up in a new cluster. - // + // // The scheme must be "https"; the URL must begin with "https://". - // + // // A path is optional, and if present may be any string permissible in // a URL. You may use the path to pass an arbitrary string to the // webhook, for example, a cluster identifier. - // + // // Attempting to use a user or basic auth e.g. "user:password@" is not // allowed. Fragments ("#...") and query parameters ("?...") are not // allowed, either. - // + // // +optional optional string url = 1; // `service` is a reference to the service for this webhook. Either // `service` or `url` must be specified. - // + // // If the webhook is running within the cluster, then you should use `service`. - // + // // Port 443 will be used if it is open, otherwise it is an error. - // + // // +optional optional ServiceReference service = 2; diff --git a/staging/src/k8s.io/api/auditregistration/v1alpha1/types.go b/staging/src/k8s.io/api/auditregistration/v1alpha1/types.go index a27d559a4e013..af31cfe275a2a 100644 --- a/staging/src/k8s.io/api/auditregistration/v1alpha1/types.go +++ b/staging/src/k8s.io/api/auditregistration/v1alpha1/types.go @@ -133,7 +133,7 @@ type WebhookThrottleConfig struct { // WebhookClientConfig contains the information to make a connection with the webhook type WebhookClientConfig struct { // `url` gives the location of the webhook, in standard URL form - // (`[scheme://]host:port/path`). Exactly one of `url` or `service` + // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // // The `host` should not refer to a service running in the cluster; use diff --git a/staging/src/k8s.io/api/auditregistration/v1alpha1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/auditregistration/v1alpha1/types_swagger_doc_generated.go index 0fe9133326e6c..edd608f3b26e8 100644 --- a/staging/src/k8s.io/api/auditregistration/v1alpha1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/auditregistration/v1alpha1/types_swagger_doc_generated.go @@ -88,7 +88,7 @@ func (Webhook) SwaggerDoc() map[string]string { var map_WebhookClientConfig = map[string]string{ "": "WebhookClientConfig contains the information to make a connection with the webhook", - "url": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", + "url": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", "service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.\n\nPort 443 will be used if it is open, otherwise it is an error.", "caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.", } diff --git a/staging/src/k8s.io/api/authentication/OWNERS b/staging/src/k8s.io/api/authentication/OWNERS index 2bdfd0ce5bc59..1b888f0b8036d 100755 --- a/staging/src/k8s.io/api/authentication/OWNERS +++ b/staging/src/k8s.io/api/authentication/OWNERS @@ -1,9 +1,6 @@ reviewers: -- liggitt -- lavalamp -- wojtek-t -- deads2k -- sttts -- mbohlool -- jianhuiz -- enj +- sig-auth-authenticators-approvers +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/api/authorization/OWNERS b/staging/src/k8s.io/api/authorization/OWNERS index c1613fc2e0263..ff4a7f4bf9ad0 100755 --- a/staging/src/k8s.io/api/authorization/OWNERS +++ b/staging/src/k8s.io/api/authorization/OWNERS @@ -1,17 +1,7 @@ +# approval on api packages bubbles to api-approvers reviewers: -- thockin -- lavalamp -- smarterclayton -- wojtek-t -- deads2k -- liggitt -- nikhiljindal -- erictune -- sttts -- ncdc -- dims -- mml -- mbohlool -- david-mcmahon -- jianhuiz -- enj +- sig-auth-authorizers-approvers +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/api/core/v1/generated.proto b/staging/src/k8s.io/api/core/v1/generated.proto index fa32f76f7bdd6..c76482ffbdbd1 100644 --- a/staging/src/k8s.io/api/core/v1/generated.proto +++ b/staging/src/k8s.io/api/core/v1/generated.proto @@ -31,7 +31,7 @@ import "k8s.io/apimachinery/pkg/util/intstr/generated.proto"; option go_package = "v1"; // Represents a Persistent Disk resource in AWS. -// +// // An AWS EBS disk must exist before mounting to a container. The disk // must also be in the same AWS zone as the kubelet. An AWS EBS disk // can only be mounted as read/write once. AWS EBS volumes support @@ -436,7 +436,7 @@ message ConfigMap { // ConfigMapEnvSource selects a ConfigMap to populate the environment // variables with. -// +// // The contents of the target ConfigMap's Data field will represent the // key-value pairs as environment variables. message ConfigMapEnvSource { @@ -497,7 +497,7 @@ message ConfigMapNodeConfigSource { } // Adapts a ConfigMap into a projected volume. -// +// // The contents of the target ConfigMap's Data field will be presented in a // projected volume as files using the keys in the Data field as the file names, // unless the items element is populated with specific mappings of keys to paths. @@ -522,7 +522,7 @@ message ConfigMapProjection { } // Adapts a ConfigMap into a volume. -// +// // The contents of the target ConfigMap's Data field will be presented in a // volume as files using the keys in the Data field as the file names, unless // the items element is populated with specific mappings of keys to paths. @@ -606,6 +606,9 @@ message Container { // +optional // +patchMergeKey=containerPort // +patchStrategy=merge + // +listType=map + // +listMapKey=containerPort + // +listMapKey=protocol repeated ContainerPort ports = 6; // List of sources to populate environment variables in the container. @@ -1314,7 +1317,7 @@ message FlockerVolumeSource { } // Represents a Persistent Disk resource in Google Compute Engine. -// +// // A GCE PD must exist before mounting to a container. The disk must // also be in the same GCE project and zone as the kubelet. A GCE PD // can only be mounted as read/write once or read-only many times. GCE @@ -1350,7 +1353,7 @@ message GCEPersistentDiskVolumeSource { // Represents a volume that is populated with the contents of a git repository. // Git repo volumes do not support ownership management. // Git repo volumes support SELinux relabeling. -// +// // DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an // EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir // into the Pod's container. @@ -2899,11 +2902,11 @@ message PodSecurityContext { // A special supplemental group that applies to all containers in a pod. // Some volume types allow the Kubelet to change the ownership of that volume // to be owned by the pod: - // + // // 1. The owning GID will be the FSGroup // 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) // 3. The permission bits are OR'd with rw-rw---- - // + // // If unset, the Kubelet will not modify the ownership and permissions of any volume. // +optional optional int64 fsGroup = 5; @@ -3141,7 +3144,7 @@ message PodStatus { // The conditions array, the reason and message fields, and the individual container status // arrays contain more detail about the pod's status. // There are five possible phase values: - // + // // Pending: The pod has been accepted by the Kubernetes system, but one or more of the // container images has not been created. This includes time before being scheduled as // well as time spent downloading images over the network, which could take a while. @@ -3153,7 +3156,7 @@ message PodStatus { // by the system. // Unknown: For some reason the state of the pod could not be obtained, typically due to an // error in communicating with the host of the pod. - // + // // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase // +optional optional string phase = 1; @@ -3884,7 +3887,7 @@ message Secret { // SecretEnvSource selects a Secret to populate the environment // variables with. -// +// // The contents of the target Secret's Data field will represent the // key-value pairs as environment variables. message SecretEnvSource { @@ -3922,7 +3925,7 @@ message SecretList { } // Adapts a secret into a projected volume. -// +// // The contents of the target Secret's Data field will be presented in a // projected volume as files using the keys in the Data field as the file names. // Note that this is identical to a secret volume source without the default @@ -3958,7 +3961,7 @@ message SecretReference { } // Adapts a Secret into a volume. -// +// // The contents of the target Secret's Data field will be presented in a volume // as files using the keys in the Data field as the file names. // Secret volumes support ownership management and SELinux relabeling. diff --git a/staging/src/k8s.io/api/core/v1/types.go b/staging/src/k8s.io/api/core/v1/types.go index 475e9d0137b6b..67c67f849c84c 100644 --- a/staging/src/k8s.io/api/core/v1/types.go +++ b/staging/src/k8s.io/api/core/v1/types.go @@ -2060,6 +2060,9 @@ type Container struct { // +optional // +patchMergeKey=containerPort // +patchStrategy=merge + // +listType=map + // +listMapKey=containerPort + // +listMapKey=protocol Ports []ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` // List of sources to populate environment variables in the container. // The keys defined within a source must be a C_IDENTIFIER. All invalid keys @@ -3282,8 +3285,8 @@ type ReplicationControllerCondition struct { } // +genclient -// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/api/extensions/v1beta1.Scale -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/extensions/v1beta1.Scale,result=k8s.io/api/extensions/v1beta1.Scale +// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/api/autoscaling/v1.Scale +// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/autoscaling/v1.Scale,result=k8s.io/api/autoscaling/v1.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ReplicationController represents the configuration of a replication controller. @@ -4996,6 +4999,10 @@ const ( TLSCertKey = "tls.crt" // TLSPrivateKeyKey is the key for the private key field in a TLS secret. TLSPrivateKeyKey = "tls.key" + // SecretTypeBootstrapToken is used during the automated bootstrap process (first + // implemented by kubeadm). It stores tokens that are used to sign well known + // ConfigMaps. They are used for authn. + SecretTypeBootstrapToken SecretType = "bootstrap.kubernetes.io/token" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/staging/src/k8s.io/api/extensions/v1beta1/BUILD b/staging/src/k8s.io/api/extensions/v1beta1/BUILD index 57da4b778f9dd..ce7106a2dfc12 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/BUILD +++ b/staging/src/k8s.io/api/extensions/v1beta1/BUILD @@ -20,7 +20,6 @@ go_library( deps = [ "//staging/src/k8s.io/api/apps/v1beta1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/staging/src/k8s.io/api/extensions/v1beta1/generated.pb.go b/staging/src/k8s.io/api/extensions/v1beta1/generated.pb.go index 7bf49f3184dc9..a0dfa96620dba 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/generated.pb.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/generated.pb.go @@ -26,10 +26,6 @@ limitations under the License. It has these top-level messages: AllowedFlexVolume AllowedHostPath - CustomMetricCurrentStatus - CustomMetricCurrentStatusList - CustomMetricTarget - CustomMetricTargetList DaemonSet DaemonSetCondition DaemonSetList @@ -91,7 +87,6 @@ import fmt "fmt" import math "math" import k8s_io_api_core_v1 "k8s.io/api/core/v1" - import k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" import k8s_io_apimachinery_pkg_util_intstr "k8s.io/apimachinery/pkg/util/intstr" @@ -122,261 +117,235 @@ func (m *AllowedHostPath) Reset() { *m = AllowedHostPath{} } func (*AllowedHostPath) ProtoMessage() {} func (*AllowedHostPath) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} } -func (m *CustomMetricCurrentStatus) Reset() { *m = CustomMetricCurrentStatus{} } -func (*CustomMetricCurrentStatus) ProtoMessage() {} -func (*CustomMetricCurrentStatus) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{2} -} - -func (m *CustomMetricCurrentStatusList) Reset() { *m = CustomMetricCurrentStatusList{} } -func (*CustomMetricCurrentStatusList) ProtoMessage() {} -func (*CustomMetricCurrentStatusList) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{3} -} - -func (m *CustomMetricTarget) Reset() { *m = CustomMetricTarget{} } -func (*CustomMetricTarget) ProtoMessage() {} -func (*CustomMetricTarget) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{4} } - -func (m *CustomMetricTargetList) Reset() { *m = CustomMetricTargetList{} } -func (*CustomMetricTargetList) ProtoMessage() {} -func (*CustomMetricTargetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{5} } - func (m *DaemonSet) Reset() { *m = DaemonSet{} } func (*DaemonSet) ProtoMessage() {} -func (*DaemonSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{6} } +func (*DaemonSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} } func (m *DaemonSetCondition) Reset() { *m = DaemonSetCondition{} } func (*DaemonSetCondition) ProtoMessage() {} -func (*DaemonSetCondition) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{7} } +func (*DaemonSetCondition) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{3} } func (m *DaemonSetList) Reset() { *m = DaemonSetList{} } func (*DaemonSetList) ProtoMessage() {} -func (*DaemonSetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{8} } +func (*DaemonSetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{4} } func (m *DaemonSetSpec) Reset() { *m = DaemonSetSpec{} } func (*DaemonSetSpec) ProtoMessage() {} -func (*DaemonSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{9} } +func (*DaemonSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{5} } func (m *DaemonSetStatus) Reset() { *m = DaemonSetStatus{} } func (*DaemonSetStatus) ProtoMessage() {} -func (*DaemonSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{10} } +func (*DaemonSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{6} } -func (m *DaemonSetUpdateStrategy) Reset() { *m = DaemonSetUpdateStrategy{} } -func (*DaemonSetUpdateStrategy) ProtoMessage() {} -func (*DaemonSetUpdateStrategy) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{11} -} +func (m *DaemonSetUpdateStrategy) Reset() { *m = DaemonSetUpdateStrategy{} } +func (*DaemonSetUpdateStrategy) ProtoMessage() {} +func (*DaemonSetUpdateStrategy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{7} } func (m *Deployment) Reset() { *m = Deployment{} } func (*Deployment) ProtoMessage() {} -func (*Deployment) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} } +func (*Deployment) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{8} } func (m *DeploymentCondition) Reset() { *m = DeploymentCondition{} } func (*DeploymentCondition) ProtoMessage() {} -func (*DeploymentCondition) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{13} } +func (*DeploymentCondition) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{9} } func (m *DeploymentList) Reset() { *m = DeploymentList{} } func (*DeploymentList) ProtoMessage() {} -func (*DeploymentList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{14} } +func (*DeploymentList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{10} } func (m *DeploymentRollback) Reset() { *m = DeploymentRollback{} } func (*DeploymentRollback) ProtoMessage() {} -func (*DeploymentRollback) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{15} } +func (*DeploymentRollback) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{11} } func (m *DeploymentSpec) Reset() { *m = DeploymentSpec{} } func (*DeploymentSpec) ProtoMessage() {} -func (*DeploymentSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{16} } +func (*DeploymentSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} } func (m *DeploymentStatus) Reset() { *m = DeploymentStatus{} } func (*DeploymentStatus) ProtoMessage() {} -func (*DeploymentStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{17} } +func (*DeploymentStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{13} } func (m *DeploymentStrategy) Reset() { *m = DeploymentStrategy{} } func (*DeploymentStrategy) ProtoMessage() {} -func (*DeploymentStrategy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{18} } +func (*DeploymentStrategy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{14} } func (m *FSGroupStrategyOptions) Reset() { *m = FSGroupStrategyOptions{} } func (*FSGroupStrategyOptions) ProtoMessage() {} -func (*FSGroupStrategyOptions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{19} } +func (*FSGroupStrategyOptions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{15} } func (m *HTTPIngressPath) Reset() { *m = HTTPIngressPath{} } func (*HTTPIngressPath) ProtoMessage() {} -func (*HTTPIngressPath) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{20} } +func (*HTTPIngressPath) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{16} } func (m *HTTPIngressRuleValue) Reset() { *m = HTTPIngressRuleValue{} } func (*HTTPIngressRuleValue) ProtoMessage() {} -func (*HTTPIngressRuleValue) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{21} } +func (*HTTPIngressRuleValue) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{17} } func (m *HostPortRange) Reset() { *m = HostPortRange{} } func (*HostPortRange) ProtoMessage() {} -func (*HostPortRange) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{22} } +func (*HostPortRange) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{18} } func (m *IDRange) Reset() { *m = IDRange{} } func (*IDRange) ProtoMessage() {} -func (*IDRange) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{23} } +func (*IDRange) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{19} } func (m *IPBlock) Reset() { *m = IPBlock{} } func (*IPBlock) ProtoMessage() {} -func (*IPBlock) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{24} } +func (*IPBlock) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{20} } func (m *Ingress) Reset() { *m = Ingress{} } func (*Ingress) ProtoMessage() {} -func (*Ingress) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{25} } +func (*Ingress) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{21} } func (m *IngressBackend) Reset() { *m = IngressBackend{} } func (*IngressBackend) ProtoMessage() {} -func (*IngressBackend) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{26} } +func (*IngressBackend) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{22} } func (m *IngressList) Reset() { *m = IngressList{} } func (*IngressList) ProtoMessage() {} -func (*IngressList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{27} } +func (*IngressList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{23} } func (m *IngressRule) Reset() { *m = IngressRule{} } func (*IngressRule) ProtoMessage() {} -func (*IngressRule) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{28} } +func (*IngressRule) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{24} } func (m *IngressRuleValue) Reset() { *m = IngressRuleValue{} } func (*IngressRuleValue) ProtoMessage() {} -func (*IngressRuleValue) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{29} } +func (*IngressRuleValue) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{25} } func (m *IngressSpec) Reset() { *m = IngressSpec{} } func (*IngressSpec) ProtoMessage() {} -func (*IngressSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{30} } +func (*IngressSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{26} } func (m *IngressStatus) Reset() { *m = IngressStatus{} } func (*IngressStatus) ProtoMessage() {} -func (*IngressStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{31} } +func (*IngressStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{27} } func (m *IngressTLS) Reset() { *m = IngressTLS{} } func (*IngressTLS) ProtoMessage() {} -func (*IngressTLS) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{32} } +func (*IngressTLS) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{28} } func (m *NetworkPolicy) Reset() { *m = NetworkPolicy{} } func (*NetworkPolicy) ProtoMessage() {} -func (*NetworkPolicy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{33} } +func (*NetworkPolicy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{29} } func (m *NetworkPolicyEgressRule) Reset() { *m = NetworkPolicyEgressRule{} } func (*NetworkPolicyEgressRule) ProtoMessage() {} func (*NetworkPolicyEgressRule) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{34} + return fileDescriptorGenerated, []int{30} } func (m *NetworkPolicyIngressRule) Reset() { *m = NetworkPolicyIngressRule{} } func (*NetworkPolicyIngressRule) ProtoMessage() {} func (*NetworkPolicyIngressRule) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{35} + return fileDescriptorGenerated, []int{31} } func (m *NetworkPolicyList) Reset() { *m = NetworkPolicyList{} } func (*NetworkPolicyList) ProtoMessage() {} -func (*NetworkPolicyList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{36} } +func (*NetworkPolicyList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{32} } func (m *NetworkPolicyPeer) Reset() { *m = NetworkPolicyPeer{} } func (*NetworkPolicyPeer) ProtoMessage() {} -func (*NetworkPolicyPeer) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{37} } +func (*NetworkPolicyPeer) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{33} } func (m *NetworkPolicyPort) Reset() { *m = NetworkPolicyPort{} } func (*NetworkPolicyPort) ProtoMessage() {} -func (*NetworkPolicyPort) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{38} } +func (*NetworkPolicyPort) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{34} } func (m *NetworkPolicySpec) Reset() { *m = NetworkPolicySpec{} } func (*NetworkPolicySpec) ProtoMessage() {} -func (*NetworkPolicySpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{39} } +func (*NetworkPolicySpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{35} } func (m *PodSecurityPolicy) Reset() { *m = PodSecurityPolicy{} } func (*PodSecurityPolicy) ProtoMessage() {} -func (*PodSecurityPolicy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{40} } +func (*PodSecurityPolicy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{36} } func (m *PodSecurityPolicyList) Reset() { *m = PodSecurityPolicyList{} } func (*PodSecurityPolicyList) ProtoMessage() {} -func (*PodSecurityPolicyList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{41} } +func (*PodSecurityPolicyList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{37} } func (m *PodSecurityPolicySpec) Reset() { *m = PodSecurityPolicySpec{} } func (*PodSecurityPolicySpec) ProtoMessage() {} -func (*PodSecurityPolicySpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{42} } +func (*PodSecurityPolicySpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{38} } func (m *ReplicaSet) Reset() { *m = ReplicaSet{} } func (*ReplicaSet) ProtoMessage() {} -func (*ReplicaSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{43} } +func (*ReplicaSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{39} } func (m *ReplicaSetCondition) Reset() { *m = ReplicaSetCondition{} } func (*ReplicaSetCondition) ProtoMessage() {} -func (*ReplicaSetCondition) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{44} } +func (*ReplicaSetCondition) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{40} } func (m *ReplicaSetList) Reset() { *m = ReplicaSetList{} } func (*ReplicaSetList) ProtoMessage() {} -func (*ReplicaSetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{45} } +func (*ReplicaSetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{41} } func (m *ReplicaSetSpec) Reset() { *m = ReplicaSetSpec{} } func (*ReplicaSetSpec) ProtoMessage() {} -func (*ReplicaSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{46} } +func (*ReplicaSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{42} } func (m *ReplicaSetStatus) Reset() { *m = ReplicaSetStatus{} } func (*ReplicaSetStatus) ProtoMessage() {} -func (*ReplicaSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{47} } +func (*ReplicaSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{43} } func (m *ReplicationControllerDummy) Reset() { *m = ReplicationControllerDummy{} } func (*ReplicationControllerDummy) ProtoMessage() {} func (*ReplicationControllerDummy) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{48} + return fileDescriptorGenerated, []int{44} } func (m *RollbackConfig) Reset() { *m = RollbackConfig{} } func (*RollbackConfig) ProtoMessage() {} -func (*RollbackConfig) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{49} } +func (*RollbackConfig) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{45} } func (m *RollingUpdateDaemonSet) Reset() { *m = RollingUpdateDaemonSet{} } func (*RollingUpdateDaemonSet) ProtoMessage() {} -func (*RollingUpdateDaemonSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{50} } +func (*RollingUpdateDaemonSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{46} } func (m *RollingUpdateDeployment) Reset() { *m = RollingUpdateDeployment{} } func (*RollingUpdateDeployment) ProtoMessage() {} func (*RollingUpdateDeployment) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{51} + return fileDescriptorGenerated, []int{47} } func (m *RunAsGroupStrategyOptions) Reset() { *m = RunAsGroupStrategyOptions{} } func (*RunAsGroupStrategyOptions) ProtoMessage() {} func (*RunAsGroupStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{52} + return fileDescriptorGenerated, []int{48} } func (m *RunAsUserStrategyOptions) Reset() { *m = RunAsUserStrategyOptions{} } func (*RunAsUserStrategyOptions) ProtoMessage() {} func (*RunAsUserStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{53} + return fileDescriptorGenerated, []int{49} } func (m *SELinuxStrategyOptions) Reset() { *m = SELinuxStrategyOptions{} } func (*SELinuxStrategyOptions) ProtoMessage() {} -func (*SELinuxStrategyOptions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{54} } +func (*SELinuxStrategyOptions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{50} } func (m *Scale) Reset() { *m = Scale{} } func (*Scale) ProtoMessage() {} -func (*Scale) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{55} } +func (*Scale) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{51} } func (m *ScaleSpec) Reset() { *m = ScaleSpec{} } func (*ScaleSpec) ProtoMessage() {} -func (*ScaleSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{56} } +func (*ScaleSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{52} } func (m *ScaleStatus) Reset() { *m = ScaleStatus{} } func (*ScaleStatus) ProtoMessage() {} -func (*ScaleStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{57} } +func (*ScaleStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{53} } func (m *SupplementalGroupsStrategyOptions) Reset() { *m = SupplementalGroupsStrategyOptions{} } func (*SupplementalGroupsStrategyOptions) ProtoMessage() {} func (*SupplementalGroupsStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{58} + return fileDescriptorGenerated, []int{54} } func init() { proto.RegisterType((*AllowedFlexVolume)(nil), "k8s.io.api.extensions.v1beta1.AllowedFlexVolume") proto.RegisterType((*AllowedHostPath)(nil), "k8s.io.api.extensions.v1beta1.AllowedHostPath") - proto.RegisterType((*CustomMetricCurrentStatus)(nil), "k8s.io.api.extensions.v1beta1.CustomMetricCurrentStatus") - proto.RegisterType((*CustomMetricCurrentStatusList)(nil), "k8s.io.api.extensions.v1beta1.CustomMetricCurrentStatusList") - proto.RegisterType((*CustomMetricTarget)(nil), "k8s.io.api.extensions.v1beta1.CustomMetricTarget") - proto.RegisterType((*CustomMetricTargetList)(nil), "k8s.io.api.extensions.v1beta1.CustomMetricTargetList") proto.RegisterType((*DaemonSet)(nil), "k8s.io.api.extensions.v1beta1.DaemonSet") proto.RegisterType((*DaemonSetCondition)(nil), "k8s.io.api.extensions.v1beta1.DaemonSetCondition") proto.RegisterType((*DaemonSetList)(nil), "k8s.io.api.extensions.v1beta1.DaemonSetList") @@ -483,126 +452,6 @@ func (m *AllowedHostPath) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *CustomMetricCurrentStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CustomMetricCurrentStatus) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.CurrentValue.Size())) - n1, err := m.CurrentValue.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n1 - return i, nil -} - -func (m *CustomMetricCurrentStatusList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CustomMetricCurrentStatusList) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Items) > 0 { - for _, msg := range m.Items { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *CustomMetricTarget) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CustomMetricTarget) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.TargetValue.Size())) - n2, err := m.TargetValue.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n2 - return i, nil -} - -func (m *CustomMetricTargetList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CustomMetricTargetList) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Items) > 0 { - for _, msg := range m.Items { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - func (m *DaemonSet) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -621,27 +470,27 @@ func (m *DaemonSet) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n3, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n1, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n3 + i += n1 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n4, err := m.Spec.MarshalTo(dAtA[i:]) + n2, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n4 + i += n2 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n5, err := m.Status.MarshalTo(dAtA[i:]) + n3, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n3 return i, nil } @@ -671,11 +520,11 @@ func (m *DaemonSetCondition) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.LastTransitionTime.Size())) - n6, err := m.LastTransitionTime.MarshalTo(dAtA[i:]) + n4, err := m.LastTransitionTime.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n4 dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) @@ -705,11 +554,11 @@ func (m *DaemonSetList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n7, err := m.ListMeta.MarshalTo(dAtA[i:]) + n5, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n5 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -744,28 +593,28 @@ func (m *DaemonSetSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Selector.Size())) - n8, err := m.Selector.MarshalTo(dAtA[i:]) + n6, err := m.Selector.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n6 } dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Template.Size())) - n9, err := m.Template.MarshalTo(dAtA[i:]) + n7, err := m.Template.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n7 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.UpdateStrategy.Size())) - n10, err := m.UpdateStrategy.MarshalTo(dAtA[i:]) + n8, err := m.UpdateStrategy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n8 dAtA[i] = 0x20 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.MinReadySeconds)) @@ -862,11 +711,11 @@ func (m *DaemonSetUpdateStrategy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.RollingUpdate.Size())) - n11, err := m.RollingUpdate.MarshalTo(dAtA[i:]) + n9, err := m.RollingUpdate.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n9 } return i, nil } @@ -889,27 +738,27 @@ func (m *Deployment) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n12, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n10, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n10 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n13, err := m.Spec.MarshalTo(dAtA[i:]) + n11, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n11 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n14, err := m.Status.MarshalTo(dAtA[i:]) + n12, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n12 return i, nil } @@ -947,19 +796,19 @@ func (m *DeploymentCondition) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x32 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.LastUpdateTime.Size())) - n15, err := m.LastUpdateTime.MarshalTo(dAtA[i:]) + n13, err := m.LastUpdateTime.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n13 dAtA[i] = 0x3a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.LastTransitionTime.Size())) - n16, err := m.LastTransitionTime.MarshalTo(dAtA[i:]) + n14, err := m.LastTransitionTime.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n14 return i, nil } @@ -981,11 +830,11 @@ func (m *DeploymentList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n17, err := m.ListMeta.MarshalTo(dAtA[i:]) + n15, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n15 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -1045,11 +894,11 @@ func (m *DeploymentRollback) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.RollbackTo.Size())) - n18, err := m.RollbackTo.MarshalTo(dAtA[i:]) + n16, err := m.RollbackTo.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n16 return i, nil } @@ -1077,28 +926,28 @@ func (m *DeploymentSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Selector.Size())) - n19, err := m.Selector.MarshalTo(dAtA[i:]) + n17, err := m.Selector.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n17 } dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Template.Size())) - n20, err := m.Template.MarshalTo(dAtA[i:]) + n18, err := m.Template.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n18 dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Strategy.Size())) - n21, err := m.Strategy.MarshalTo(dAtA[i:]) + n19, err := m.Strategy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n19 dAtA[i] = 0x28 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.MinReadySeconds)) @@ -1119,11 +968,11 @@ func (m *DeploymentSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x42 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.RollbackTo.Size())) - n22, err := m.RollbackTo.MarshalTo(dAtA[i:]) + n20, err := m.RollbackTo.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n20 } if m.ProgressDeadlineSeconds != nil { dAtA[i] = 0x48 @@ -1209,11 +1058,11 @@ func (m *DeploymentStrategy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.RollingUpdate.Size())) - n23, err := m.RollingUpdate.MarshalTo(dAtA[i:]) + n21, err := m.RollingUpdate.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n21 } return i, nil } @@ -1274,11 +1123,11 @@ func (m *HTTPIngressPath) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Backend.Size())) - n24, err := m.Backend.MarshalTo(dAtA[i:]) + n22, err := m.Backend.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n22 return i, nil } @@ -1415,27 +1264,27 @@ func (m *Ingress) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n25, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n23, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n23 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n26, err := m.Spec.MarshalTo(dAtA[i:]) + n24, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n24 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n27, err := m.Status.MarshalTo(dAtA[i:]) + n25, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n25 return i, nil } @@ -1461,11 +1310,11 @@ func (m *IngressBackend) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ServicePort.Size())) - n28, err := m.ServicePort.MarshalTo(dAtA[i:]) + n26, err := m.ServicePort.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n26 return i, nil } @@ -1487,11 +1336,11 @@ func (m *IngressList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n29, err := m.ListMeta.MarshalTo(dAtA[i:]) + n27, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n27 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -1529,11 +1378,11 @@ func (m *IngressRule) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.IngressRuleValue.Size())) - n30, err := m.IngressRuleValue.MarshalTo(dAtA[i:]) + n28, err := m.IngressRuleValue.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n28 return i, nil } @@ -1556,11 +1405,11 @@ func (m *IngressRuleValue) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.HTTP.Size())) - n31, err := m.HTTP.MarshalTo(dAtA[i:]) + n29, err := m.HTTP.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n29 } return i, nil } @@ -1584,11 +1433,11 @@ func (m *IngressSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Backend.Size())) - n32, err := m.Backend.MarshalTo(dAtA[i:]) + n30, err := m.Backend.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n32 + i += n30 } if len(m.TLS) > 0 { for _, msg := range m.TLS { @@ -1635,11 +1484,11 @@ func (m *IngressStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.LoadBalancer.Size())) - n33, err := m.LoadBalancer.MarshalTo(dAtA[i:]) + n31, err := m.LoadBalancer.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n31 return i, nil } @@ -1698,19 +1547,19 @@ func (m *NetworkPolicy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n34, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n32, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n34 + i += n32 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n35, err := m.Spec.MarshalTo(dAtA[i:]) + n33, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n33 return i, nil } @@ -1816,11 +1665,11 @@ func (m *NetworkPolicyList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n36, err := m.ListMeta.MarshalTo(dAtA[i:]) + n34, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n34 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -1855,31 +1704,31 @@ func (m *NetworkPolicyPeer) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.PodSelector.Size())) - n37, err := m.PodSelector.MarshalTo(dAtA[i:]) + n35, err := m.PodSelector.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n35 } if m.NamespaceSelector != nil { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.NamespaceSelector.Size())) - n38, err := m.NamespaceSelector.MarshalTo(dAtA[i:]) + n36, err := m.NamespaceSelector.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n36 } if m.IPBlock != nil { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.IPBlock.Size())) - n39, err := m.IPBlock.MarshalTo(dAtA[i:]) + n37, err := m.IPBlock.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n37 } return i, nil } @@ -1909,11 +1758,11 @@ func (m *NetworkPolicyPort) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Port.Size())) - n40, err := m.Port.MarshalTo(dAtA[i:]) + n38, err := m.Port.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n38 } return i, nil } @@ -1936,11 +1785,11 @@ func (m *NetworkPolicySpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.PodSelector.Size())) - n41, err := m.PodSelector.MarshalTo(dAtA[i:]) + n39, err := m.PodSelector.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n39 if len(m.Ingress) > 0 { for _, msg := range m.Ingress { dAtA[i] = 0x12 @@ -2001,19 +1850,19 @@ func (m *PodSecurityPolicy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n42, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n40, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n42 + i += n40 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n43, err := m.Spec.MarshalTo(dAtA[i:]) + n41, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n43 + i += n41 return i, nil } @@ -2035,11 +1884,11 @@ func (m *PodSecurityPolicyList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n44, err := m.ListMeta.MarshalTo(dAtA[i:]) + n42, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n44 + i += n42 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -2177,35 +2026,35 @@ func (m *PodSecurityPolicySpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x52 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.SELinux.Size())) - n45, err := m.SELinux.MarshalTo(dAtA[i:]) + n43, err := m.SELinux.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n45 + i += n43 dAtA[i] = 0x5a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.RunAsUser.Size())) - n46, err := m.RunAsUser.MarshalTo(dAtA[i:]) + n44, err := m.RunAsUser.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n46 + i += n44 dAtA[i] = 0x62 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.SupplementalGroups.Size())) - n47, err := m.SupplementalGroups.MarshalTo(dAtA[i:]) + n45, err := m.SupplementalGroups.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n47 + i += n45 dAtA[i] = 0x6a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.FSGroup.Size())) - n48, err := m.FSGroup.MarshalTo(dAtA[i:]) + n46, err := m.FSGroup.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n48 + i += n46 dAtA[i] = 0x70 i++ if m.ReadOnlyRootFilesystem { @@ -2321,11 +2170,11 @@ func (m *PodSecurityPolicySpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.RunAsGroup.Size())) - n49, err := m.RunAsGroup.MarshalTo(dAtA[i:]) + n47, err := m.RunAsGroup.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n49 + i += n47 } return i, nil } @@ -2348,27 +2197,27 @@ func (m *ReplicaSet) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n50, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n48, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n50 + i += n48 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n51, err := m.Spec.MarshalTo(dAtA[i:]) + n49, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n51 + i += n49 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n52, err := m.Status.MarshalTo(dAtA[i:]) + n50, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n52 + i += n50 return i, nil } @@ -2398,11 +2247,11 @@ func (m *ReplicaSetCondition) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.LastTransitionTime.Size())) - n53, err := m.LastTransitionTime.MarshalTo(dAtA[i:]) + n51, err := m.LastTransitionTime.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n53 + i += n51 dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) @@ -2432,11 +2281,11 @@ func (m *ReplicaSetList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n54, err := m.ListMeta.MarshalTo(dAtA[i:]) + n52, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n54 + i += n52 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -2476,20 +2325,20 @@ func (m *ReplicaSetSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Selector.Size())) - n55, err := m.Selector.MarshalTo(dAtA[i:]) + n53, err := m.Selector.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n55 + i += n53 } dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Template.Size())) - n56, err := m.Template.MarshalTo(dAtA[i:]) + n54, err := m.Template.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n56 + i += n54 dAtA[i] = 0x20 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.MinReadySeconds)) @@ -2599,11 +2448,11 @@ func (m *RollingUpdateDaemonSet) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.MaxUnavailable.Size())) - n57, err := m.MaxUnavailable.MarshalTo(dAtA[i:]) + n55, err := m.MaxUnavailable.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n57 + i += n55 } return i, nil } @@ -2627,21 +2476,21 @@ func (m *RollingUpdateDeployment) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.MaxUnavailable.Size())) - n58, err := m.MaxUnavailable.MarshalTo(dAtA[i:]) + n56, err := m.MaxUnavailable.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n58 + i += n56 } if m.MaxSurge != nil { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.MaxSurge.Size())) - n59, err := m.MaxSurge.MarshalTo(dAtA[i:]) + n57, err := m.MaxSurge.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n59 + i += n57 } return i, nil } @@ -2737,11 +2586,11 @@ func (m *SELinuxStrategyOptions) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.SELinuxOptions.Size())) - n60, err := m.SELinuxOptions.MarshalTo(dAtA[i:]) + n58, err := m.SELinuxOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n60 + i += n58 } return i, nil } @@ -2764,27 +2613,27 @@ func (m *Scale) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n61, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n59, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n61 + i += n59 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n62, err := m.Spec.MarshalTo(dAtA[i:]) + n60, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n62 + i += n60 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n63, err := m.Status.MarshalTo(dAtA[i:]) + n61, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n63 + i += n61 return i, nil } @@ -2916,50 +2765,6 @@ func (m *AllowedHostPath) Size() (n int) { return n } -func (m *CustomMetricCurrentStatus) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.CurrentValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *CustomMetricCurrentStatusList) Size() (n int) { - var l int - _ = l - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *CustomMetricTarget) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.TargetValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *CustomMetricTargetList) Size() (n int) { - var l int - _ = l - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - func (m *DaemonSet) Size() (n int) { var l int _ = l @@ -3813,101 +3618,59 @@ func (this *AllowedHostPath) String() string { }, "") return s } -func (this *CustomMetricCurrentStatus) String() string { +func (this *DaemonSet) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&CustomMetricCurrentStatus{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `CurrentValue:` + strings.Replace(strings.Replace(this.CurrentValue.String(), "Quantity", "k8s_io_apimachinery_pkg_api_resource.Quantity", 1), `&`, ``, 1) + `,`, + s := strings.Join([]string{`&DaemonSet{`, + `ObjectMeta:` + strings.Replace(strings.Replace(this.ObjectMeta.String(), "ObjectMeta", "k8s_io_apimachinery_pkg_apis_meta_v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "DaemonSetSpec", "DaemonSetSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "DaemonSetStatus", "DaemonSetStatus", 1), `&`, ``, 1) + `,`, `}`, }, "") return s } -func (this *CustomMetricCurrentStatusList) String() string { +func (this *DaemonSetCondition) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&CustomMetricCurrentStatusList{`, - `Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "CustomMetricCurrentStatus", "CustomMetricCurrentStatus", 1), `&`, ``, 1) + `,`, + s := strings.Join([]string{`&DaemonSetCondition{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `Status:` + fmt.Sprintf("%v", this.Status) + `,`, + `LastTransitionTime:` + strings.Replace(strings.Replace(this.LastTransitionTime.String(), "Time", "k8s_io_apimachinery_pkg_apis_meta_v1.Time", 1), `&`, ``, 1) + `,`, + `Reason:` + fmt.Sprintf("%v", this.Reason) + `,`, + `Message:` + fmt.Sprintf("%v", this.Message) + `,`, `}`, }, "") return s } -func (this *CustomMetricTarget) String() string { +func (this *DaemonSetList) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&CustomMetricTarget{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `TargetValue:` + strings.Replace(strings.Replace(this.TargetValue.String(), "Quantity", "k8s_io_apimachinery_pkg_api_resource.Quantity", 1), `&`, ``, 1) + `,`, + s := strings.Join([]string{`&DaemonSetList{`, + `ListMeta:` + strings.Replace(strings.Replace(this.ListMeta.String(), "ListMeta", "k8s_io_apimachinery_pkg_apis_meta_v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "DaemonSet", "DaemonSet", 1), `&`, ``, 1) + `,`, `}`, }, "") return s } -func (this *CustomMetricTargetList) String() string { +func (this *DaemonSetSpec) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&CustomMetricTargetList{`, - `Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "CustomMetricTarget", "CustomMetricTarget", 1), `&`, ``, 1) + `,`, + s := strings.Join([]string{`&DaemonSetSpec{`, + `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "k8s_io_apimachinery_pkg_apis_meta_v1.LabelSelector", 1) + `,`, + `Template:` + strings.Replace(strings.Replace(this.Template.String(), "PodTemplateSpec", "k8s_io_api_core_v1.PodTemplateSpec", 1), `&`, ``, 1) + `,`, + `UpdateStrategy:` + strings.Replace(strings.Replace(this.UpdateStrategy.String(), "DaemonSetUpdateStrategy", "DaemonSetUpdateStrategy", 1), `&`, ``, 1) + `,`, + `MinReadySeconds:` + fmt.Sprintf("%v", this.MinReadySeconds) + `,`, + `TemplateGeneration:` + fmt.Sprintf("%v", this.TemplateGeneration) + `,`, + `RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`, `}`, }, "") return s } -func (this *DaemonSet) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&DaemonSet{`, - `ObjectMeta:` + strings.Replace(strings.Replace(this.ObjectMeta.String(), "ObjectMeta", "k8s_io_apimachinery_pkg_apis_meta_v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "DaemonSetSpec", "DaemonSetSpec", 1), `&`, ``, 1) + `,`, - `Status:` + strings.Replace(strings.Replace(this.Status.String(), "DaemonSetStatus", "DaemonSetStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *DaemonSetCondition) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&DaemonSetCondition{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `LastTransitionTime:` + strings.Replace(strings.Replace(this.LastTransitionTime.String(), "Time", "k8s_io_apimachinery_pkg_apis_meta_v1.Time", 1), `&`, ``, 1) + `,`, - `Reason:` + fmt.Sprintf("%v", this.Reason) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `}`, - }, "") - return s -} -func (this *DaemonSetList) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&DaemonSetList{`, - `ListMeta:` + strings.Replace(strings.Replace(this.ListMeta.String(), "ListMeta", "k8s_io_apimachinery_pkg_apis_meta_v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "DaemonSet", "DaemonSet", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *DaemonSetSpec) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&DaemonSetSpec{`, - `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "k8s_io_apimachinery_pkg_apis_meta_v1.LabelSelector", 1) + `,`, - `Template:` + strings.Replace(strings.Replace(this.Template.String(), "PodTemplateSpec", "k8s_io_api_core_v1.PodTemplateSpec", 1), `&`, ``, 1) + `,`, - `UpdateStrategy:` + strings.Replace(strings.Replace(this.UpdateStrategy.String(), "DaemonSetUpdateStrategy", "DaemonSetUpdateStrategy", 1), `&`, ``, 1) + `,`, - `MinReadySeconds:` + fmt.Sprintf("%v", this.MinReadySeconds) + `,`, - `TemplateGeneration:` + fmt.Sprintf("%v", this.TemplateGeneration) + `,`, - `RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`, - `}`, - }, "") - return s -} -func (this *DaemonSetStatus) String() string { +func (this *DaemonSetStatus) String() string { if this == nil { return "nil" } @@ -4708,386 +4471,6 @@ func (m *AllowedHostPath) Unmarshal(dAtA []byte) error { } return nil } -func (m *CustomMetricCurrentStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CustomMetricCurrentStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CustomMetricCurrentStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.CurrentValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CustomMetricCurrentStatusList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CustomMetricCurrentStatusList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CustomMetricCurrentStatusList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, CustomMetricCurrentStatus{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CustomMetricTarget) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CustomMetricTarget: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CustomMetricTarget: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.TargetValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CustomMetricTargetList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CustomMetricTargetList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CustomMetricTargetList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, CustomMetricTarget{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *DaemonSet) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -12686,237 +12069,230 @@ func init() { } var fileDescriptorGenerated = []byte{ - // 3709 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcd, 0x6f, 0x24, 0x49, - 0x56, 0xef, 0xac, 0x2a, 0xbb, 0xca, 0xcf, 0xed, 0xaf, 0xb0, 0xdb, 0x5d, 0xd3, 0x33, 0xed, 0xea, - 0xcd, 0x91, 0x9a, 0x9e, 0xa1, 0xa7, 0x6a, 0xba, 0x67, 0xa6, 0xb7, 0x99, 0x16, 0xbb, 0xeb, 0xb2, - 0xfb, 0xc3, 0x8b, 0x3f, 0x6a, 0xa2, 0xec, 0x66, 0x19, 0x31, 0xcb, 0xa4, 0xab, 0xc2, 0xe5, 0x1c, - 0x67, 0x65, 0xe6, 0x66, 0x44, 0x7a, 0x5d, 0x12, 0x42, 0x1c, 0x00, 0x09, 0x09, 0x04, 0x1c, 0x96, - 0x8f, 0x1b, 0x2b, 0x24, 0x4e, 0x20, 0xb8, 0xc1, 0x61, 0x35, 0x12, 0xd2, 0x22, 0x8d, 0xd0, 0x22, - 0xed, 0x8d, 0x3d, 0x59, 0x8c, 0xf7, 0x84, 0xf8, 0x07, 0x50, 0x1f, 0x10, 0x8a, 0xc8, 0xc8, 0xef, - 0x4c, 0x57, 0x95, 0xa7, 0xdb, 0x42, 0x88, 0x9b, 0x2b, 0xde, 0x7b, 0xbf, 0xf7, 0x22, 0xe2, 0xc5, - 0x7b, 0x2f, 0x23, 0x9e, 0xe1, 0xc9, 0xd1, 0x43, 0x5a, 0xd7, 0xad, 0xc6, 0x91, 0xbb, 0x4f, 0x1c, - 0x93, 0x30, 0x42, 0x1b, 0xc7, 0xc4, 0xec, 0x5a, 0x4e, 0x43, 0x12, 0x34, 0x5b, 0x6f, 0x90, 0x13, - 0x46, 0x4c, 0xaa, 0x5b, 0x26, 0x6d, 0x1c, 0xdf, 0xdb, 0x27, 0x4c, 0xbb, 0xd7, 0xe8, 0x11, 0x93, - 0x38, 0x1a, 0x23, 0xdd, 0xba, 0xed, 0x58, 0xcc, 0x42, 0x37, 0x3d, 0xf6, 0xba, 0x66, 0xeb, 0xf5, - 0x90, 0xbd, 0x2e, 0xd9, 0x6f, 0xbc, 0xd3, 0xd3, 0xd9, 0xa1, 0xbb, 0x5f, 0xef, 0x58, 0xfd, 0x46, - 0xcf, 0xea, 0x59, 0x0d, 0x21, 0xb5, 0xef, 0x1e, 0x88, 0x5f, 0xe2, 0x87, 0xf8, 0xcb, 0x43, 0xbb, - 0xa1, 0x46, 0x94, 0x77, 0x2c, 0x87, 0x34, 0x8e, 0x53, 0x1a, 0x6f, 0xbc, 0x1f, 0xf2, 0xf4, 0xb5, - 0xce, 0xa1, 0x6e, 0x12, 0x67, 0xd0, 0xb0, 0x8f, 0x7a, 0x42, 0xc8, 0x21, 0xd4, 0x72, 0x9d, 0x0e, - 0x19, 0x4b, 0x8a, 0x36, 0xfa, 0x84, 0x69, 0x59, 0xba, 0x1a, 0x79, 0x52, 0x8e, 0x6b, 0x32, 0xbd, - 0x9f, 0x56, 0xf3, 0x60, 0x98, 0x00, 0xed, 0x1c, 0x92, 0xbe, 0x96, 0x92, 0x7b, 0x2f, 0x4f, 0xce, - 0x65, 0xba, 0xd1, 0xd0, 0x4d, 0x46, 0x99, 0x93, 0x14, 0x52, 0x1f, 0xc1, 0xc2, 0xaa, 0x61, 0x58, - 0xdf, 0x27, 0xdd, 0x27, 0x06, 0x39, 0x79, 0x6e, 0x19, 0x6e, 0x9f, 0xa0, 0xdb, 0x30, 0xd9, 0x75, - 0xf4, 0x63, 0xe2, 0x54, 0x95, 0x5b, 0xca, 0x9d, 0xa9, 0xe6, 0xec, 0x17, 0xa7, 0xb5, 0x2b, 0x67, - 0xa7, 0xb5, 0xc9, 0x75, 0x31, 0x8a, 0x25, 0x55, 0xa5, 0x30, 0x27, 0x85, 0x9f, 0x59, 0x94, 0xb5, - 0x34, 0x76, 0x88, 0xee, 0x03, 0xd8, 0x1a, 0x3b, 0x6c, 0x39, 0xe4, 0x40, 0x3f, 0x91, 0xe2, 0x48, - 0x8a, 0x43, 0x2b, 0xa0, 0xe0, 0x08, 0x17, 0xba, 0x0b, 0x15, 0x87, 0x68, 0xdd, 0x1d, 0xd3, 0x18, - 0x54, 0x0b, 0xb7, 0x94, 0x3b, 0x95, 0xe6, 0xbc, 0x94, 0xa8, 0x60, 0x39, 0x8e, 0x03, 0x0e, 0xf5, - 0x2f, 0x14, 0x78, 0x6d, 0xcd, 0xa5, 0xcc, 0xea, 0x6f, 0x11, 0xe6, 0xe8, 0x9d, 0x35, 0xd7, 0x71, - 0x88, 0xc9, 0xda, 0x4c, 0x63, 0x2e, 0x45, 0xb7, 0xa0, 0x64, 0x6a, 0x7d, 0x22, 0x35, 0x5f, 0x95, - 0x38, 0xa5, 0x6d, 0xad, 0x4f, 0xb0, 0xa0, 0xa0, 0x8f, 0x61, 0xe2, 0x58, 0x33, 0x5c, 0x22, 0x54, - 0x4d, 0xdf, 0xaf, 0xd7, 0x43, 0xef, 0x0b, 0x96, 0xad, 0x6e, 0x1f, 0xf5, 0x84, 0x3b, 0xfa, 0xbe, - 0x50, 0xff, 0xc8, 0xd5, 0x4c, 0xa6, 0xb3, 0x41, 0x73, 0x49, 0x42, 0x5e, 0x95, 0x7a, 0x9f, 0x73, - 0x2c, 0xec, 0x41, 0xaa, 0xbf, 0x05, 0x37, 0x73, 0x4d, 0xdb, 0xd4, 0x29, 0x43, 0x9f, 0xc0, 0x84, - 0xce, 0x48, 0x9f, 0x56, 0x95, 0x5b, 0xc5, 0x3b, 0xd3, 0xf7, 0x1f, 0xd6, 0xcf, 0x75, 0xfd, 0x7a, - 0x2e, 0x58, 0x73, 0x46, 0x9a, 0x31, 0xb1, 0xc1, 0xe1, 0xb0, 0x87, 0xaa, 0xfe, 0x89, 0x02, 0x28, - 0x2a, 0xb3, 0xab, 0x39, 0x3d, 0xc2, 0x46, 0x58, 0x94, 0x5f, 0xfb, 0x6a, 0x8b, 0xb2, 0x28, 0x21, - 0xa7, 0x3d, 0x85, 0xb1, 0x35, 0xb1, 0x61, 0x39, 0x6d, 0x92, 0x58, 0x8c, 0xe7, 0xf1, 0xc5, 0xb8, - 0x37, 0xc6, 0x62, 0x78, 0x28, 0x39, 0xab, 0xf0, 0x83, 0x02, 0x4c, 0xad, 0x6b, 0xa4, 0x6f, 0x99, - 0x6d, 0xc2, 0xd0, 0xa7, 0x50, 0xe1, 0x47, 0xb3, 0xab, 0x31, 0x4d, 0x2c, 0xc0, 0xf4, 0xfd, 0x77, - 0xcf, 0x9b, 0x1d, 0xad, 0x73, 0xee, 0xfa, 0xf1, 0xbd, 0xfa, 0xce, 0xfe, 0x67, 0xa4, 0xc3, 0xb6, - 0x08, 0xd3, 0x42, 0x0f, 0x0e, 0xc7, 0x70, 0x80, 0x8a, 0xb6, 0xa1, 0x44, 0x6d, 0xd2, 0x91, 0x6b, - 0x77, 0x77, 0xc8, 0x34, 0x02, 0xcb, 0xda, 0x36, 0xe9, 0x84, 0x9b, 0xc1, 0x7f, 0x61, 0x81, 0x83, - 0x9e, 0xc3, 0x24, 0x15, 0xbb, 0x5c, 0x2d, 0xa6, 0x76, 0xe3, 0x7c, 0x44, 0xcf, 0x37, 0x82, 0xe3, - 0xea, 0xfd, 0xc6, 0x12, 0x4d, 0xfd, 0x8f, 0x02, 0xa0, 0x80, 0x77, 0xcd, 0x32, 0xbb, 0x3a, 0xd3, - 0x2d, 0x13, 0x7d, 0x08, 0x25, 0x36, 0xb0, 0x7d, 0xef, 0xb8, 0xed, 0x1b, 0xb4, 0x3b, 0xb0, 0xc9, - 0x8b, 0xd3, 0xda, 0x72, 0x5a, 0x82, 0x53, 0xb0, 0x90, 0x41, 0x9b, 0x81, 0xa9, 0x05, 0x21, 0xfd, - 0x7e, 0x5c, 0xf5, 0x8b, 0xd3, 0x5a, 0x46, 0x38, 0xae, 0x07, 0x48, 0x71, 0x03, 0xd1, 0x31, 0x20, - 0x43, 0xa3, 0x6c, 0xd7, 0xd1, 0x4c, 0xea, 0x69, 0xd2, 0xfb, 0x44, 0x2e, 0xc2, 0xdb, 0xa3, 0x6d, - 0x1a, 0x97, 0x68, 0xde, 0x90, 0x56, 0xa0, 0xcd, 0x14, 0x1a, 0xce, 0xd0, 0xc0, 0xe3, 0x9d, 0x43, - 0x34, 0x6a, 0x99, 0xd5, 0x52, 0x3c, 0xde, 0x61, 0x31, 0x8a, 0x25, 0x15, 0xbd, 0x05, 0xe5, 0x3e, - 0xa1, 0x54, 0xeb, 0x91, 0xea, 0x84, 0x60, 0x9c, 0x93, 0x8c, 0xe5, 0x2d, 0x6f, 0x18, 0xfb, 0x74, - 0xf5, 0x47, 0x0a, 0xcc, 0x04, 0x2b, 0x27, 0xbc, 0xfd, 0xd7, 0x53, 0x7e, 0x58, 0x1f, 0x6d, 0x4a, - 0x5c, 0x5a, 0x78, 0x61, 0x10, 0x15, 0xfd, 0x91, 0x88, 0x0f, 0x6e, 0xf9, 0x67, 0xa9, 0x20, 0xce, - 0xd2, 0x9d, 0x51, 0x5d, 0x26, 0xe7, 0x08, 0xfd, 0x69, 0x29, 0x62, 0x3e, 0x77, 0x4d, 0xf4, 0x09, - 0x54, 0x28, 0x31, 0x48, 0x87, 0x59, 0x8e, 0x34, 0xff, 0xbd, 0x11, 0xcd, 0xd7, 0xf6, 0x89, 0xd1, - 0x96, 0xa2, 0xcd, 0xab, 0xdc, 0x7e, 0xff, 0x17, 0x0e, 0x20, 0xd1, 0x47, 0x50, 0x61, 0xa4, 0x6f, - 0x1b, 0x1a, 0xf3, 0x63, 0xd0, 0x9b, 0xd1, 0x29, 0x70, 0xcf, 0xe1, 0x60, 0x2d, 0xab, 0xbb, 0x2b, - 0xd9, 0xc4, 0xf1, 0x09, 0x96, 0xc4, 0x1f, 0xc5, 0x01, 0x0c, 0x3a, 0x86, 0x59, 0xd7, 0xee, 0x72, - 0x4e, 0xc6, 0x33, 0x5e, 0x6f, 0x20, 0x3d, 0xe9, 0xc1, 0xa8, 0x6b, 0xb3, 0x17, 0x93, 0x6e, 0x2e, - 0x4b, 0x5d, 0xb3, 0xf1, 0x71, 0x9c, 0xd0, 0x82, 0x56, 0x61, 0xae, 0xaf, 0x9b, 0x3c, 0x73, 0x0d, - 0xda, 0xa4, 0x63, 0x99, 0x5d, 0x2a, 0xdc, 0x6a, 0xa2, 0x79, 0x5d, 0x02, 0xcc, 0x6d, 0xc5, 0xc9, - 0x38, 0xc9, 0x8f, 0xbe, 0x0d, 0xc8, 0x9f, 0xc6, 0x53, 0x2f, 0x61, 0xeb, 0x96, 0x29, 0x7c, 0xae, - 0x18, 0x3a, 0xf7, 0x6e, 0x8a, 0x03, 0x67, 0x48, 0xa1, 0x4d, 0x58, 0x72, 0xc8, 0xb1, 0xce, 0xe7, - 0xf8, 0x4c, 0xa7, 0xcc, 0x72, 0x06, 0x9b, 0x7a, 0x5f, 0x67, 0xd5, 0x49, 0x61, 0x53, 0xf5, 0xec, - 0xb4, 0xb6, 0x84, 0x33, 0xe8, 0x38, 0x53, 0x4a, 0xfd, 0xb3, 0x49, 0x98, 0x4b, 0xc4, 0x1b, 0xf4, - 0x1c, 0x96, 0x3b, 0x5e, 0x72, 0xda, 0x76, 0xfb, 0xfb, 0xc4, 0x69, 0x77, 0x0e, 0x49, 0xd7, 0x35, - 0x48, 0x57, 0x38, 0xca, 0x44, 0x73, 0x45, 0x5a, 0xbc, 0xbc, 0x96, 0xc9, 0x85, 0x73, 0xa4, 0xf9, - 0x2a, 0x98, 0x62, 0x68, 0x4b, 0xa7, 0x34, 0xc0, 0x2c, 0x08, 0xcc, 0x60, 0x15, 0xb6, 0x53, 0x1c, - 0x38, 0x43, 0x8a, 0xdb, 0xd8, 0x25, 0x54, 0x77, 0x48, 0x37, 0x69, 0x63, 0x31, 0x6e, 0xe3, 0x7a, - 0x26, 0x17, 0xce, 0x91, 0x46, 0x1f, 0xc0, 0xb4, 0xa7, 0x4d, 0xec, 0x9f, 0xdc, 0xe8, 0x20, 0x1d, - 0x6e, 0x87, 0x24, 0x1c, 0xe5, 0xe3, 0x53, 0xb3, 0xf6, 0x29, 0x71, 0x8e, 0x49, 0x37, 0x7f, 0x83, - 0x77, 0x52, 0x1c, 0x38, 0x43, 0x8a, 0x4f, 0xcd, 0xf3, 0xc0, 0xd4, 0xd4, 0x26, 0xe3, 0x53, 0xdb, - 0xcb, 0xe4, 0xc2, 0x39, 0xd2, 0xdc, 0x8f, 0x3d, 0x93, 0x57, 0x8f, 0x35, 0xdd, 0xd0, 0xf6, 0x0d, - 0x52, 0x2d, 0xc7, 0xfd, 0x78, 0x3b, 0x4e, 0xc6, 0x49, 0x7e, 0xf4, 0x14, 0x16, 0xbc, 0xa1, 0x3d, - 0x53, 0x0b, 0x40, 0x2a, 0x02, 0xe4, 0x35, 0x09, 0xb2, 0xb0, 0x9d, 0x64, 0xc0, 0x69, 0x19, 0xf4, - 0x21, 0xcc, 0x76, 0x2c, 0xc3, 0x10, 0xfe, 0xb8, 0x66, 0xb9, 0x26, 0xab, 0x4e, 0x09, 0x14, 0xc4, - 0xcf, 0xe3, 0x5a, 0x8c, 0x82, 0x13, 0x9c, 0x88, 0x00, 0x74, 0xfc, 0x84, 0x43, 0xab, 0x30, 0x52, - 0xad, 0x91, 0x4e, 0x7a, 0x61, 0x0d, 0x10, 0x0c, 0x51, 0x1c, 0x01, 0x56, 0xff, 0x45, 0x81, 0xeb, - 0x39, 0xa1, 0x03, 0x7d, 0x33, 0x96, 0x62, 0x7f, 0x31, 0x91, 0x62, 0x5f, 0xcf, 0x11, 0x8b, 0xe4, - 0x59, 0x13, 0x66, 0x1c, 0x3e, 0x2b, 0xb3, 0xe7, 0xb1, 0xc8, 0x18, 0xf9, 0xc1, 0x90, 0x69, 0xe0, - 0xa8, 0x4c, 0x18, 0xf3, 0x17, 0xce, 0x4e, 0x6b, 0x33, 0x31, 0x1a, 0x8e, 0xc3, 0xab, 0x7f, 0x5e, - 0x00, 0x58, 0x27, 0xb6, 0x61, 0x0d, 0xfa, 0xc4, 0xbc, 0x8c, 0x1a, 0x6a, 0x27, 0x56, 0x43, 0xbd, - 0x33, 0x6c, 0x7b, 0x02, 0xd3, 0x72, 0x8b, 0xa8, 0x5f, 0x4d, 0x14, 0x51, 0x8d, 0xd1, 0x21, 0xcf, - 0xaf, 0xa2, 0xfe, 0xad, 0x08, 0x8b, 0x21, 0x73, 0x58, 0x46, 0x3d, 0x8a, 0xed, 0xf1, 0x2f, 0x24, - 0xf6, 0xf8, 0x7a, 0x86, 0xc8, 0x2b, 0xab, 0xa3, 0x5e, 0x7e, 0x3d, 0x83, 0x3e, 0x83, 0x59, 0x5e, - 0x38, 0x79, 0xee, 0x21, 0xca, 0xb2, 0xc9, 0xb1, 0xcb, 0xb2, 0x20, 0x81, 0x6e, 0xc6, 0x90, 0x70, - 0x02, 0x39, 0xa7, 0x0c, 0x2c, 0xbf, 0xea, 0x32, 0x50, 0xfd, 0x5c, 0x81, 0xd9, 0x70, 0x9b, 0x2e, - 0xa1, 0x68, 0xdb, 0x8e, 0x17, 0x6d, 0x6f, 0x8d, 0xec, 0xa2, 0x39, 0x55, 0xdb, 0x7f, 0xf1, 0x02, - 0x3f, 0x60, 0xe2, 0x07, 0x7c, 0x5f, 0xeb, 0x1c, 0x8d, 0xf0, 0xf9, 0xf7, 0x03, 0x05, 0x90, 0xcc, - 0x02, 0xab, 0xa6, 0x69, 0x31, 0xcd, 0x8b, 0x95, 0x9e, 0x59, 0x1b, 0x23, 0x9b, 0xe5, 0x6b, 0xac, - 0xef, 0xa5, 0xb0, 0x1e, 0x9b, 0xcc, 0x19, 0x84, 0x3b, 0x92, 0x66, 0xc0, 0x19, 0x06, 0x20, 0x0d, - 0xc0, 0x91, 0x98, 0xbb, 0x96, 0x3c, 0xc8, 0xef, 0x8c, 0x10, 0xf3, 0xb8, 0xc0, 0x9a, 0x65, 0x1e, - 0xe8, 0xbd, 0x30, 0xec, 0xe0, 0x00, 0x08, 0x47, 0x40, 0x6f, 0x3c, 0x86, 0xeb, 0x39, 0xd6, 0xa2, - 0x79, 0x28, 0x1e, 0x91, 0x81, 0xb7, 0x6c, 0x98, 0xff, 0x89, 0x96, 0xa2, 0x9f, 0xc9, 0x53, 0xf2, - 0x0b, 0xf7, 0xc3, 0xc2, 0x43, 0x45, 0xfd, 0xd1, 0x44, 0xd4, 0x77, 0x44, 0xc5, 0x7c, 0x07, 0x2a, - 0x0e, 0xb1, 0x0d, 0xbd, 0xa3, 0x51, 0x59, 0x08, 0x5d, 0xf5, 0xae, 0x34, 0xbc, 0x31, 0x1c, 0x50, - 0x63, 0xb5, 0x75, 0xe1, 0xd5, 0xd6, 0xd6, 0xc5, 0x97, 0x53, 0x5b, 0xff, 0x06, 0x54, 0xa8, 0x5f, - 0x55, 0x97, 0x04, 0xe4, 0xbd, 0x31, 0xe2, 0xab, 0x2c, 0xa8, 0x03, 0x05, 0x41, 0x29, 0x1d, 0x80, - 0x66, 0x15, 0xd1, 0x13, 0x63, 0x16, 0xd1, 0x2f, 0xb5, 0xf0, 0xe5, 0x31, 0xd5, 0xd6, 0x5c, 0x4a, - 0xba, 0x22, 0x10, 0x55, 0xc2, 0x98, 0xda, 0x12, 0xa3, 0x58, 0x52, 0xd1, 0x27, 0x31, 0x97, 0xad, - 0x5c, 0xc4, 0x65, 0x67, 0xf3, 0xdd, 0x15, 0xed, 0xc1, 0x75, 0xdb, 0xb1, 0x7a, 0x0e, 0xa1, 0x74, - 0x9d, 0x68, 0x5d, 0x43, 0x37, 0x89, 0xbf, 0x3e, 0x5e, 0x45, 0xf4, 0xfa, 0xd9, 0x69, 0xed, 0x7a, - 0x2b, 0x9b, 0x05, 0xe7, 0xc9, 0xaa, 0x5f, 0x94, 0x60, 0x3e, 0x99, 0x01, 0x73, 0x8a, 0x54, 0xe5, - 0x42, 0x45, 0xea, 0xdd, 0xc8, 0x61, 0xf0, 0x2a, 0xf8, 0xc8, 0x1d, 0x5f, 0xea, 0x40, 0xac, 0xc2, - 0x9c, 0x8c, 0x06, 0x3e, 0x51, 0x96, 0xe9, 0xc1, 0xee, 0xef, 0xc5, 0xc9, 0x38, 0xc9, 0xcf, 0x4b, - 0xcf, 0xb0, 0xa2, 0xf4, 0x41, 0x4a, 0xf1, 0xd2, 0x73, 0x35, 0xc9, 0x80, 0xd3, 0x32, 0x68, 0x0b, - 0x16, 0x5d, 0x33, 0x0d, 0xe5, 0x79, 0xe3, 0xeb, 0x12, 0x6a, 0x71, 0x2f, 0xcd, 0x82, 0xb3, 0xe4, - 0xd0, 0x41, 0xac, 0x1a, 0x9d, 0x14, 0x11, 0xf6, 0xfe, 0xc8, 0x67, 0x67, 0xe4, 0x72, 0x14, 0x3d, - 0x82, 0x19, 0x47, 0x7c, 0x77, 0xf8, 0x06, 0x7b, 0xb5, 0xfb, 0x35, 0x29, 0x36, 0x83, 0xa3, 0x44, - 0x1c, 0xe7, 0xcd, 0x28, 0xb7, 0x2b, 0xa3, 0x96, 0xdb, 0xea, 0x3f, 0x29, 0xd1, 0x24, 0x14, 0x94, - 0xc0, 0xc3, 0x6e, 0x99, 0x52, 0x12, 0x91, 0xea, 0xc8, 0xca, 0xae, 0x7e, 0x1f, 0x8c, 0x55, 0xfd, - 0x86, 0xc9, 0x73, 0x78, 0xf9, 0xfb, 0x43, 0x05, 0x96, 0x9f, 0xb4, 0x9f, 0x3a, 0x96, 0x6b, 0xfb, - 0xe6, 0xec, 0xd8, 0xde, 0xba, 0x7e, 0x1d, 0x4a, 0x8e, 0x6b, 0xf8, 0xf3, 0x78, 0xd3, 0x9f, 0x07, - 0x76, 0x0d, 0x3e, 0x8f, 0xc5, 0x84, 0x94, 0x37, 0x09, 0x2e, 0x80, 0xb6, 0x61, 0xd2, 0xd1, 0xcc, - 0x1e, 0xf1, 0xd3, 0xea, 0xed, 0x21, 0xd6, 0x6f, 0xac, 0x63, 0xce, 0x1e, 0x29, 0xde, 0x84, 0x34, - 0x96, 0x28, 0xea, 0x1f, 0x2a, 0x30, 0xf7, 0x6c, 0x77, 0xb7, 0xb5, 0x61, 0x8a, 0x13, 0x2d, 0x6e, - 0xdf, 0x6f, 0x41, 0xc9, 0xd6, 0xd8, 0x61, 0x32, 0xd3, 0x73, 0x1a, 0x16, 0x14, 0xf4, 0x1d, 0x28, - 0xf3, 0x48, 0x42, 0xcc, 0xee, 0x88, 0xa5, 0xb6, 0x84, 0x6f, 0x7a, 0x42, 0x61, 0x85, 0x28, 0x07, - 0xb0, 0x0f, 0xa7, 0x1e, 0xc1, 0x52, 0xc4, 0x1c, 0xbe, 0x1e, 0xe2, 0x1a, 0x18, 0xb5, 0x61, 0x82, - 0x6b, 0xf6, 0x6f, 0x79, 0x87, 0x5d, 0x66, 0x26, 0xa6, 0x14, 0x56, 0x3a, 0xfc, 0x17, 0xc5, 0x1e, - 0x96, 0xba, 0x05, 0x33, 0xe2, 0xc9, 0xc1, 0x72, 0x98, 0x58, 0x16, 0x74, 0x13, 0x8a, 0x7d, 0xdd, - 0x94, 0x79, 0x76, 0x5a, 0xca, 0x14, 0x79, 0x8e, 0xe0, 0xe3, 0x82, 0xac, 0x9d, 0xc8, 0xc8, 0x13, - 0x92, 0xb5, 0x13, 0xcc, 0xc7, 0xd5, 0xa7, 0x50, 0x96, 0xcb, 0x1d, 0x05, 0x2a, 0x9e, 0x0f, 0x54, - 0xcc, 0x00, 0xda, 0x81, 0xf2, 0x46, 0xab, 0x69, 0x58, 0x5e, 0xd5, 0xd5, 0xd1, 0xbb, 0x4e, 0x72, - 0x2f, 0xd6, 0x36, 0xd6, 0x31, 0x16, 0x14, 0xa4, 0xc2, 0x24, 0x39, 0xe9, 0x10, 0x9b, 0x09, 0x8f, - 0x98, 0x6a, 0x02, 0xdf, 0xe5, 0xc7, 0x62, 0x04, 0x4b, 0x8a, 0xfa, 0x47, 0x05, 0x28, 0xcb, 0xe5, - 0xb8, 0x84, 0xaf, 0xb0, 0xcd, 0xd8, 0x57, 0xd8, 0xdb, 0xa3, 0xb9, 0x46, 0xee, 0x27, 0xd8, 0x6e, - 0xe2, 0x13, 0xec, 0xee, 0x88, 0x78, 0xe7, 0x7f, 0x7f, 0xfd, 0xbd, 0x02, 0xb3, 0x71, 0xa7, 0x44, - 0x1f, 0xc0, 0x34, 0x4f, 0x38, 0x7a, 0x87, 0x6c, 0x87, 0x75, 0x6e, 0x70, 0x09, 0xd3, 0x0e, 0x49, - 0x38, 0xca, 0x87, 0x7a, 0x81, 0x18, 0xf7, 0x23, 0x39, 0xe9, 0xfc, 0x25, 0x75, 0x99, 0x6e, 0xd4, - 0xbd, 0x67, 0xb4, 0xfa, 0x86, 0xc9, 0x76, 0x9c, 0x36, 0x73, 0x74, 0xb3, 0x97, 0x52, 0x24, 0x9c, - 0x32, 0x8a, 0xac, 0xfe, 0xa3, 0x02, 0xd3, 0xd2, 0xe4, 0x4b, 0xf8, 0xaa, 0xf8, 0x95, 0xf8, 0x57, - 0xc5, 0xed, 0x11, 0x0f, 0x78, 0xf6, 0x27, 0xc5, 0x5f, 0x87, 0xa6, 0xf3, 0x23, 0xcd, 0xbd, 0xfa, - 0xd0, 0xa2, 0x2c, 0xe9, 0xd5, 0xfc, 0x30, 0x62, 0x41, 0x41, 0x2e, 0xcc, 0xeb, 0x89, 0x18, 0x20, - 0x97, 0xb6, 0x31, 0x9a, 0x25, 0x81, 0x58, 0xb3, 0x2a, 0xe1, 0xe7, 0x93, 0x14, 0x9c, 0x52, 0xa1, - 0x12, 0x48, 0x71, 0xa1, 0x8f, 0xa0, 0x74, 0xc8, 0x98, 0x9d, 0x71, 0x5f, 0x3d, 0x24, 0xf2, 0x84, - 0x26, 0x54, 0xc4, 0xec, 0x76, 0x77, 0x5b, 0x58, 0x40, 0xa9, 0xff, 0x1d, 0xae, 0x47, 0xdb, 0xf3, - 0xf1, 0x20, 0x9e, 0x2a, 0x17, 0x89, 0xa7, 0xd3, 0x59, 0xb1, 0x14, 0x3d, 0x83, 0x22, 0x33, 0x46, - 0xfd, 0x2c, 0x94, 0x88, 0xbb, 0x9b, 0xed, 0x30, 0x20, 0xed, 0x6e, 0xb6, 0x31, 0x87, 0x40, 0x3b, - 0x30, 0xc1, 0xb3, 0x0f, 0x3f, 0x82, 0xc5, 0xd1, 0x8f, 0x34, 0x9f, 0x7f, 0xe8, 0x10, 0xfc, 0x17, - 0xc5, 0x1e, 0x8e, 0xfa, 0x3d, 0x98, 0x89, 0x9d, 0x53, 0xf4, 0x29, 0x5c, 0x35, 0x2c, 0xad, 0xdb, - 0xd4, 0x0c, 0xcd, 0xec, 0x10, 0xff, 0x71, 0xe0, 0x76, 0xd6, 0x17, 0xc6, 0x66, 0x84, 0x4f, 0x9e, - 0xf2, 0xe0, 0x39, 0x35, 0x4a, 0xc3, 0x31, 0x44, 0x55, 0x03, 0x08, 0xe7, 0x88, 0x6a, 0x30, 0xc1, - 0xfd, 0xcc, 0xcb, 0x27, 0x53, 0xcd, 0x29, 0x6e, 0x21, 0x77, 0x3f, 0x8a, 0xbd, 0x71, 0x74, 0x1f, - 0x80, 0x92, 0x8e, 0x43, 0x98, 0x08, 0x06, 0x85, 0xf8, 0x13, 0x74, 0x3b, 0xa0, 0xe0, 0x08, 0x97, - 0xfa, 0xcf, 0x0a, 0xcc, 0x6c, 0x13, 0xf6, 0x7d, 0xcb, 0x39, 0x6a, 0x59, 0x86, 0xde, 0x19, 0x5c, - 0x42, 0xb0, 0xc5, 0xb1, 0x60, 0xfb, 0xee, 0x90, 0x9d, 0x89, 0x59, 0x97, 0x17, 0x72, 0xd5, 0xcf, - 0x15, 0xb8, 0x1e, 0xe3, 0x7c, 0x1c, 0x1e, 0xdd, 0x3d, 0x98, 0xb0, 0x2d, 0x87, 0xf9, 0x89, 0x78, - 0x2c, 0x85, 0x3c, 0x8c, 0x45, 0x52, 0x31, 0x87, 0xc1, 0x1e, 0x1a, 0xda, 0x84, 0x02, 0xb3, 0xa4, - 0xab, 0x8e, 0x87, 0x49, 0x88, 0xd3, 0x04, 0x89, 0x59, 0xd8, 0xb5, 0x70, 0x81, 0x59, 0x7c, 0x23, - 0xaa, 0x31, 0xae, 0x68, 0xf0, 0x79, 0x45, 0x33, 0xc0, 0x50, 0x3a, 0x70, 0xac, 0xfe, 0x85, 0xe7, - 0x10, 0x6c, 0xc4, 0x13, 0xc7, 0xea, 0x63, 0x81, 0xa5, 0xfe, 0x58, 0x81, 0x85, 0x18, 0xe7, 0x25, - 0x04, 0xfe, 0x8f, 0xe2, 0x81, 0xff, 0xee, 0x38, 0x13, 0xc9, 0x09, 0xff, 0x3f, 0x2e, 0x24, 0xa6, - 0xc1, 0x27, 0x8c, 0x0e, 0x60, 0xda, 0xb6, 0xba, 0xed, 0x97, 0xf0, 0x1c, 0x38, 0xc7, 0xf3, 0x66, - 0x2b, 0xc4, 0xc2, 0x51, 0x60, 0x74, 0x02, 0x0b, 0xa6, 0xd6, 0x27, 0xd4, 0xd6, 0x3a, 0xa4, 0xfd, - 0x12, 0x2e, 0x48, 0xae, 0x89, 0xf7, 0x86, 0x24, 0x22, 0x4e, 0x2b, 0x41, 0x5b, 0x50, 0xd6, 0x6d, - 0x51, 0xc7, 0xc9, 0xda, 0x65, 0x68, 0x16, 0xf5, 0xaa, 0x3e, 0x2f, 0x9e, 0xcb, 0x1f, 0xd8, 0xc7, - 0x50, 0xff, 0x26, 0xe9, 0x0d, 0xdc, 0xff, 0xd0, 0x53, 0xa8, 0x88, 0x26, 0x9c, 0x8e, 0x65, 0xf8, - 0x2f, 0x03, 0x7c, 0x67, 0x5b, 0x72, 0xec, 0xc5, 0x69, 0xed, 0xf5, 0x8c, 0x4b, 0x5f, 0x9f, 0x8c, - 0x03, 0x61, 0xb4, 0x0d, 0x25, 0xfb, 0xab, 0x54, 0x30, 0x22, 0xc9, 0x89, 0xb2, 0x45, 0xe0, 0xa8, - 0xbf, 0x53, 0x4c, 0x98, 0x2b, 0x52, 0xdd, 0x67, 0x2f, 0x6d, 0xd7, 0x83, 0x8a, 0x29, 0x77, 0xe7, - 0xf7, 0xa1, 0x2c, 0x33, 0xbc, 0x74, 0xe6, 0xaf, 0x8f, 0xe3, 0xcc, 0xd1, 0x2c, 0x16, 0x7c, 0xb0, - 0xf8, 0x83, 0x3e, 0x30, 0xfa, 0x2e, 0x4c, 0x12, 0x4f, 0x85, 0x97, 0x1b, 0x1f, 0x8c, 0xa3, 0x22, - 0x8c, 0xab, 0x61, 0xa1, 0x2a, 0xc7, 0x24, 0x2a, 0xfa, 0x26, 0x5f, 0x2f, 0xce, 0xcb, 0x3f, 0x02, - 0x69, 0xb5, 0x24, 0xd2, 0xd5, 0x4d, 0x6f, 0xda, 0xc1, 0xf0, 0x8b, 0xd3, 0x1a, 0x84, 0x3f, 0x71, - 0x54, 0x42, 0xfd, 0x57, 0x05, 0x16, 0xc4, 0x0a, 0x75, 0x5c, 0x47, 0x67, 0x83, 0x4b, 0x4b, 0x4c, - 0xcf, 0x63, 0x89, 0xe9, 0xfd, 0x21, 0xcb, 0x92, 0xb2, 0x30, 0x37, 0x39, 0xfd, 0x44, 0x81, 0x6b, - 0x29, 0xee, 0x4b, 0x88, 0x8b, 0x7b, 0xf1, 0xb8, 0xf8, 0xee, 0xb8, 0x13, 0xca, 0x89, 0x8d, 0xbf, - 0x3b, 0x9f, 0x31, 0x1d, 0x71, 0x52, 0xee, 0x03, 0xd8, 0x8e, 0x7e, 0xac, 0x1b, 0xa4, 0x27, 0x1f, - 0xc1, 0x2b, 0x91, 0x26, 0xb8, 0x80, 0x82, 0x23, 0x5c, 0x88, 0xc2, 0x72, 0x97, 0x1c, 0x68, 0xae, - 0xc1, 0x56, 0xbb, 0xdd, 0x35, 0xcd, 0xd6, 0xf6, 0x75, 0x43, 0x67, 0xba, 0xbc, 0x2e, 0x98, 0x6a, - 0x3e, 0xf2, 0x1e, 0xa7, 0xb3, 0x38, 0x5e, 0x9c, 0xd6, 0x6e, 0x66, 0xbd, 0x0e, 0xf9, 0x2c, 0x03, - 0x9c, 0x03, 0x8d, 0x06, 0x50, 0x75, 0xc8, 0xf7, 0x5c, 0xdd, 0x21, 0xdd, 0x75, 0xc7, 0xb2, 0x63, - 0x6a, 0x8b, 0x42, 0xed, 0x2f, 0x9f, 0x9d, 0xd6, 0xaa, 0x38, 0x87, 0x67, 0xb8, 0xe2, 0x5c, 0x78, - 0xf4, 0x19, 0x2c, 0x6a, 0x5e, 0xef, 0x60, 0x4c, 0xab, 0x77, 0x4a, 0x1e, 0x9e, 0x9d, 0xd6, 0x16, - 0x57, 0xd3, 0xe4, 0xe1, 0x0a, 0xb3, 0x40, 0x51, 0x03, 0xca, 0xc7, 0xa2, 0xb3, 0x91, 0x56, 0x27, - 0x04, 0x3e, 0x4f, 0x04, 0x65, 0xaf, 0xd9, 0x91, 0x63, 0x4e, 0x3e, 0x69, 0x8b, 0xd3, 0xe7, 0x73, - 0xf1, 0x0f, 0x4a, 0x5e, 0x4b, 0xca, 0x13, 0x2f, 0x6e, 0x8c, 0x2b, 0x61, 0xd4, 0x7a, 0x16, 0x92, - 0x70, 0x94, 0x0f, 0x7d, 0x02, 0x53, 0x87, 0xf2, 0x56, 0x82, 0x56, 0xcb, 0x23, 0x25, 0xe1, 0xd8, - 0x2d, 0x46, 0x73, 0x41, 0xaa, 0x98, 0xf2, 0x87, 0x29, 0x0e, 0x11, 0xd1, 0x5b, 0x50, 0x16, 0x3f, - 0x36, 0xd6, 0xc5, 0x75, 0x5c, 0x25, 0x8c, 0x6d, 0xcf, 0xbc, 0x61, 0xec, 0xd3, 0x7d, 0xd6, 0x8d, - 0xd6, 0x9a, 0xb8, 0x16, 0x4e, 0xb0, 0x6e, 0xb4, 0xd6, 0xb0, 0x4f, 0x47, 0x9f, 0x42, 0x99, 0x92, - 0x4d, 0xdd, 0x74, 0x4f, 0xaa, 0x30, 0xd2, 0xa3, 0x72, 0xfb, 0xb1, 0xe0, 0x4e, 0x5c, 0x8c, 0x85, - 0x1a, 0x24, 0x1d, 0xfb, 0xb0, 0xe8, 0x10, 0xa6, 0x1c, 0xd7, 0x5c, 0xa5, 0x7b, 0x94, 0x38, 0xd5, - 0x69, 0xa1, 0x63, 0x58, 0x38, 0xc7, 0x3e, 0x7f, 0x52, 0x4b, 0xb0, 0x42, 0x01, 0x07, 0x0e, 0xc1, - 0xd1, 0x1f, 0x28, 0x80, 0xa8, 0x6b, 0xdb, 0x06, 0xe9, 0x13, 0x93, 0x69, 0x86, 0xb8, 0x8b, 0xa3, - 0xd5, 0xab, 0x42, 0xe7, 0xb7, 0x86, 0xcd, 0x2b, 0x25, 0x98, 0x54, 0x1e, 0x5c, 0x7a, 0xa7, 0x59, - 0x71, 0x86, 0x5e, 0xbe, 0xb4, 0x07, 0x54, 0xfc, 0x5d, 0x9d, 0x19, 0x69, 0x69, 0xb3, 0xef, 0x1c, - 0xc3, 0xa5, 0x95, 0x74, 0xec, 0xc3, 0xa2, 0xe7, 0xb0, 0xec, 0x37, 0xc6, 0x62, 0xcb, 0x62, 0x4f, - 0x74, 0x83, 0xd0, 0x01, 0x65, 0xa4, 0x5f, 0x9d, 0x15, 0xdb, 0x1e, 0xf4, 0x7e, 0xe0, 0x4c, 0x2e, - 0x9c, 0x23, 0x8d, 0xfa, 0x50, 0xf3, 0x43, 0x06, 0x3f, 0x4f, 0x41, 0xcc, 0x7a, 0x4c, 0x3b, 0x9a, - 0xe1, 0xbd, 0x03, 0xcc, 0x09, 0x05, 0x6f, 0x9e, 0x9d, 0xd6, 0x6a, 0xeb, 0xe7, 0xb3, 0xe2, 0x61, - 0x58, 0xe8, 0x3b, 0x50, 0xd5, 0xf2, 0xf4, 0xcc, 0x0b, 0x3d, 0x6f, 0xf0, 0x38, 0x94, 0xab, 0x20, - 0x57, 0x1a, 0x31, 0x98, 0xd7, 0xe2, 0x2d, 0xca, 0xb4, 0xba, 0x30, 0xd2, 0x45, 0x64, 0xa2, 0xb3, - 0x39, 0xbc, 0x8c, 0x48, 0x10, 0x28, 0x4e, 0x69, 0x40, 0xbf, 0x09, 0x48, 0x4b, 0x76, 0x55, 0xd3, - 0x2a, 0x1a, 0x29, 0xfd, 0xa4, 0xda, 0xb1, 0x43, 0xb7, 0x4b, 0x91, 0x28, 0xce, 0xd0, 0x83, 0x36, - 0x61, 0x49, 0x8e, 0xee, 0x99, 0x54, 0x3b, 0x20, 0xed, 0x01, 0xed, 0x30, 0x83, 0x56, 0x17, 0x45, - 0xec, 0x13, 0x0f, 0x5f, 0xab, 0x19, 0x74, 0x9c, 0x29, 0x85, 0xbe, 0x05, 0xf3, 0x07, 0x96, 0xb3, - 0xaf, 0x77, 0xbb, 0xc4, 0xf4, 0x91, 0x96, 0x04, 0xd2, 0x12, 0x5f, 0x8d, 0x27, 0x09, 0x1a, 0x4e, - 0x71, 0x23, 0x0a, 0xd7, 0x24, 0x72, 0xcb, 0xb1, 0x3a, 0x5b, 0x96, 0x6b, 0x32, 0xaf, 0x24, 0xba, - 0x16, 0xa4, 0x98, 0x6b, 0xab, 0x59, 0x0c, 0x2f, 0x4e, 0x6b, 0xb7, 0xb2, 0x2b, 0xe0, 0x90, 0x09, - 0x67, 0x63, 0xa3, 0x43, 0x00, 0x11, 0x17, 0xbc, 0xe3, 0xb7, 0x2c, 0x8e, 0xdf, 0xc3, 0x51, 0xa2, - 0x4e, 0xe6, 0x09, 0xf4, 0x9e, 0xe4, 0x02, 0x32, 0x8e, 0x60, 0x8b, 0x5e, 0x19, 0xf9, 0x72, 0x72, - 0x39, 0xfd, 0xc6, 0xe3, 0xf5, 0xca, 0x84, 0xa6, 0xbd, 0xb4, 0x5e, 0x99, 0x08, 0xe4, 0xf9, 0x77, - 0xb5, 0xff, 0x59, 0x80, 0xc5, 0x90, 0x79, 0xe4, 0x5e, 0x99, 0x0c, 0x91, 0xff, 0xef, 0x39, 0x1e, - 0xde, 0x73, 0xfc, 0xb9, 0x02, 0xb3, 0xe1, 0xd2, 0xfd, 0xef, 0xeb, 0x5f, 0x09, 0x6d, 0xcb, 0xa9, - 0xa8, 0xff, 0xae, 0x10, 0x9d, 0xc0, 0xff, 0xf9, 0x26, 0x8a, 0xaf, 0xde, 0x28, 0xac, 0xfe, 0xa4, - 0x08, 0xf3, 0xc9, 0xd3, 0x18, 0x7b, 0x6b, 0x57, 0x86, 0xbe, 0xb5, 0xb7, 0x60, 0xe9, 0xc0, 0x35, - 0x8c, 0x81, 0x58, 0x86, 0xc8, 0x83, 0xbb, 0xf7, 0x56, 0xf6, 0x86, 0x94, 0x5c, 0x7a, 0x92, 0xc1, - 0x83, 0x33, 0x25, 0x73, 0xfa, 0x06, 0x8a, 0x17, 0xea, 0x1b, 0x48, 0x3d, 0x63, 0x97, 0xc6, 0x78, - 0xc6, 0xce, 0xec, 0x01, 0x98, 0xb8, 0x40, 0x0f, 0xc0, 0x45, 0x1e, 0xed, 0x33, 0x82, 0xd8, 0xd0, - 0x1e, 0xd2, 0x37, 0xe0, 0x86, 0x14, 0x63, 0xe2, 0x3d, 0xdd, 0x64, 0x8e, 0x65, 0x18, 0xc4, 0x59, - 0x77, 0xfb, 0xfd, 0x81, 0xfa, 0x0d, 0x98, 0x8d, 0x77, 0x8a, 0x78, 0x3b, 0xed, 0x35, 0xab, 0xc8, - 0x17, 0xcb, 0xc8, 0x4e, 0x7b, 0xe3, 0x38, 0xe0, 0x50, 0x7f, 0x4f, 0x81, 0xe5, 0xec, 0x8e, 0x50, - 0x64, 0xc0, 0x6c, 0x5f, 0x3b, 0x89, 0x76, 0xe9, 0x2a, 0x17, 0xbc, 0x4b, 0x12, 0x2d, 0x02, 0x5b, - 0x31, 0x2c, 0x9c, 0xc0, 0x56, 0x7f, 0xae, 0xc0, 0xf5, 0x9c, 0xc7, 0xf9, 0xcb, 0xb5, 0x04, 0x7d, - 0x0c, 0x95, 0xbe, 0x76, 0xd2, 0x76, 0x9d, 0x1e, 0xb9, 0xf0, 0xed, 0x99, 0x88, 0x18, 0x5b, 0x12, - 0x05, 0x07, 0x78, 0xea, 0x5f, 0x29, 0xf0, 0x5a, 0x6e, 0x45, 0x81, 0x1e, 0xc4, 0xfa, 0x08, 0xd4, - 0x44, 0x1f, 0x01, 0x4a, 0x0b, 0xbe, 0xa2, 0x36, 0x82, 0x1f, 0x2a, 0x50, 0xcd, 0xfb, 0xda, 0x42, - 0x1f, 0xc4, 0x8c, 0xfc, 0x5a, 0xc2, 0xc8, 0x85, 0x94, 0xdc, 0x2b, 0xb2, 0xf1, 0x6f, 0x15, 0x58, - 0xce, 0xfe, 0xea, 0x44, 0xef, 0xc5, 0x2c, 0xac, 0x25, 0x2c, 0x9c, 0x4b, 0x48, 0x49, 0xfb, 0xbe, - 0x0b, 0xb3, 0xf2, 0xdb, 0x54, 0xc2, 0xc8, 0xbd, 0x57, 0xb3, 0x22, 0xba, 0x84, 0xf0, 0x2b, 0x41, - 0xe1, 0x55, 0xf1, 0x31, 0x9c, 0x40, 0x53, 0x7f, 0xbf, 0x00, 0x13, 0xed, 0x8e, 0x66, 0x90, 0x4b, - 0x28, 0x06, 0xbf, 0x1d, 0x2b, 0x06, 0x87, 0xfd, 0xdf, 0x8f, 0xb0, 0x2a, 0xb7, 0x0e, 0xc4, 0x89, - 0x3a, 0xf0, 0xed, 0x91, 0xd0, 0xce, 0x2f, 0x01, 0x7f, 0x09, 0xa6, 0x02, 0xa5, 0xe3, 0x65, 0x26, - 0xf5, 0x2f, 0x0b, 0x30, 0x1d, 0x51, 0x31, 0x66, 0x5e, 0x3b, 0x88, 0xd5, 0x03, 0xa3, 0xfc, 0xb7, - 0x65, 0x44, 0x57, 0xdd, 0xaf, 0x00, 0xbc, 0xbe, 0xd5, 0xb0, 0x53, 0x31, 0x5d, 0x18, 0x7c, 0x03, - 0x66, 0x99, 0xf8, 0x6f, 0xc4, 0xe0, 0x66, 0xbc, 0x28, 0x7c, 0x31, 0xe8, 0x76, 0xde, 0x8d, 0x51, - 0x71, 0x82, 0xfb, 0xc6, 0x23, 0x98, 0x89, 0x29, 0x1b, 0xab, 0xed, 0xf4, 0x1f, 0x14, 0xf8, 0xda, - 0xd0, 0x7b, 0x0b, 0xd4, 0x8c, 0x1d, 0x92, 0x7a, 0xe2, 0x90, 0xac, 0xe4, 0x03, 0xbc, 0xba, 0xf6, - 0xa5, 0xe6, 0x3b, 0x5f, 0x7c, 0xb9, 0x72, 0xe5, 0xa7, 0x5f, 0xae, 0x5c, 0xf9, 0xd9, 0x97, 0x2b, - 0x57, 0x7e, 0xfb, 0x6c, 0x45, 0xf9, 0xe2, 0x6c, 0x45, 0xf9, 0xe9, 0xd9, 0x8a, 0xf2, 0xb3, 0xb3, - 0x15, 0xe5, 0xdf, 0xcf, 0x56, 0x94, 0x3f, 0xfe, 0xf9, 0xca, 0x95, 0x8f, 0xcb, 0x12, 0xee, 0x7f, - 0x02, 0x00, 0x00, 0xff, 0xff, 0x73, 0x7f, 0xfe, 0x70, 0x6c, 0x3e, 0x00, 0x00, + // 3587 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcd, 0x6f, 0x1c, 0x47, + 0x76, 0x57, 0xcf, 0x0c, 0x39, 0xc3, 0x47, 0xf1, 0xab, 0x48, 0x91, 0x63, 0xc9, 0xe2, 0xc8, 0x6d, + 0x40, 0x91, 0x1d, 0x69, 0xc6, 0x92, 0x2d, 0x59, 0xb1, 0x10, 0xdb, 0x1c, 0x52, 0x94, 0xe8, 0xf0, + 0x63, 0x5c, 0x43, 0x2a, 0x86, 0x11, 0x3b, 0x6e, 0xce, 0x14, 0x87, 0x2d, 0xf6, 0x74, 0xb7, 0xbb, + 0x6b, 0x68, 0x0e, 0x90, 0x43, 0x0e, 0x49, 0x80, 0x00, 0x09, 0x92, 0x8b, 0x93, 0x1c, 0x63, 0x04, + 0xc8, 0x69, 0x17, 0xbb, 0xb7, 0xdd, 0x83, 0x61, 0x60, 0x01, 0x2f, 0x20, 0x2c, 0xbc, 0x80, 0x6f, + 0xeb, 0x13, 0xb1, 0xa6, 0x4f, 0x8b, 0xfd, 0x07, 0x16, 0x3a, 0x2c, 0x16, 0x55, 0x5d, 0xfd, 0xdd, + 0xad, 0x69, 0xd2, 0x12, 0xb1, 0x58, 0xec, 0x8d, 0x53, 0xef, 0xbd, 0xdf, 0x7b, 0x55, 0xf5, 0xea, + 0xbd, 0xd7, 0x55, 0x8f, 0xb0, 0xbc, 0x77, 0xdb, 0xae, 0xaa, 0x46, 0x6d, 0xaf, 0xb7, 0x4d, 0x2c, + 0x9d, 0x50, 0x62, 0xd7, 0xf6, 0x89, 0xde, 0x36, 0xac, 0x9a, 0x20, 0x28, 0xa6, 0x5a, 0x23, 0x07, + 0x94, 0xe8, 0xb6, 0x6a, 0xe8, 0x76, 0x6d, 0xff, 0xfa, 0x36, 0xa1, 0xca, 0xf5, 0x5a, 0x87, 0xe8, + 0xc4, 0x52, 0x28, 0x69, 0x57, 0x4d, 0xcb, 0xa0, 0x06, 0xba, 0xe8, 0xb0, 0x57, 0x15, 0x53, 0xad, + 0xfa, 0xec, 0x55, 0xc1, 0x7e, 0xfe, 0x5a, 0x47, 0xa5, 0xbb, 0xbd, 0xed, 0x6a, 0xcb, 0xe8, 0xd6, + 0x3a, 0x46, 0xc7, 0xa8, 0x71, 0xa9, 0xed, 0xde, 0x0e, 0xff, 0xc5, 0x7f, 0xf0, 0xbf, 0x1c, 0xb4, + 0xf3, 0x72, 0x40, 0x79, 0xcb, 0xb0, 0x48, 0x6d, 0x3f, 0xa6, 0xf1, 0xfc, 0x6b, 0x3e, 0x4f, 0x57, + 0x69, 0xed, 0xaa, 0x3a, 0xb1, 0xfa, 0x35, 0x73, 0xaf, 0xc3, 0x06, 0xec, 0x5a, 0x97, 0x50, 0x25, + 0x49, 0xaa, 0x96, 0x26, 0x65, 0xf5, 0x74, 0xaa, 0x76, 0x49, 0x4c, 0xe0, 0xd6, 0x20, 0x01, 0xbb, + 0xb5, 0x4b, 0xba, 0x4a, 0x4c, 0xee, 0xd5, 0x34, 0xb9, 0x1e, 0x55, 0xb5, 0x9a, 0xaa, 0x53, 0x9b, + 0x5a, 0x51, 0x21, 0xf9, 0x0e, 0x4c, 0x2d, 0x68, 0x9a, 0xf1, 0x09, 0x69, 0x2f, 0x6b, 0xe4, 0xe0, + 0x81, 0xa1, 0xf5, 0xba, 0x04, 0x5d, 0x86, 0xe1, 0xb6, 0xa5, 0xee, 0x13, 0xab, 0x2c, 0x5d, 0x92, + 0xae, 0x8c, 0xd4, 0xc7, 0x1f, 0x1d, 0x56, 0xce, 0x1c, 0x1d, 0x56, 0x86, 0x97, 0xf8, 0x28, 0x16, + 0x54, 0xd9, 0x86, 0x09, 0x21, 0x7c, 0xdf, 0xb0, 0x69, 0x43, 0xa1, 0xbb, 0xe8, 0x06, 0x80, 0xa9, + 0xd0, 0xdd, 0x86, 0x45, 0x76, 0xd4, 0x03, 0x21, 0x8e, 0x84, 0x38, 0x34, 0x3c, 0x0a, 0x0e, 0x70, + 0xa1, 0xab, 0x50, 0xb2, 0x88, 0xd2, 0xde, 0xd0, 0xb5, 0x7e, 0x39, 0x77, 0x49, 0xba, 0x52, 0xaa, + 0x4f, 0x0a, 0x89, 0x12, 0x16, 0xe3, 0xd8, 0xe3, 0x90, 0x3f, 0xcd, 0xc1, 0xc8, 0x92, 0x42, 0xba, + 0x86, 0xde, 0x24, 0x14, 0x7d, 0x04, 0x25, 0xb6, 0xf0, 0x6d, 0x85, 0x2a, 0x5c, 0xdb, 0xe8, 0x8d, + 0x57, 0xaa, 0xbe, 0x63, 0x78, 0xeb, 0x50, 0x35, 0xf7, 0x3a, 0x6c, 0xc0, 0xae, 0x32, 0xee, 0xea, + 0xfe, 0xf5, 0xea, 0xc6, 0xf6, 0x43, 0xd2, 0xa2, 0x6b, 0x84, 0x2a, 0xbe, 0x7d, 0xfe, 0x18, 0xf6, + 0x50, 0xd1, 0x3a, 0x14, 0x6c, 0x93, 0xb4, 0xb8, 0x65, 0xa3, 0x37, 0xae, 0x56, 0x9f, 0xe8, 0x76, + 0x55, 0xcf, 0xb2, 0xa6, 0x49, 0x5a, 0xf5, 0xb3, 0x02, 0xb9, 0xc0, 0x7e, 0x61, 0x8e, 0x83, 0x1e, + 0xc0, 0xb0, 0x4d, 0x15, 0xda, 0xb3, 0xcb, 0x79, 0x8e, 0x58, 0xcd, 0x8c, 0xc8, 0xa5, 0xfc, 0xcd, + 0x70, 0x7e, 0x63, 0x81, 0x26, 0xff, 0x26, 0x07, 0xc8, 0xe3, 0x5d, 0x34, 0xf4, 0xb6, 0x4a, 0x55, + 0x43, 0x47, 0x6f, 0x40, 0x81, 0xf6, 0x4d, 0x22, 0xb6, 0xe2, 0xb2, 0x6b, 0xd0, 0x66, 0xdf, 0x24, + 0x8f, 0x0f, 0x2b, 0xb3, 0x71, 0x09, 0x46, 0xc1, 0x5c, 0x06, 0xad, 0x7a, 0xa6, 0xe6, 0xb8, 0xf4, + 0x6b, 0x61, 0xd5, 0x8f, 0x0f, 0x2b, 0x09, 0xc7, 0xa6, 0xea, 0x21, 0x85, 0x0d, 0x44, 0xfb, 0x80, + 0x34, 0xc5, 0xa6, 0x9b, 0x96, 0xa2, 0xdb, 0x8e, 0x26, 0xb5, 0x4b, 0xc4, 0x22, 0xbc, 0x9c, 0x6d, + 0xd3, 0x98, 0x44, 0xfd, 0xbc, 0xb0, 0x02, 0xad, 0xc6, 0xd0, 0x70, 0x82, 0x06, 0xe6, 0xcd, 0x16, + 0x51, 0x6c, 0x43, 0x2f, 0x17, 0xc2, 0xde, 0x8c, 0xf9, 0x28, 0x16, 0x54, 0xf4, 0x12, 0x14, 0xbb, + 0xc4, 0xb6, 0x95, 0x0e, 0x29, 0x0f, 0x71, 0xc6, 0x09, 0xc1, 0x58, 0x5c, 0x73, 0x86, 0xb1, 0x4b, + 0x97, 0x3f, 0x97, 0x60, 0xcc, 0x5b, 0xb9, 0x55, 0xd5, 0xa6, 0xe8, 0xef, 0x62, 0x7e, 0x58, 0xcd, + 0x36, 0x25, 0x26, 0xcd, 0xbd, 0xd0, 0xf3, 0x79, 0x77, 0x24, 0xe0, 0x83, 0x6b, 0x30, 0xa4, 0x52, + 0xd2, 0x65, 0xfb, 0x90, 0xbf, 0x32, 0x7a, 0xe3, 0x4a, 0x56, 0x97, 0xa9, 0x8f, 0x09, 0xd0, 0xa1, + 0x15, 0x26, 0x8e, 0x1d, 0x14, 0xf9, 0xbf, 0x0a, 0x01, 0xf3, 0x99, 0x6b, 0xa2, 0x0f, 0xa0, 0x64, + 0x13, 0x8d, 0xb4, 0xa8, 0x61, 0x09, 0xf3, 0x5f, 0xcd, 0x68, 0xbe, 0xb2, 0x4d, 0xb4, 0xa6, 0x10, + 0xad, 0x9f, 0x65, 0xf6, 0xbb, 0xbf, 0xb0, 0x07, 0x89, 0xde, 0x85, 0x12, 0x25, 0x5d, 0x53, 0x53, + 0x28, 0x11, 0xe7, 0xe8, 0xc5, 0xe0, 0x14, 0x98, 0xe7, 0x30, 0xb0, 0x86, 0xd1, 0xde, 0x14, 0x6c, + 0xfc, 0xf8, 0x78, 0x4b, 0xe2, 0x8e, 0x62, 0x0f, 0x06, 0xed, 0xc3, 0x78, 0xcf, 0x6c, 0x33, 0x4e, + 0xca, 0xe2, 0x59, 0xa7, 0x2f, 0x3c, 0xe9, 0x56, 0xd6, 0xb5, 0xd9, 0x0a, 0x49, 0xd7, 0x67, 0x85, + 0xae, 0xf1, 0xf0, 0x38, 0x8e, 0x68, 0x41, 0x0b, 0x30, 0xd1, 0x55, 0x75, 0x16, 0x97, 0xfa, 0x4d, + 0xd2, 0x32, 0xf4, 0xb6, 0xcd, 0xdd, 0x6a, 0xa8, 0x3e, 0x27, 0x00, 0x26, 0xd6, 0xc2, 0x64, 0x1c, + 0xe5, 0x47, 0xef, 0x00, 0x72, 0xa7, 0x71, 0xcf, 0x09, 0xc7, 0xaa, 0xa1, 0x73, 0x9f, 0xcb, 0xfb, + 0xce, 0xbd, 0x19, 0xe3, 0xc0, 0x09, 0x52, 0x68, 0x15, 0x66, 0x2c, 0xb2, 0xaf, 0xb2, 0x39, 0xde, + 0x57, 0x6d, 0x6a, 0x58, 0xfd, 0x55, 0xb5, 0xab, 0xd2, 0xf2, 0x30, 0xb7, 0xa9, 0x7c, 0x74, 0x58, + 0x99, 0xc1, 0x09, 0x74, 0x9c, 0x28, 0x25, 0xff, 0xf7, 0x30, 0x4c, 0x44, 0xe2, 0x0d, 0x7a, 0x00, + 0xb3, 0xad, 0x9e, 0x65, 0x11, 0x9d, 0xae, 0xf7, 0xba, 0xdb, 0xc4, 0x6a, 0xb6, 0x76, 0x49, 0xbb, + 0xa7, 0x91, 0x36, 0x77, 0x94, 0xa1, 0xfa, 0xbc, 0xb0, 0x78, 0x76, 0x31, 0x91, 0x0b, 0xa7, 0x48, + 0xb3, 0x55, 0xd0, 0xf9, 0xd0, 0x9a, 0x6a, 0xdb, 0x1e, 0x66, 0x8e, 0x63, 0x7a, 0xab, 0xb0, 0x1e, + 0xe3, 0xc0, 0x09, 0x52, 0xcc, 0xc6, 0x36, 0xb1, 0x55, 0x8b, 0xb4, 0xa3, 0x36, 0xe6, 0xc3, 0x36, + 0x2e, 0x25, 0x72, 0xe1, 0x14, 0x69, 0x74, 0x13, 0x46, 0x1d, 0x6d, 0x7c, 0xff, 0xc4, 0x46, 0x4f, + 0x0b, 0xb0, 0xd1, 0x75, 0x9f, 0x84, 0x83, 0x7c, 0x6c, 0x6a, 0xc6, 0xb6, 0x4d, 0xac, 0x7d, 0xd2, + 0x4e, 0xdf, 0xe0, 0x8d, 0x18, 0x07, 0x4e, 0x90, 0x62, 0x53, 0x73, 0x3c, 0x30, 0x36, 0xb5, 0xe1, + 0xf0, 0xd4, 0xb6, 0x12, 0xb9, 0x70, 0x8a, 0x34, 0xf3, 0x63, 0xc7, 0xe4, 0x85, 0x7d, 0x45, 0xd5, + 0x94, 0x6d, 0x8d, 0x94, 0x8b, 0x61, 0x3f, 0x5e, 0x0f, 0x93, 0x71, 0x94, 0x1f, 0xdd, 0x83, 0x29, + 0x67, 0x68, 0x4b, 0x57, 0x3c, 0x90, 0x12, 0x07, 0x79, 0x4e, 0x80, 0x4c, 0xad, 0x47, 0x19, 0x70, + 0x5c, 0x06, 0xbd, 0x01, 0xe3, 0x2d, 0x43, 0xd3, 0xb8, 0x3f, 0x2e, 0x1a, 0x3d, 0x9d, 0x96, 0x47, + 0x38, 0x0a, 0x62, 0xe7, 0x71, 0x31, 0x44, 0xc1, 0x11, 0x4e, 0x44, 0x00, 0x5a, 0x6e, 0xc2, 0xb1, + 0xcb, 0xc0, 0xe3, 0xe3, 0xf5, 0xac, 0x31, 0xc0, 0x4b, 0x55, 0x7e, 0x0d, 0xe0, 0x0d, 0xd9, 0x38, + 0x00, 0x2c, 0xff, 0x42, 0x82, 0xb9, 0x94, 0xd0, 0x81, 0xde, 0x0a, 0xa5, 0xd8, 0xbf, 0x8c, 0xa4, + 0xd8, 0x0b, 0x29, 0x62, 0x81, 0x3c, 0xab, 0xc3, 0x98, 0xc5, 0x66, 0xa5, 0x77, 0x1c, 0x16, 0x11, + 0x23, 0x6f, 0x0e, 0x98, 0x06, 0x0e, 0xca, 0xf8, 0x31, 0x7f, 0xea, 0xe8, 0xb0, 0x32, 0x16, 0xa2, + 0xe1, 0x30, 0xbc, 0xfc, 0x3f, 0x39, 0x80, 0x25, 0x62, 0x6a, 0x46, 0xbf, 0x4b, 0xf4, 0xd3, 0xa8, + 0xa1, 0x36, 0x42, 0x35, 0xd4, 0xb5, 0x41, 0xdb, 0xe3, 0x99, 0x96, 0x5a, 0x44, 0xfd, 0x6d, 0xa4, + 0x88, 0xaa, 0x65, 0x87, 0x7c, 0x72, 0x15, 0xf5, 0xab, 0x3c, 0x4c, 0xfb, 0xcc, 0x7e, 0x19, 0x75, + 0x27, 0xb4, 0xc7, 0x7f, 0x11, 0xd9, 0xe3, 0xb9, 0x04, 0x91, 0x67, 0x56, 0x47, 0x3d, 0xfd, 0x7a, + 0x06, 0x3d, 0x84, 0x71, 0x56, 0x38, 0x39, 0xee, 0xc1, 0xcb, 0xb2, 0xe1, 0x63, 0x97, 0x65, 0x5e, + 0x02, 0x5d, 0x0d, 0x21, 0xe1, 0x08, 0x72, 0x4a, 0x19, 0x58, 0x7c, 0xd6, 0x65, 0xa0, 0xfc, 0x85, + 0x04, 0xe3, 0xfe, 0x36, 0x9d, 0x42, 0xd1, 0xb6, 0x1e, 0x2e, 0xda, 0x5e, 0xca, 0xec, 0xa2, 0x29, + 0x55, 0xdb, 0xef, 0x58, 0x81, 0xef, 0x31, 0xb1, 0x03, 0xbe, 0xad, 0xb4, 0xf6, 0xd0, 0x25, 0x28, + 0xe8, 0x4a, 0xd7, 0xf5, 0x4c, 0xef, 0xb0, 0xac, 0x2b, 0x5d, 0x82, 0x39, 0x05, 0x7d, 0x2a, 0x01, + 0x12, 0x59, 0x60, 0x41, 0xd7, 0x0d, 0xaa, 0x38, 0xb1, 0xd2, 0x31, 0x6b, 0x25, 0xb3, 0x59, 0xae, + 0xc6, 0xea, 0x56, 0x0c, 0xeb, 0xae, 0x4e, 0xad, 0xbe, 0xbf, 0x23, 0x71, 0x06, 0x9c, 0x60, 0x00, + 0x52, 0x00, 0x2c, 0x81, 0xb9, 0x69, 0x88, 0x83, 0x7c, 0x2d, 0x43, 0xcc, 0x63, 0x02, 0x8b, 0x86, + 0xbe, 0xa3, 0x76, 0xfc, 0xb0, 0x83, 0x3d, 0x20, 0x1c, 0x00, 0x3d, 0x7f, 0x17, 0xe6, 0x52, 0xac, + 0x45, 0x93, 0x90, 0xdf, 0x23, 0x7d, 0x67, 0xd9, 0x30, 0xfb, 0x13, 0xcd, 0xc0, 0xd0, 0xbe, 0xa2, + 0xf5, 0x9c, 0xf0, 0x3b, 0x82, 0x9d, 0x1f, 0x6f, 0xe4, 0x6e, 0x4b, 0xf2, 0xe7, 0x43, 0x41, 0xdf, + 0xe1, 0x15, 0xf3, 0x15, 0xf6, 0xd1, 0x6a, 0x6a, 0x6a, 0x4b, 0xb1, 0x45, 0x21, 0x74, 0xd6, 0xf9, + 0x60, 0x75, 0xc6, 0xb0, 0x47, 0x0d, 0xd5, 0xd6, 0xb9, 0x67, 0x5b, 0x5b, 0xe7, 0x9f, 0x4e, 0x6d, + 0xfd, 0xf7, 0x50, 0xb2, 0xdd, 0xaa, 0xba, 0xc0, 0x21, 0xaf, 0x1f, 0x23, 0xbe, 0x8a, 0x82, 0xda, + 0x53, 0xe0, 0x95, 0xd2, 0x1e, 0x68, 0x52, 0x11, 0x3d, 0x74, 0xcc, 0x22, 0xfa, 0xa9, 0x16, 0xbe, + 0x2c, 0xa6, 0x9a, 0x4a, 0xcf, 0x26, 0x6d, 0x1e, 0x88, 0x4a, 0x7e, 0x4c, 0x6d, 0xf0, 0x51, 0x2c, + 0xa8, 0xe8, 0x83, 0x90, 0xcb, 0x96, 0x4e, 0xe2, 0xb2, 0xe3, 0xe9, 0xee, 0x8a, 0xb6, 0x60, 0xce, + 0xb4, 0x8c, 0x8e, 0x45, 0x6c, 0x7b, 0x89, 0x28, 0x6d, 0x4d, 0xd5, 0x89, 0xbb, 0x3e, 0x4e, 0x45, + 0x74, 0xe1, 0xe8, 0xb0, 0x32, 0xd7, 0x48, 0x66, 0xc1, 0x69, 0xb2, 0xf2, 0xa3, 0x02, 0x4c, 0x46, + 0x33, 0x60, 0x4a, 0x91, 0x2a, 0x9d, 0xa8, 0x48, 0xbd, 0x1a, 0x38, 0x0c, 0x4e, 0x05, 0x1f, 0xb8, + 0xc1, 0x89, 0x1d, 0x88, 0x05, 0x98, 0x10, 0xd1, 0xc0, 0x25, 0x8a, 0x32, 0xdd, 0xdb, 0xfd, 0xad, + 0x30, 0x19, 0x47, 0xf9, 0x59, 0xe9, 0xe9, 0x57, 0x94, 0x2e, 0x48, 0x21, 0x5c, 0x7a, 0x2e, 0x44, + 0x19, 0x70, 0x5c, 0x06, 0xad, 0xc1, 0x74, 0x4f, 0x8f, 0x43, 0x39, 0xde, 0x78, 0x41, 0x40, 0x4d, + 0x6f, 0xc5, 0x59, 0x70, 0x92, 0x1c, 0xda, 0x09, 0x55, 0xa3, 0xc3, 0x3c, 0xc2, 0xde, 0xc8, 0x7c, + 0x76, 0x32, 0x97, 0xa3, 0xe8, 0x0e, 0x8c, 0x59, 0xfc, 0xbb, 0xc3, 0x35, 0xd8, 0xa9, 0xdd, 0xcf, + 0x09, 0xb1, 0x31, 0x1c, 0x24, 0xe2, 0x30, 0x6f, 0x42, 0xb9, 0x5d, 0xca, 0x5a, 0x6e, 0xcb, 0x3f, + 0x93, 0x82, 0x49, 0xc8, 0x2b, 0x81, 0x07, 0xdd, 0x32, 0xc5, 0x24, 0x02, 0xd5, 0x91, 0x91, 0x5c, + 0xfd, 0xde, 0x3a, 0x56, 0xf5, 0xeb, 0x27, 0xcf, 0xc1, 0xe5, 0xef, 0x67, 0x12, 0xcc, 0x2e, 0x37, + 0xef, 0x59, 0x46, 0xcf, 0x74, 0xcd, 0xd9, 0x30, 0x9d, 0x75, 0x7d, 0x1d, 0x0a, 0x56, 0x4f, 0x73, + 0xe7, 0xf1, 0xa2, 0x3b, 0x0f, 0xdc, 0xd3, 0xd8, 0x3c, 0xa6, 0x23, 0x52, 0xce, 0x24, 0x98, 0x00, + 0x5a, 0x87, 0x61, 0x4b, 0xd1, 0x3b, 0xc4, 0x4d, 0xab, 0x97, 0x07, 0x58, 0xbf, 0xb2, 0x84, 0x19, + 0x7b, 0xa0, 0x78, 0xe3, 0xd2, 0x58, 0xa0, 0xc8, 0xff, 0x2e, 0xc1, 0xc4, 0xfd, 0xcd, 0xcd, 0xc6, + 0x8a, 0xce, 0x4f, 0x34, 0xbf, 0x5b, 0xbd, 0x04, 0x05, 0x53, 0xa1, 0xbb, 0xd1, 0x4c, 0xcf, 0x68, + 0x98, 0x53, 0xd0, 0x7b, 0x50, 0x64, 0x91, 0x84, 0xe8, 0xed, 0x8c, 0xa5, 0xb6, 0x80, 0xaf, 0x3b, + 0x42, 0x7e, 0x85, 0x28, 0x06, 0xb0, 0x0b, 0x27, 0xef, 0xc1, 0x4c, 0xc0, 0x1c, 0xb6, 0x1e, 0x0f, + 0x58, 0x76, 0x44, 0x4d, 0x18, 0x62, 0x9a, 0x59, 0x0e, 0xcc, 0x67, 0xb8, 0xcc, 0x8c, 0x4c, 0xc9, + 0xaf, 0x74, 0xd8, 0x2f, 0x1b, 0x3b, 0x58, 0xf2, 0x1a, 0x8c, 0xf1, 0x0b, 0x65, 0xc3, 0xa2, 0x7c, + 0x59, 0xd0, 0x45, 0xc8, 0x77, 0x55, 0x5d, 0xe4, 0xd9, 0x51, 0x21, 0x93, 0x67, 0x39, 0x82, 0x8d, + 0x73, 0xb2, 0x72, 0x20, 0x22, 0x8f, 0x4f, 0x56, 0x0e, 0x30, 0x1b, 0x97, 0xef, 0x41, 0x51, 0x2c, + 0x77, 0x10, 0x28, 0xff, 0x64, 0xa0, 0x7c, 0x02, 0xd0, 0x06, 0x14, 0x57, 0x1a, 0x75, 0xcd, 0x70, + 0xaa, 0xae, 0x96, 0xda, 0xb6, 0xa2, 0x7b, 0xb1, 0xb8, 0xb2, 0x84, 0x31, 0xa7, 0x20, 0x19, 0x86, + 0xc9, 0x41, 0x8b, 0x98, 0x94, 0x7b, 0xc4, 0x48, 0x1d, 0xd8, 0x2e, 0xdf, 0xe5, 0x23, 0x58, 0x50, + 0xe4, 0xff, 0xc8, 0x41, 0x51, 0x2c, 0xc7, 0x29, 0x7c, 0x85, 0xad, 0x86, 0xbe, 0xc2, 0x5e, 0xce, + 0xe6, 0x1a, 0xa9, 0x9f, 0x60, 0x9b, 0x91, 0x4f, 0xb0, 0xab, 0x19, 0xf1, 0x9e, 0xfc, 0xfd, 0xf5, + 0x63, 0x09, 0xc6, 0xc3, 0x4e, 0x89, 0x6e, 0xc2, 0x28, 0x4b, 0x38, 0x6a, 0x8b, 0xac, 0xfb, 0x75, + 0xae, 0x77, 0x09, 0xd3, 0xf4, 0x49, 0x38, 0xc8, 0x87, 0x3a, 0x9e, 0x18, 0xf3, 0x23, 0x31, 0xe9, + 0xf4, 0x25, 0xed, 0x51, 0x55, 0xab, 0x3a, 0x8f, 0x24, 0xd5, 0x15, 0x9d, 0x6e, 0x58, 0x4d, 0x6a, + 0xa9, 0x7a, 0x27, 0xa6, 0x88, 0x3b, 0x65, 0x10, 0x59, 0xfe, 0xa9, 0x04, 0xa3, 0xc2, 0xe4, 0x53, + 0xf8, 0xaa, 0xf8, 0x9b, 0xf0, 0x57, 0xc5, 0xe5, 0x8c, 0x07, 0x3c, 0xf9, 0x93, 0xe2, 0xff, 0x7d, + 0xd3, 0xd9, 0x91, 0x66, 0x5e, 0xbd, 0x6b, 0xd8, 0x34, 0xea, 0xd5, 0xec, 0x30, 0x62, 0x4e, 0x41, + 0x3d, 0x98, 0x54, 0x23, 0x31, 0x40, 0x2c, 0x6d, 0x2d, 0x9b, 0x25, 0x9e, 0x58, 0xbd, 0x2c, 0xe0, + 0x27, 0xa3, 0x14, 0x1c, 0x53, 0x21, 0x13, 0x88, 0x71, 0xa1, 0x77, 0xa1, 0xb0, 0x4b, 0xa9, 0x99, + 0x70, 0x5f, 0x3d, 0x20, 0xf2, 0xf8, 0x26, 0x94, 0xf8, 0xec, 0x36, 0x37, 0x1b, 0x98, 0x43, 0xc9, + 0xbf, 0xf7, 0xd7, 0xa3, 0xe9, 0xf8, 0xb8, 0x17, 0x4f, 0xa5, 0x93, 0xc4, 0xd3, 0xd1, 0xa4, 0x58, + 0x8a, 0xee, 0x43, 0x9e, 0x6a, 0x59, 0x3f, 0x0b, 0x05, 0xe2, 0xe6, 0x6a, 0xd3, 0x0f, 0x48, 0x9b, + 0xab, 0x4d, 0xcc, 0x20, 0xd0, 0x06, 0x0c, 0xb1, 0xec, 0xc3, 0x8e, 0x60, 0x3e, 0xfb, 0x91, 0x66, + 0xf3, 0xf7, 0x1d, 0x82, 0xfd, 0xb2, 0xb1, 0x83, 0x23, 0x7f, 0x0c, 0x63, 0xa1, 0x73, 0x8a, 0x3e, + 0x82, 0xb3, 0x9a, 0xa1, 0xb4, 0xeb, 0x8a, 0xa6, 0xe8, 0x2d, 0xe2, 0x3e, 0x0e, 0x5c, 0x4e, 0xfa, + 0xc2, 0x58, 0x0d, 0xf0, 0x89, 0x53, 0x3e, 0x23, 0x94, 0x9c, 0x0d, 0xd2, 0x70, 0x08, 0x51, 0x56, + 0x00, 0xfc, 0x39, 0xa2, 0x0a, 0x0c, 0x31, 0x3f, 0x73, 0xf2, 0xc9, 0x48, 0x7d, 0x84, 0x59, 0xc8, + 0xdc, 0xcf, 0xc6, 0xce, 0x38, 0xba, 0x01, 0x60, 0x93, 0x96, 0x45, 0x28, 0x0f, 0x06, 0xb9, 0xf0, + 0x03, 0x63, 0xd3, 0xa3, 0xe0, 0x00, 0x97, 0xfc, 0x73, 0x09, 0xc6, 0xd6, 0x09, 0xfd, 0xc4, 0xb0, + 0xf6, 0x1a, 0x86, 0xa6, 0xb6, 0xfa, 0xa7, 0x10, 0x6c, 0x71, 0x28, 0xd8, 0xbe, 0x32, 0x60, 0x67, + 0x42, 0xd6, 0xa5, 0x85, 0x5c, 0xf9, 0x0b, 0x09, 0xe6, 0x42, 0x9c, 0x77, 0xfd, 0xa3, 0xbb, 0x05, + 0x43, 0xa6, 0x61, 0x51, 0x37, 0x11, 0x1f, 0x4b, 0x21, 0x0b, 0x63, 0x81, 0x54, 0xcc, 0x60, 0xb0, + 0x83, 0x86, 0x56, 0x21, 0x47, 0x0d, 0xe1, 0xaa, 0xc7, 0xc3, 0x24, 0xc4, 0xaa, 0x83, 0xc0, 0xcc, + 0x6d, 0x1a, 0x38, 0x47, 0x0d, 0xb6, 0x11, 0xe5, 0x10, 0x57, 0x30, 0xf8, 0x3c, 0xa3, 0x19, 0x60, + 0x28, 0xec, 0x58, 0x46, 0xf7, 0xc4, 0x73, 0xf0, 0x36, 0x62, 0xd9, 0x32, 0xba, 0x98, 0x63, 0xc9, + 0x5f, 0x4a, 0x30, 0x15, 0xe2, 0x3c, 0x85, 0xc0, 0xff, 0x6e, 0x38, 0xf0, 0x5f, 0x3d, 0xce, 0x44, + 0x52, 0xc2, 0xff, 0x97, 0xb9, 0xc8, 0x34, 0xd8, 0x84, 0xd1, 0x0e, 0x8c, 0x9a, 0x46, 0xbb, 0xf9, + 0x14, 0x9e, 0x03, 0x27, 0x58, 0xde, 0x6c, 0xf8, 0x58, 0x38, 0x08, 0x8c, 0x0e, 0x60, 0x4a, 0x57, + 0xba, 0xc4, 0x36, 0x95, 0x16, 0x69, 0x3e, 0x85, 0x0b, 0x92, 0x73, 0xfc, 0xbd, 0x21, 0x8a, 0x88, + 0xe3, 0x4a, 0xd0, 0x1a, 0x14, 0x55, 0x93, 0xd7, 0x71, 0xa2, 0x76, 0x19, 0x98, 0x45, 0x9d, 0xaa, + 0xcf, 0x89, 0xe7, 0xe2, 0x07, 0x76, 0x31, 0xe4, 0x1f, 0x44, 0xbd, 0x81, 0xf9, 0x1f, 0xba, 0x07, + 0x25, 0xde, 0x62, 0xd1, 0x32, 0x34, 0xf7, 0x65, 0x80, 0xed, 0x6c, 0x43, 0x8c, 0x3d, 0x3e, 0xac, + 0x5c, 0x48, 0xb8, 0xf4, 0x75, 0xc9, 0xd8, 0x13, 0x46, 0xeb, 0x50, 0x30, 0xbf, 0x4f, 0x05, 0xc3, + 0x93, 0x1c, 0x2f, 0x5b, 0x38, 0x8e, 0xfc, 0x4f, 0xf9, 0x88, 0xb9, 0x3c, 0xd5, 0x3d, 0x7c, 0x6a, + 0xbb, 0xee, 0x55, 0x4c, 0xa9, 0x3b, 0xbf, 0x0d, 0x45, 0x91, 0xe1, 0x85, 0x33, 0xbf, 0x7e, 0x1c, + 0x67, 0x0e, 0x66, 0x31, 0xef, 0x83, 0xc5, 0x1d, 0x74, 0x81, 0xd1, 0x87, 0x30, 0x4c, 0x1c, 0x15, + 0x4e, 0x6e, 0xbc, 0x75, 0x1c, 0x15, 0x7e, 0x5c, 0xf5, 0x0b, 0x55, 0x31, 0x26, 0x50, 0xd1, 0x5b, + 0x6c, 0xbd, 0x18, 0x2f, 0xfb, 0x08, 0xb4, 0xcb, 0x05, 0x9e, 0xae, 0x2e, 0x3a, 0xd3, 0xf6, 0x86, + 0x1f, 0x1f, 0x56, 0xc0, 0xff, 0x89, 0x83, 0x12, 0xf2, 0x2f, 0x25, 0x98, 0xe2, 0x2b, 0xd4, 0xea, + 0x59, 0x2a, 0xed, 0x9f, 0x5a, 0x62, 0x7a, 0x10, 0x4a, 0x4c, 0xaf, 0x0d, 0x58, 0x96, 0x98, 0x85, + 0xa9, 0xc9, 0xe9, 0x2b, 0x09, 0xce, 0xc5, 0xb8, 0x4f, 0x21, 0x2e, 0x6e, 0x85, 0xe3, 0xe2, 0x2b, + 0xc7, 0x9d, 0x50, 0x4a, 0x6c, 0xfc, 0xe7, 0xc9, 0x84, 0xe9, 0xf0, 0x93, 0x72, 0x03, 0xc0, 0xb4, + 0xd4, 0x7d, 0x55, 0x23, 0x1d, 0xf1, 0x08, 0x5e, 0x0a, 0xb4, 0x38, 0x79, 0x14, 0x1c, 0xe0, 0x42, + 0x36, 0xcc, 0xb6, 0xc9, 0x8e, 0xd2, 0xd3, 0xe8, 0x42, 0xbb, 0xbd, 0xa8, 0x98, 0xca, 0xb6, 0xaa, + 0xa9, 0x54, 0x15, 0xd7, 0x05, 0x23, 0xf5, 0x3b, 0xce, 0xe3, 0x74, 0x12, 0xc7, 0xe3, 0xc3, 0xca, + 0xc5, 0xa4, 0xd7, 0x21, 0x97, 0xa5, 0x8f, 0x53, 0xa0, 0x51, 0x1f, 0xca, 0x16, 0xf9, 0xb8, 0xa7, + 0x5a, 0xa4, 0xbd, 0x64, 0x19, 0x66, 0x48, 0x6d, 0x9e, 0xab, 0xfd, 0xeb, 0xa3, 0xc3, 0x4a, 0x19, + 0xa7, 0xf0, 0x0c, 0x56, 0x9c, 0x0a, 0x8f, 0x1e, 0xc2, 0xb4, 0xe2, 0x74, 0x86, 0x85, 0xb4, 0x3a, + 0xa7, 0xe4, 0xf6, 0xd1, 0x61, 0x65, 0x7a, 0x21, 0x4e, 0x1e, 0xac, 0x30, 0x09, 0x14, 0xd5, 0xa0, + 0xb8, 0xcf, 0xfb, 0xd6, 0xec, 0xf2, 0x10, 0xc7, 0x67, 0x89, 0xa0, 0xe8, 0xb4, 0xb2, 0x31, 0xcc, + 0xe1, 0xe5, 0x26, 0x3f, 0x7d, 0x2e, 0x17, 0xfb, 0xa0, 0x64, 0xb5, 0xa4, 0x38, 0xf1, 0xfc, 0xc6, + 0xb8, 0xe4, 0x47, 0xad, 0xfb, 0x3e, 0x09, 0x07, 0xf9, 0xd0, 0x07, 0x30, 0xb2, 0x2b, 0x6e, 0x25, + 0xec, 0x72, 0x31, 0x53, 0x12, 0x0e, 0xdd, 0x62, 0xd4, 0xa7, 0x84, 0x8a, 0x11, 0x77, 0xd8, 0xc6, + 0x3e, 0x22, 0x7a, 0x09, 0x8a, 0xfc, 0xc7, 0xca, 0x12, 0xbf, 0x8e, 0x2b, 0xf9, 0xb1, 0xed, 0xbe, + 0x33, 0x8c, 0x5d, 0xba, 0xcb, 0xba, 0xd2, 0x58, 0xe4, 0xd7, 0xc2, 0x11, 0xd6, 0x95, 0xc6, 0x22, + 0x76, 0xe9, 0xe8, 0x23, 0x28, 0xda, 0x64, 0x55, 0xd5, 0x7b, 0x07, 0x65, 0xc8, 0xf4, 0xa8, 0xdc, + 0xbc, 0xcb, 0xb9, 0x23, 0x17, 0x63, 0xbe, 0x06, 0x41, 0xc7, 0x2e, 0x2c, 0xda, 0x85, 0x11, 0xab, + 0xa7, 0x2f, 0xd8, 0x5b, 0x36, 0xb1, 0xca, 0xa3, 0x5c, 0xc7, 0xa0, 0x70, 0x8e, 0x5d, 0xfe, 0xa8, + 0x16, 0x6f, 0x85, 0x3c, 0x0e, 0xec, 0x83, 0xa3, 0x7f, 0x93, 0x00, 0xd9, 0x3d, 0xd3, 0xd4, 0x48, + 0x97, 0xe8, 0x54, 0xd1, 0xf8, 0x5d, 0x9c, 0x5d, 0x3e, 0xcb, 0x75, 0xbe, 0x3d, 0x68, 0x5e, 0x31, + 0xc1, 0xa8, 0x72, 0xef, 0xd2, 0x3b, 0xce, 0x8a, 0x13, 0xf4, 0xb2, 0xa5, 0xdd, 0xb1, 0xf9, 0xdf, + 0xe5, 0xb1, 0x4c, 0x4b, 0x9b, 0x7c, 0xe7, 0xe8, 0x2f, 0xad, 0xa0, 0x63, 0x17, 0x16, 0x3d, 0x80, + 0x59, 0xb7, 0xed, 0x11, 0x1b, 0x06, 0x5d, 0x56, 0x35, 0x62, 0xf7, 0x6d, 0x4a, 0xba, 0xe5, 0x71, + 0xbe, 0xed, 0x5e, 0xef, 0x07, 0x4e, 0xe4, 0xc2, 0x29, 0xd2, 0xa8, 0x0b, 0x15, 0x37, 0x64, 0xb0, + 0xf3, 0xe4, 0xc5, 0xac, 0xbb, 0x76, 0x4b, 0xd1, 0x9c, 0x77, 0x80, 0x09, 0xae, 0xe0, 0xc5, 0xa3, + 0xc3, 0x4a, 0x65, 0xe9, 0xc9, 0xac, 0x78, 0x10, 0x16, 0x7a, 0x0f, 0xca, 0x4a, 0x9a, 0x9e, 0x49, + 0xae, 0xe7, 0x79, 0x16, 0x87, 0x52, 0x15, 0xa4, 0x4a, 0x23, 0x0a, 0x93, 0x4a, 0xb8, 0x01, 0xd5, + 0x2e, 0x4f, 0x65, 0xba, 0x88, 0x8c, 0xf4, 0xad, 0xfa, 0x97, 0x11, 0x11, 0x82, 0x8d, 0x63, 0x1a, + 0xd0, 0x3f, 0x00, 0x52, 0xa2, 0x3d, 0xb3, 0x76, 0x19, 0x65, 0x4a, 0x3f, 0xb1, 0x66, 0x5b, 0xdf, + 0xed, 0x62, 0x24, 0x1b, 0x27, 0xe8, 0x41, 0xab, 0x30, 0x23, 0x46, 0xb7, 0x74, 0x5b, 0xd9, 0x21, + 0xcd, 0xbe, 0xdd, 0xa2, 0x9a, 0x5d, 0x9e, 0xe6, 0xb1, 0x8f, 0x3f, 0x7c, 0x2d, 0x24, 0xd0, 0x71, + 0xa2, 0x14, 0x7a, 0x1b, 0x26, 0x77, 0x0c, 0x6b, 0x5b, 0x6d, 0xb7, 0x89, 0xee, 0x22, 0xcd, 0x70, + 0xa4, 0x19, 0xb6, 0x1a, 0xcb, 0x11, 0x1a, 0x8e, 0x71, 0x23, 0x1b, 0xce, 0x09, 0xe4, 0x86, 0x65, + 0xb4, 0xd6, 0x8c, 0x9e, 0x4e, 0x9d, 0x92, 0xe8, 0x9c, 0x97, 0x62, 0xce, 0x2d, 0x24, 0x31, 0x3c, + 0x3e, 0xac, 0x5c, 0x4a, 0xae, 0x80, 0x7d, 0x26, 0x9c, 0x8c, 0x8d, 0x76, 0x01, 0x78, 0x5c, 0x70, + 0x8e, 0xdf, 0x2c, 0x3f, 0x7e, 0xb7, 0xb3, 0x44, 0x9d, 0xc4, 0x13, 0xe8, 0x3c, 0xc9, 0x79, 0x64, + 0x1c, 0xc0, 0xe6, 0xbd, 0x32, 0xe2, 0xe5, 0xe4, 0x74, 0xfa, 0x8d, 0x8f, 0xd7, 0x2b, 0xe3, 0x9b, + 0xf6, 0xd4, 0x7a, 0x65, 0x02, 0x90, 0x4f, 0xbe, 0xab, 0xfd, 0x6d, 0x0e, 0xa6, 0x7d, 0xe6, 0xcc, + 0xbd, 0x32, 0x09, 0x22, 0x7f, 0xee, 0x39, 0x1e, 0xdc, 0x73, 0xfc, 0x85, 0x04, 0xe3, 0xfe, 0xd2, + 0xfd, 0xf1, 0xf5, 0xaf, 0xf8, 0xb6, 0xa5, 0x54, 0xd4, 0x3f, 0xca, 0x05, 0x27, 0xf0, 0x27, 0xdf, + 0x44, 0xf1, 0xfd, 0x1b, 0x85, 0xe5, 0xaf, 0xf2, 0x30, 0x19, 0x3d, 0x8d, 0xa1, 0xb7, 0x76, 0x69, + 0xe0, 0x5b, 0x7b, 0x03, 0x66, 0x76, 0x7a, 0x9a, 0xd6, 0xe7, 0xcb, 0x10, 0x78, 0x70, 0x77, 0xde, + 0xca, 0x9e, 0x17, 0x92, 0x33, 0xcb, 0x09, 0x3c, 0x38, 0x51, 0x32, 0xa5, 0x6f, 0x20, 0x7f, 0xa2, + 0xbe, 0x81, 0xd8, 0x33, 0x76, 0xe1, 0x18, 0xcf, 0xd8, 0x89, 0x3d, 0x00, 0x43, 0x27, 0xe8, 0x01, + 0x38, 0xc9, 0xa3, 0x7d, 0x42, 0x10, 0x1b, 0xd8, 0x43, 0xfa, 0x3c, 0x9c, 0x17, 0x62, 0x94, 0xbf, + 0xa7, 0xeb, 0xd4, 0x32, 0x34, 0x8d, 0x58, 0x4b, 0xbd, 0x6e, 0xb7, 0x2f, 0xbf, 0x09, 0xe3, 0xe1, + 0x4e, 0x11, 0x67, 0xa7, 0x9d, 0x66, 0x15, 0xf1, 0x62, 0x19, 0xd8, 0x69, 0x67, 0x1c, 0x7b, 0x1c, + 0xf2, 0xbf, 0x48, 0x30, 0x9b, 0xdc, 0x11, 0x8a, 0x34, 0x18, 0xef, 0x2a, 0x07, 0xc1, 0x2e, 0x5d, + 0xe9, 0x84, 0x77, 0x49, 0xbc, 0x45, 0x60, 0x2d, 0x84, 0x85, 0x23, 0xd8, 0xf2, 0x77, 0x12, 0xcc, + 0xa5, 0x3c, 0xce, 0x9f, 0xae, 0x25, 0xe8, 0x7d, 0x28, 0x75, 0x95, 0x83, 0x66, 0xcf, 0xea, 0x90, + 0x13, 0xdf, 0x9e, 0xf1, 0x88, 0xb1, 0x26, 0x50, 0xb0, 0x87, 0x27, 0xff, 0x9f, 0x04, 0xcf, 0xa5, + 0x56, 0x14, 0xe8, 0x56, 0xa8, 0x8f, 0x40, 0x8e, 0xf4, 0x11, 0xa0, 0xb8, 0xe0, 0x33, 0x6a, 0x23, + 0xf8, 0x4c, 0x82, 0x72, 0xda, 0xd7, 0x16, 0xba, 0x19, 0x32, 0xf2, 0x85, 0x88, 0x91, 0x53, 0x31, + 0xb9, 0x67, 0x64, 0xe3, 0x0f, 0x25, 0x98, 0x4d, 0xfe, 0xea, 0x44, 0xaf, 0x86, 0x2c, 0xac, 0x44, + 0x2c, 0x9c, 0x88, 0x48, 0x09, 0xfb, 0x3e, 0x84, 0x71, 0xf1, 0x6d, 0x2a, 0x60, 0xc4, 0xde, 0xcb, + 0x49, 0x11, 0x5d, 0x40, 0xb8, 0x95, 0x20, 0xf7, 0xaa, 0xf0, 0x18, 0x8e, 0xa0, 0xc9, 0xff, 0x9a, + 0x83, 0xa1, 0x66, 0x4b, 0xd1, 0xc8, 0x29, 0x14, 0x83, 0xef, 0x84, 0x8a, 0xc1, 0x41, 0xff, 0xf7, + 0xc3, 0xad, 0x4a, 0xad, 0x03, 0x71, 0xa4, 0x0e, 0x7c, 0x39, 0x13, 0xda, 0x93, 0x4b, 0xc0, 0xbf, + 0x82, 0x11, 0x4f, 0xe9, 0xf1, 0x32, 0x93, 0xfc, 0xbf, 0x39, 0x18, 0x0d, 0xa8, 0x38, 0x66, 0x5e, + 0xdb, 0x09, 0xd5, 0x03, 0xf9, 0x0c, 0xe5, 0x7f, 0x40, 0x57, 0xd5, 0xad, 0x00, 0x9c, 0xbe, 0x55, + 0xbf, 0x53, 0x31, 0x5e, 0x18, 0xbc, 0x09, 0xe3, 0x54, 0xb1, 0x3a, 0x84, 0x7a, 0x37, 0xe3, 0x79, + 0xee, 0x8b, 0x5e, 0xb7, 0xf3, 0x66, 0x88, 0x8a, 0x23, 0xdc, 0xe7, 0xef, 0xc0, 0x58, 0x48, 0xd9, + 0xb1, 0xda, 0x4e, 0x7f, 0x22, 0xc1, 0x0b, 0x03, 0xef, 0x2d, 0x50, 0x3d, 0x74, 0x48, 0xaa, 0x91, + 0x43, 0x32, 0x9f, 0x0e, 0xf0, 0xec, 0xda, 0x97, 0xea, 0xd7, 0x1e, 0x7d, 0x3b, 0x7f, 0xe6, 0xeb, + 0x6f, 0xe7, 0xcf, 0x7c, 0xf3, 0xed, 0xfc, 0x99, 0x7f, 0x3c, 0x9a, 0x97, 0x1e, 0x1d, 0xcd, 0x4b, + 0x5f, 0x1f, 0xcd, 0x4b, 0xdf, 0x1c, 0xcd, 0x4b, 0xbf, 0x3e, 0x9a, 0x97, 0xfe, 0xf3, 0xbb, 0xf9, + 0x33, 0xef, 0x17, 0x05, 0xdc, 0x1f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x51, 0x7e, 0x9f, 0x62, 0x14, + 0x3c, 0x00, 0x00, } diff --git a/staging/src/k8s.io/api/extensions/v1beta1/generated.proto b/staging/src/k8s.io/api/extensions/v1beta1/generated.proto index 84fe2a70374f7..efcda7ebdea58 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/extensions/v1beta1/generated.proto @@ -22,7 +22,6 @@ syntax = 'proto2'; package k8s.io.api.extensions.v1beta1; import "k8s.io/api/core/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/api/resource/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; @@ -45,7 +44,7 @@ message AllowedHostPath { // pathPrefix is the path prefix that the host volume must match. // It does not support `*`. // Trailing slashes are trimmed when validating the path prefix with a host path. - // + // // Examples: // `/foo` would allow `/foo`, `/foo/` and `/foo/bar` // `/foo` would not allow `/food` or `/etc/foo` @@ -56,31 +55,6 @@ message AllowedHostPath { optional bool readOnly = 2; } -message CustomMetricCurrentStatus { - // Custom Metric name. - optional string name = 1; - - // Custom Metric value (average). - optional k8s.io.apimachinery.pkg.api.resource.Quantity value = 2; -} - -message CustomMetricCurrentStatusList { - repeated CustomMetricCurrentStatus items = 1; -} - -// Alpha-level support for Custom Metrics in HPA (as annotations). -message CustomMetricTarget { - // Custom Metric name. - optional string name = 1; - - // Custom Metric value (average). - optional k8s.io.apimachinery.pkg.api.resource.Quantity value = 2; -} - -message CustomMetricTargetList { - repeated CustomMetricTarget items = 1; -} - // DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for // more information. // DaemonSet represents the configuration of a daemon set. @@ -690,7 +664,7 @@ message NetworkPolicyList { message NetworkPolicyPeer { // This is a label selector which selects Pods. This field follows standard label // selector semantics; if present but empty, it selects all pods. - // + // // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. @@ -699,7 +673,7 @@ message NetworkPolicyPeer { // Selects Namespaces using cluster-scoped labels. This field follows standard label // selector semantics; if present but empty, it selects all namespaces. - // + // // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. @@ -894,7 +868,7 @@ message PodSecurityPolicySpec { // Each entry is either a plain sysctl name or ends in "*" in which case it is considered // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. // Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection. - // + // // Examples: // e.g. "foo/*" allows "foo/bar", "foo/baz", etc. // e.g. "foo.*" allows "foo.bar", "foo.baz", etc. @@ -904,7 +878,7 @@ message PodSecurityPolicySpec { // forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. // Each entry is either a plain sysctl name or ends in "*" in which case it is considered // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. - // + // // Examples: // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. diff --git a/staging/src/k8s.io/api/extensions/v1beta1/types.go b/staging/src/k8s.io/api/extensions/v1beta1/types.go index 63c78e2f58d73..5ba6f95854528 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/types.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/types.go @@ -19,7 +19,6 @@ package v1beta1 import ( appsv1beta1 "k8s.io/api/apps/v1beta1" "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -50,8 +49,6 @@ type ScaleStatus struct { TargetSelector string `json:"targetSelector,omitempty" protobuf:"bytes,3,opt,name=targetSelector"` } -// +genclient -// +genclient:noVerbs // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // represents a scaling request for a resource. @@ -77,29 +74,6 @@ type ReplicationControllerDummy struct { metav1.TypeMeta `json:",inline"` } -// Alpha-level support for Custom Metrics in HPA (as annotations). -type CustomMetricTarget struct { - // Custom Metric name. - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Custom Metric value (average). - TargetValue resource.Quantity `json:"value" protobuf:"bytes,2,opt,name=value"` -} - -type CustomMetricTargetList struct { - Items []CustomMetricTarget `json:"items" protobuf:"bytes,1,rep,name=items"` -} - -type CustomMetricCurrentStatus struct { - // Custom Metric name. - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Custom Metric value (average). - CurrentValue resource.Quantity `json:"value" protobuf:"bytes,2,opt,name=value"` -} - -type CustomMetricCurrentStatusList struct { - Items []CustomMetricCurrentStatus `json:"items" protobuf:"bytes,1,rep,name=items"` -} - // +genclient // +genclient:method=GetScale,verb=get,subresource=scale,result=Scale // +genclient:method=UpdateScale,verb=update,subresource=scale,input=Scale,result=Scale diff --git a/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go index a6f5aaeeed6bc..bce6036cd5d21 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go @@ -46,25 +46,6 @@ func (AllowedHostPath) SwaggerDoc() map[string]string { return map_AllowedHostPath } -var map_CustomMetricCurrentStatus = map[string]string{ - "name": "Custom Metric name.", - "value": "Custom Metric value (average).", -} - -func (CustomMetricCurrentStatus) SwaggerDoc() map[string]string { - return map_CustomMetricCurrentStatus -} - -var map_CustomMetricTarget = map[string]string{ - "": "Alpha-level support for Custom Metrics in HPA (as annotations).", - "name": "Custom Metric name.", - "value": "Custom Metric value (average).", -} - -func (CustomMetricTarget) SwaggerDoc() map[string]string { - return map_CustomMetricTarget -} - var map_DaemonSet = map[string]string{ "": "DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for more information. DaemonSet represents the configuration of a daemon set.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata", diff --git a/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go index 0e4e82fafbad4..8128c079b482b 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go @@ -59,86 +59,6 @@ func (in *AllowedHostPath) DeepCopy() *AllowedHostPath { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomMetricCurrentStatus) DeepCopyInto(out *CustomMetricCurrentStatus) { - *out = *in - out.CurrentValue = in.CurrentValue.DeepCopy() - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricCurrentStatus. -func (in *CustomMetricCurrentStatus) DeepCopy() *CustomMetricCurrentStatus { - if in == nil { - return nil - } - out := new(CustomMetricCurrentStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomMetricCurrentStatusList) DeepCopyInto(out *CustomMetricCurrentStatusList) { - *out = *in - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]CustomMetricCurrentStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricCurrentStatusList. -func (in *CustomMetricCurrentStatusList) DeepCopy() *CustomMetricCurrentStatusList { - if in == nil { - return nil - } - out := new(CustomMetricCurrentStatusList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomMetricTarget) DeepCopyInto(out *CustomMetricTarget) { - *out = *in - out.TargetValue = in.TargetValue.DeepCopy() - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricTarget. -func (in *CustomMetricTarget) DeepCopy() *CustomMetricTarget { - if in == nil { - return nil - } - out := new(CustomMetricTarget) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomMetricTargetList) DeepCopyInto(out *CustomMetricTargetList) { - *out = *in - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]CustomMetricTarget, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricTargetList. -func (in *CustomMetricTargetList) DeepCopy() *CustomMetricTargetList { - if in == nil { - return nil - } - out := new(CustomMetricTargetList) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DaemonSet) DeepCopyInto(out *DaemonSet) { *out = *in diff --git a/staging/src/k8s.io/api/imagepolicy/OWNERS b/staging/src/k8s.io/api/imagepolicy/OWNERS index 96ae42e027a01..02b8511e46556 100755 --- a/staging/src/k8s.io/api/imagepolicy/OWNERS +++ b/staging/src/k8s.io/api/imagepolicy/OWNERS @@ -1,4 +1,7 @@ +# approval on api packages bubbles to api-approvers reviewers: -- deads2k -- mbohlool -- jianhuiz +- sig-auth-policy-approvers +- sig-auth-policy-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/api/networking/v1/generated.proto b/staging/src/k8s.io/api/networking/v1/generated.proto index 4e068d08f03c6..ab3731e9c3994 100644 --- a/staging/src/k8s.io/api/networking/v1/generated.proto +++ b/staging/src/k8s.io/api/networking/v1/generated.proto @@ -114,7 +114,7 @@ message NetworkPolicyList { message NetworkPolicyPeer { // This is a label selector which selects Pods. This field follows standard label // selector semantics; if present but empty, it selects all pods. - // + // // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. @@ -123,7 +123,7 @@ message NetworkPolicyPeer { // Selects Namespaces using cluster-scoped labels. This field follows standard label // selector semantics; if present but empty, it selects all namespaces. - // + // // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. diff --git a/staging/src/k8s.io/api/policy/OWNERS b/staging/src/k8s.io/api/policy/OWNERS index 872e16329b0ad..61a5da4cf3e5b 100755 --- a/staging/src/k8s.io/api/policy/OWNERS +++ b/staging/src/k8s.io/api/policy/OWNERS @@ -1,7 +1,8 @@ -approvers: -- sig-apps-api-approvers +# approval on api packages bubbles to api-approvers reviewers: - sig-apps-reviewers -- pweil- -- liggitt -- tallclair +- sig-auth-policy-approvers +- sig-auth-policy-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/api/policy/v1beta1/generated.proto b/staging/src/k8s.io/api/policy/v1beta1/generated.proto index b6f147d1b5516..e9df3c16fe4c3 100644 --- a/staging/src/k8s.io/api/policy/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/policy/v1beta1/generated.proto @@ -42,7 +42,7 @@ message AllowedHostPath { // pathPrefix is the path prefix that the host volume must match. // It does not support `*`. // Trailing slashes are trimmed when validating the path prefix with a host path. - // + // // Examples: // `/foo` would allow `/foo`, `/foo/` and `/foo/bar` // `/foo` would not allow `/food` or `/etc/foo` @@ -58,9 +58,11 @@ message AllowedHostPath { // created by POSTing to .../pods//evictions. message Eviction { // ObjectMeta describes the pod that is being evicted. + // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // DeleteOptions may be provided + // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.DeleteOptions deleteOptions = 2; } @@ -97,17 +99,21 @@ message IDRange { // PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods message PodDisruptionBudget { + // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // Specification of the desired behavior of the PodDisruptionBudget. + // +optional optional PodDisruptionBudgetSpec spec = 2; // Most recently observed status of the PodDisruptionBudget. + // +optional optional PodDisruptionBudgetStatus status = 3; } // PodDisruptionBudgetList is a collection of PodDisruptionBudgets. message PodDisruptionBudgetList { + // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; repeated PodDisruptionBudget items = 2; @@ -119,16 +125,19 @@ message PodDisruptionBudgetSpec { // "selector" will still be available after the eviction, i.e. even in the // absence of the evicted pod. So for example you can prevent all voluntary // evictions by specifying "100%". + // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString minAvailable = 1; // Label query over pods whose evictions are managed by the disruption // budget. + // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; // An eviction is allowed if at most "maxUnavailable" pods selected by // "selector" are unavailable after the eviction, i.e. even in absence of // the evicted pod. For example, one can prevent all voluntary evictions // by specifying 0. This is a mutually exclusive setting with "minAvailable". + // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxUnavailable = 3; } @@ -287,7 +296,7 @@ message PodSecurityPolicySpec { // Each entry is either a plain sysctl name or ends in "*" in which case it is considered // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. // Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection. - // + // // Examples: // e.g. "foo/*" allows "foo/bar", "foo/baz", etc. // e.g. "foo.*" allows "foo.bar", "foo.baz", etc. @@ -297,7 +306,7 @@ message PodSecurityPolicySpec { // forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. // Each entry is either a plain sysctl name or ends in "*" in which case it is considered // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. - // + // // Examples: // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. diff --git a/staging/src/k8s.io/api/policy/v1beta1/types.go b/staging/src/k8s.io/api/policy/v1beta1/types.go index 808d6fd061755..91ea1185878a5 100644 --- a/staging/src/k8s.io/api/policy/v1beta1/types.go +++ b/staging/src/k8s.io/api/policy/v1beta1/types.go @@ -28,16 +28,19 @@ type PodDisruptionBudgetSpec struct { // "selector" will still be available after the eviction, i.e. even in the // absence of the evicted pod. So for example you can prevent all voluntary // evictions by specifying "100%". + // +optional MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty" protobuf:"bytes,1,opt,name=minAvailable"` // Label query over pods whose evictions are managed by the disruption // budget. + // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"` // An eviction is allowed if at most "maxUnavailable" pods selected by // "selector" are unavailable after the eviction, i.e. even in absence of // the evicted pod. For example, one can prevent all voluntary evictions // by specifying 0. This is a mutually exclusive setting with "minAvailable". + // +optional MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,3,opt,name=maxUnavailable"` } @@ -81,12 +84,15 @@ type PodDisruptionBudgetStatus struct { // PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods type PodDisruptionBudget struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Specification of the desired behavior of the PodDisruptionBudget. + // +optional Spec PodDisruptionBudgetSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` // Most recently observed status of the PodDisruptionBudget. + // +optional Status PodDisruptionBudgetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -95,6 +101,7 @@ type PodDisruptionBudget struct { // PodDisruptionBudgetList is a collection of PodDisruptionBudgets. type PodDisruptionBudgetList struct { metav1.TypeMeta `json:",inline"` + // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` Items []PodDisruptionBudget `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -110,9 +117,11 @@ type Eviction struct { metav1.TypeMeta `json:",inline"` // ObjectMeta describes the pod that is being evicted. + // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // DeleteOptions may be provided + // +optional DeleteOptions *metav1.DeleteOptions `json:"deleteOptions,omitempty" protobuf:"bytes,2,opt,name=deleteOptions"` } @@ -250,13 +259,13 @@ type AllowedHostPath struct { ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,2,opt,name=readOnly"` } -// FSType gives strong typing to different file systems that are used by volumes. -type FSType string - // AllowAllCapabilities can be used as a value for the PodSecurityPolicy.AllowAllCapabilities // field and means that any capabilities are allowed to be requested. var AllowAllCapabilities v1.Capability = "*" +// FSType gives strong typing to different file systems that are used by volumes. +type FSType string + var ( AzureFile FSType = "azureFile" Flocker FSType = "flocker" diff --git a/staging/src/k8s.io/api/rbac/OWNERS b/staging/src/k8s.io/api/rbac/OWNERS index 45b66b0a8ca25..ff4a7f4bf9ad0 100755 --- a/staging/src/k8s.io/api/rbac/OWNERS +++ b/staging/src/k8s.io/api/rbac/OWNERS @@ -1,16 +1,7 @@ +# approval on api packages bubbles to api-approvers reviewers: -- thockin -- lavalamp -- smarterclayton -- deads2k -- sttts -- ncdc -- dims -- krousey -- mml -- mbohlool -- david-mcmahon -- lixiaobing10051267 -- jianhuiz -- liggitt -- enj +- sig-auth-authorizers-approvers +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/api/storage/v1/generated.proto b/staging/src/k8s.io/api/storage/v1/generated.proto index d1785659c02ab..1b8102c05392b 100644 --- a/staging/src/k8s.io/api/storage/v1/generated.proto +++ b/staging/src/k8s.io/api/storage/v1/generated.proto @@ -31,7 +31,7 @@ option go_package = "v1"; // StorageClass describes the parameters for a class of storage for // which PersistentVolumes can be dynamically provisioned. -// +// // StorageClasses are non-namespaced; the name of the storage class // according to etcd is in ObjectMeta.Name. message StorageClass { diff --git a/staging/src/k8s.io/api/storage/v1alpha1/generated.proto b/staging/src/k8s.io/api/storage/v1alpha1/generated.proto index ccb947540f118..fdc4ad257d39f 100644 --- a/staging/src/k8s.io/api/storage/v1alpha1/generated.proto +++ b/staging/src/k8s.io/api/storage/v1alpha1/generated.proto @@ -30,7 +30,7 @@ option go_package = "v1alpha1"; // VolumeAttachment captures the intent to attach or detach the specified volume // to/from the specified node. -// +// // VolumeAttachment objects are non-namespaced. message VolumeAttachment { // Standard object metadata. diff --git a/staging/src/k8s.io/api/storage/v1beta1/generated.proto b/staging/src/k8s.io/api/storage/v1beta1/generated.proto index ecf53bef60e6c..db1f302a053a0 100644 --- a/staging/src/k8s.io/api/storage/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/storage/v1beta1/generated.proto @@ -31,7 +31,7 @@ option go_package = "v1beta1"; // StorageClass describes the parameters for a class of storage for // which PersistentVolumes can be dynamically provisioned. -// +// // StorageClasses are non-namespaced; the name of the storage class // according to etcd is in ObjectMeta.Name. message StorageClass { @@ -90,7 +90,7 @@ message StorageClassList { // VolumeAttachment captures the intent to attach or detach the specified volume // to/from the specified node. -// +// // VolumeAttachment objects are non-namespaced. message VolumeAttachment { // Standard object metadata. diff --git a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json index 8de05fd42f47b..8a52adb8c6458 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json @@ -32,7 +32,7 @@ }, { "ImportPath": "github.com/asaskevich/govalidator", - "Rev": "593d64559f7600f29581a3ee42177f5dbded27a9" + "Rev": "f9ffefc3facfbe0caee3fea233cbb6e8208f4541" }, { "ImportPath": "github.com/beorn7/perks/quantile", @@ -44,311 +44,311 @@ }, { "ImportPath": "github.com/coreos/etcd/alarm", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/auth", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/client", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/concurrency", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/namespace", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/naming", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/compactor", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/discovery", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/embed", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/error", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/etcdhttp", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2v3", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3client", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/auth", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb/gw", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/membership", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/stats", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/integration", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease/leasehttp", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease/leasepb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc/backend", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/adt", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/contention", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/cors", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/cpuutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/crc", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/debugutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/httputil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/idutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/ioutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/logutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/netutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/pbutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/runtime", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/schedule", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/srv", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/testutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/wait", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/adapter", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/cache", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/raft", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/raft/raftpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/rafthttp", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/snap", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/snap/snappb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/store", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/version", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/wal", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/wal/walpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/go-semver/semver", - "Rev": "568e959cd89871e61434c1143528d9162da89ef2" + "Rev": "e214231b295a8ea9479f11b70b35d5acf3556d9b" }, { "ImportPath": "github.com/coreos/go-systemd/daemon", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/coreos/go-systemd/journal", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/coreos/pkg/capnslog", - "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" + "Rev": "97fdf19511ea361ae1c100dd393cc47f8dcfa1e1" }, { "ImportPath": "github.com/davecgh/go-spew/spew", @@ -390,45 +390,57 @@ "ImportPath": "github.com/ghodss/yaml", "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577" }, + { + "ImportPath": "github.com/globalsign/mgo/bson", + "Rev": "eeefdecb41b842af6dc652aaea4026e8403e62df" + }, + { + "ImportPath": "github.com/globalsign/mgo/internal/json", + "Rev": "eeefdecb41b842af6dc652aaea4026e8403e62df" + }, { "ImportPath": "github.com/go-openapi/analysis", - "Rev": "b44dc874b601d9e4e2f6e19140e794ba24bead3b" + "Rev": "c701774f4e604d952e4e8c56dee260be696e33c3" + }, + { + "ImportPath": "github.com/go-openapi/analysis/internal", + "Rev": "c701774f4e604d952e4e8c56dee260be696e33c3" }, { "ImportPath": "github.com/go-openapi/errors", - "Rev": "d24ebc2075bad502fac3a8ae27aa6dd58e1952dc" + "Rev": "d9664f9fab8994271e573ed69cf2adfc09b7a800" }, { "ImportPath": "github.com/go-openapi/jsonpointer", - "Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98" + "Rev": "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004" }, { "ImportPath": "github.com/go-openapi/jsonreference", - "Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272" + "Rev": "8483a886a90412cd6858df4ea3483dce9c8e35a3" }, { "ImportPath": "github.com/go-openapi/loads", - "Rev": "a80dea3052f00e5f032e860dd7355cd0cc67e24d" + "Rev": "150d36912387ec2f607be674c5be309ddccc0eed" }, { "ImportPath": "github.com/go-openapi/runtime", - "Rev": "11e322eeecc1032d5a0a96c566ed53f2b5c26e22" + "Rev": "231d7876b7019dbcbfc97a7ba764379497b67c1d" }, { "ImportPath": "github.com/go-openapi/spec", - "Rev": "1de3e0542de65ad8d75452a595886fdd0befb363" + "Rev": "5bae59e25b21498baea7f9d46e9c147ec106a42e" }, { "ImportPath": "github.com/go-openapi/strfmt", - "Rev": "d65c7fdb29eca313476e529628176fe17e58c488" + "Rev": "35fe47352985e13cc75f13120d70d26fd764ed51" }, { "ImportPath": "github.com/go-openapi/swag", - "Rev": "f3f9494671f93fcff853e3c6e9e948b3eb71e590" + "Rev": "5899d5c5e619fda5fa86e14795a835f473ca284c" }, { "ImportPath": "github.com/go-openapi/validate", - "Rev": "d509235108fcf6ab4913d2dcb3a2260c0db2108e" + "Rev": "d2eab7d93009e9215fc85b2faa2c2f2a98c2af48" }, { "ImportPath": "github.com/gogo/protobuf/gogoproto", @@ -514,6 +526,10 @@ "ImportPath": "github.com/gregjones/httpcache/diskcache", "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" }, + { + "ImportPath": "github.com/grpc-ecosystem/go-grpc-middleware", + "Rev": "498ae206fc3cfe81cd82e48c1d4354026fa5f9ec" + }, { "ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus", "Rev": "2500245aa6110c562d17020fb31a2c133d737799" @@ -570,6 +586,10 @@ "ImportPath": "github.com/matttproud/golang_protobuf_extensions/pbutil", "Rev": "c12348ce28de40eed0136aa2b644d0ee0650e56c" }, + { + "ImportPath": "github.com/mitchellh/mapstructure", + "Rev": "53818660ed4955e899c0bcafa97299a388bd7c8e" + }, { "ImportPath": "github.com/modern-go/concurrent", "Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94" @@ -658,6 +678,38 @@ "ImportPath": "github.com/xiang90/probing", "Rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2" }, + { + "ImportPath": "go.uber.org/atomic", + "Rev": "8dc6146f7569370a472715e178d8ae31172ee6da" + }, + { + "ImportPath": "go.uber.org/multierr", + "Rev": "ddea229ff1dff9e6fe8a6c0344ac73b09e81fce5" + }, + { + "ImportPath": "go.uber.org/zap", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/buffer", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/bufferpool", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/color", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/exit", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/zapcore", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, { "ImportPath": "golang.org/x/crypto/bcrypt", "Rev": "de0752318171da717af4ce24d0a2e8626afaeb11" @@ -672,35 +724,35 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/internal/timeseries", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/trace", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/websocket", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -1354,6 +1406,10 @@ "ImportPath": "k8s.io/apiserver/pkg/authentication/serviceaccount", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/apiserver/pkg/authentication/token/cache", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/token/tokenfile", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -2156,23 +2212,23 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer", @@ -2386,10 +2442,18 @@ "ImportPath": "k8s.io/apiserver/pkg/util/feature", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/apiserver/pkg/util/feature/testing", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/apiserver/pkg/util/logs", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/apiserver/pkg/util/webhook", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/client-go/discovery", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/OWNERS b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/OWNERS new file mode 100644 index 0000000000000..bae178f8175ea --- /dev/null +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/OWNERS @@ -0,0 +1,9 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go index ff8cc033469a3..b948e61791701 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go @@ -61,6 +61,11 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { {Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"}, } } + if obj.Conversion == nil { + obj.Conversion = &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.NoneConverter, + } + } }, func(obj *apiextensions.CustomResourceDefinition, c fuzz.Continue) { c.FuzzNoCustom(obj) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go index 6fc75154fac00..fcbd8bd197aea 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go @@ -20,6 +20,16 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// ConversionStrategyType describes different conversion types. +type ConversionStrategyType string + +const ( + // NoneConverter is a converter that only sets apiversion of the CR and leave everything else unchanged. + NoneConverter ConversionStrategyType = "None" + // WebhookConverter is a converter that calls to an external webhook to convert the CR. + WebhookConverter ConversionStrategyType = "Webhook" +) + // CustomResourceDefinitionSpec describes how a user wants their resource to appear type CustomResourceDefinitionSpec struct { // Group is the group this resource belongs in @@ -34,8 +44,14 @@ type CustomResourceDefinitionSpec struct { // Scope indicates whether this resource is cluster or namespace scoped. Default is namespaced Scope ResourceScope // Validation describes the validation methods for CustomResources + // Optional, the global validation schema for all versions. + // Top-level and per-version schemas are mutually exclusive. + // +optional Validation *CustomResourceValidation - // Subresources describes the subresources for CustomResources + // Subresources describes the subresources for CustomResource + // Optional, the global subresources for all versions. + // Top-level and per-version subresources are mutually exclusive. + // +optional Subresources *CustomResourceSubresources // Versions is the list of all supported versions for this resource. // If Version field is provided, this field is optional. @@ -50,9 +66,90 @@ type CustomResourceDefinitionSpec struct { // v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10. Versions []CustomResourceDefinitionVersion // AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column. + // Optional, the global columns for all versions. + // Top-level and per-version columns are mutually exclusive. + // +optional AdditionalPrinterColumns []CustomResourceColumnDefinition + + // `conversion` defines conversion settings for the CRD. + Conversion *CustomResourceConversion } +// CustomResourceConversion describes how to convert different versions of a CR. +type CustomResourceConversion struct { + // `strategy` specifies the conversion strategy. Allowed values are: + // - `None`: The converter only change the apiVersion and would not touch any other field in the CR. + // - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option. + Strategy ConversionStrategyType + + // `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`. + WebhookClientConfig *WebhookClientConfig +} + +// WebhookClientConfig contains the information to make a TLS +// connection with the webhook. It has the same field as admissionregistration.internal.WebhookClientConfig. +type WebhookClientConfig struct { + // `url` gives the location of the webhook, in standard URL form + // (`scheme://host:port/path`). Exactly one of `url` or `service` + // must be specified. + // + // The `host` should not refer to a service running in the cluster; use + // the `service` field instead. The host might be resolved via external + // DNS in some apiservers (e.g., `kube-apiserver` cannot resolve + // in-cluster DNS as that would be a layering violation). `host` may + // also be an IP address. + // + // Please note that using `localhost` or `127.0.0.1` as a `host` is + // risky unless you take great care to run this webhook on all hosts + // which run an apiserver which might need to make calls to this + // webhook. Such installs are likely to be non-portable, i.e., not easy + // to turn up in a new cluster. + // + // The scheme must be "https"; the URL must begin with "https://". + // + // A path is optional, and if present may be any string permissible in + // a URL. You may use the path to pass an arbitrary string to the + // webhook, for example, a cluster identifier. + // + // Attempting to use a user or basic auth e.g. "user:password@" is not + // allowed. Fragments ("#...") and query parameters ("?...") are not + // allowed, either. + // + // +optional + URL *string + + // `service` is a reference to the service for this webhook. Either + // `service` or `url` must be specified. + // + // If the webhook is running within the cluster, then you should use `service`. + // + // Port 443 will be used if it is open, otherwise it is an error. + // + // +optional + Service *ServiceReference + + // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // If unspecified, system trust roots on the apiserver are used. + // +optional + CABundle []byte +} + +// ServiceReference holds a reference to Service.legacy.k8s.io +type ServiceReference struct { + // `namespace` is the namespace of the service. + // Required + Namespace string + // `name` is the name of the service. + // Required + Name string + + // `path` is an optional URL path which will be sent in any request to + // this service. + // +optional + Path *string +} + +// CustomResourceDefinitionVersion describes a version for CRD. type CustomResourceDefinitionVersion struct { // Name is the version name, e.g. “v1”, “v2beta1”, etc. Name string @@ -61,6 +158,27 @@ type CustomResourceDefinitionVersion struct { // Storage flags the version as storage version. There must be exactly one flagged // as storage version. Storage bool + // Schema describes the schema for CustomResource used in validation, pruning, and defaulting. + // Top-level and per-version schemas are mutually exclusive. + // Per-version schemas must not all be set to identical values (top-level validation schema should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // +optional + Schema *CustomResourceValidation + // Subresources describes the subresources for CustomResource + // Top-level and per-version subresources are mutually exclusive. + // Per-version subresources must not all be set to identical values (top-level subresources should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // +optional + Subresources *CustomResourceSubresources + // AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column. + // Top-level and per-version columns are mutually exclusive. + // Per-version columns must not all be set to identical values (top-level columns should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // NOTE: CRDs created prior to 1.13 populated the top-level additionalPrinterColumns field by default. To apply an + // update that changes to per-version additionalPrinterColumns, the top-level additionalPrinterColumns field must + // be explicitly set to null + // +optional + AdditionalPrinterColumns []CustomResourceColumnDefinition } // CustomResourceColumnDefinition specifies a column for server side printing. diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/BUILD b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/BUILD index 3aedf66109758..6abba9ae8a6a6 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/BUILD +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/BUILD @@ -30,6 +30,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library", "//vendor/github.com/gogo/protobuf/proto:go_default_library", "//vendor/github.com/gogo/protobuf/sortkeys:go_default_library", diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/defaults.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/defaults.go index e3235e8702c31..5aae97cf1a266 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/defaults.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/defaults.go @@ -19,12 +19,9 @@ package v1beta1 import ( "strings" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) -var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc() - func addDefaultingFuncs(scheme *runtime.Scheme) error { scheme.AddTypeDefaultingFunc(&CustomResourceDefinition{}, func(obj interface{}) { SetDefaults_CustomResourceDefinition(obj.(*CustomResourceDefinition)) }) // TODO figure out why I can't seem to get my defaulter generated @@ -66,9 +63,19 @@ func SetDefaults_CustomResourceDefinitionSpec(obj *CustomResourceDefinitionSpec) if len(obj.Version) == 0 && len(obj.Versions) != 0 { obj.Version = obj.Versions[0].Name } - if len(obj.AdditionalPrinterColumns) == 0 { - obj.AdditionalPrinterColumns = []CustomResourceColumnDefinition{ - {Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"}, + if obj.Conversion == nil { + obj.Conversion = &CustomResourceConversion{ + Strategy: NoneConverter, + } + } +} + +// hasPerVersionColumns returns true if a CRD uses per-version columns. +func hasPerVersionColumns(versions []CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if len(v.AdditionalPrinterColumns) > 0 { + return true } } + return false } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go index 7649c78de27bc..ef2dfe16aa6d6 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go @@ -24,7 +24,11 @@ limitations under the License. k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto It has these top-level messages: + ConversionRequest + ConversionResponse + ConversionReview CustomResourceColumnDefinition + CustomResourceConversion CustomResourceDefinition CustomResourceDefinitionCondition CustomResourceDefinitionList @@ -42,6 +46,8 @@ limitations under the License. JSONSchemaPropsOrArray JSONSchemaPropsOrBool JSONSchemaPropsOrStringArray + ServiceReference + WebhookClientConfig */ package v1beta1 @@ -49,6 +55,10 @@ import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" +import k8s_io_apimachinery_pkg_runtime "k8s.io/apimachinery/pkg/runtime" + +import k8s_io_apimachinery_pkg_types "k8s.io/apimachinery/pkg/types" + import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" import encoding_binary "encoding/binary" @@ -68,106 +78,136 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package +func (m *ConversionRequest) Reset() { *m = ConversionRequest{} } +func (*ConversionRequest) ProtoMessage() {} +func (*ConversionRequest) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} } + +func (m *ConversionResponse) Reset() { *m = ConversionResponse{} } +func (*ConversionResponse) ProtoMessage() {} +func (*ConversionResponse) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} } + +func (m *ConversionReview) Reset() { *m = ConversionReview{} } +func (*ConversionReview) ProtoMessage() {} +func (*ConversionReview) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} } + func (m *CustomResourceColumnDefinition) Reset() { *m = CustomResourceColumnDefinition{} } func (*CustomResourceColumnDefinition) ProtoMessage() {} func (*CustomResourceColumnDefinition) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{0} + return fileDescriptorGenerated, []int{3} +} + +func (m *CustomResourceConversion) Reset() { *m = CustomResourceConversion{} } +func (*CustomResourceConversion) ProtoMessage() {} +func (*CustomResourceConversion) Descriptor() ([]byte, []int) { + return fileDescriptorGenerated, []int{4} } func (m *CustomResourceDefinition) Reset() { *m = CustomResourceDefinition{} } func (*CustomResourceDefinition) ProtoMessage() {} func (*CustomResourceDefinition) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{1} + return fileDescriptorGenerated, []int{5} } func (m *CustomResourceDefinitionCondition) Reset() { *m = CustomResourceDefinitionCondition{} } func (*CustomResourceDefinitionCondition) ProtoMessage() {} func (*CustomResourceDefinitionCondition) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{2} + return fileDescriptorGenerated, []int{6} } func (m *CustomResourceDefinitionList) Reset() { *m = CustomResourceDefinitionList{} } func (*CustomResourceDefinitionList) ProtoMessage() {} func (*CustomResourceDefinitionList) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{3} + return fileDescriptorGenerated, []int{7} } func (m *CustomResourceDefinitionNames) Reset() { *m = CustomResourceDefinitionNames{} } func (*CustomResourceDefinitionNames) ProtoMessage() {} func (*CustomResourceDefinitionNames) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{4} + return fileDescriptorGenerated, []int{8} } func (m *CustomResourceDefinitionSpec) Reset() { *m = CustomResourceDefinitionSpec{} } func (*CustomResourceDefinitionSpec) ProtoMessage() {} func (*CustomResourceDefinitionSpec) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{5} + return fileDescriptorGenerated, []int{9} } func (m *CustomResourceDefinitionStatus) Reset() { *m = CustomResourceDefinitionStatus{} } func (*CustomResourceDefinitionStatus) ProtoMessage() {} func (*CustomResourceDefinitionStatus) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{6} + return fileDescriptorGenerated, []int{10} } func (m *CustomResourceDefinitionVersion) Reset() { *m = CustomResourceDefinitionVersion{} } func (*CustomResourceDefinitionVersion) ProtoMessage() {} func (*CustomResourceDefinitionVersion) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{7} + return fileDescriptorGenerated, []int{11} } func (m *CustomResourceSubresourceScale) Reset() { *m = CustomResourceSubresourceScale{} } func (*CustomResourceSubresourceScale) ProtoMessage() {} func (*CustomResourceSubresourceScale) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{8} + return fileDescriptorGenerated, []int{12} } func (m *CustomResourceSubresourceStatus) Reset() { *m = CustomResourceSubresourceStatus{} } func (*CustomResourceSubresourceStatus) ProtoMessage() {} func (*CustomResourceSubresourceStatus) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{9} + return fileDescriptorGenerated, []int{13} } func (m *CustomResourceSubresources) Reset() { *m = CustomResourceSubresources{} } func (*CustomResourceSubresources) ProtoMessage() {} func (*CustomResourceSubresources) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{10} + return fileDescriptorGenerated, []int{14} } func (m *CustomResourceValidation) Reset() { *m = CustomResourceValidation{} } func (*CustomResourceValidation) ProtoMessage() {} func (*CustomResourceValidation) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{11} + return fileDescriptorGenerated, []int{15} } func (m *ExternalDocumentation) Reset() { *m = ExternalDocumentation{} } func (*ExternalDocumentation) ProtoMessage() {} -func (*ExternalDocumentation) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} } +func (*ExternalDocumentation) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{16} } func (m *JSON) Reset() { *m = JSON{} } func (*JSON) ProtoMessage() {} -func (*JSON) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{13} } +func (*JSON) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{17} } func (m *JSONSchemaProps) Reset() { *m = JSONSchemaProps{} } func (*JSONSchemaProps) ProtoMessage() {} -func (*JSONSchemaProps) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{14} } +func (*JSONSchemaProps) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{18} } func (m *JSONSchemaPropsOrArray) Reset() { *m = JSONSchemaPropsOrArray{} } func (*JSONSchemaPropsOrArray) ProtoMessage() {} -func (*JSONSchemaPropsOrArray) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{15} } +func (*JSONSchemaPropsOrArray) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{19} } func (m *JSONSchemaPropsOrBool) Reset() { *m = JSONSchemaPropsOrBool{} } func (*JSONSchemaPropsOrBool) ProtoMessage() {} -func (*JSONSchemaPropsOrBool) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{16} } +func (*JSONSchemaPropsOrBool) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{20} } func (m *JSONSchemaPropsOrStringArray) Reset() { *m = JSONSchemaPropsOrStringArray{} } func (*JSONSchemaPropsOrStringArray) ProtoMessage() {} func (*JSONSchemaPropsOrStringArray) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{17} + return fileDescriptorGenerated, []int{21} } +func (m *ServiceReference) Reset() { *m = ServiceReference{} } +func (*ServiceReference) ProtoMessage() {} +func (*ServiceReference) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{22} } + +func (m *WebhookClientConfig) Reset() { *m = WebhookClientConfig{} } +func (*WebhookClientConfig) ProtoMessage() {} +func (*WebhookClientConfig) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{23} } + func init() { + proto.RegisterType((*ConversionRequest)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.ConversionRequest") + proto.RegisterType((*ConversionResponse)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.ConversionResponse") + proto.RegisterType((*ConversionReview)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.ConversionReview") proto.RegisterType((*CustomResourceColumnDefinition)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceColumnDefinition") + proto.RegisterType((*CustomResourceConversion)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceConversion") proto.RegisterType((*CustomResourceDefinition)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinition") proto.RegisterType((*CustomResourceDefinitionCondition)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionCondition") proto.RegisterType((*CustomResourceDefinitionList)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionList") @@ -185,7 +225,127 @@ func init() { proto.RegisterType((*JSONSchemaPropsOrArray)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrArray") proto.RegisterType((*JSONSchemaPropsOrBool)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrBool") proto.RegisterType((*JSONSchemaPropsOrStringArray)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrStringArray") + proto.RegisterType((*ServiceReference)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.ServiceReference") + proto.RegisterType((*WebhookClientConfig)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.WebhookClientConfig") +} +func (m *ConversionRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConversionRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) + i += copy(dAtA[i:], m.UID) + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DesiredAPIVersion))) + i += copy(dAtA[i:], m.DesiredAPIVersion) + if len(m.Objects) > 0 { + for _, msg := range m.Objects { + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *ConversionResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConversionResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) + i += copy(dAtA[i:], m.UID) + if len(m.ConvertedObjects) > 0 { + for _, msg := range m.ConvertedObjects { + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Result.Size())) + n1, err := m.Result.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + return i, nil +} + +func (m *ConversionReview) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConversionReview) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Request != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Request.Size())) + n2, err := m.Request.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.Response != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Response.Size())) + n3, err := m.Response.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + return i, nil } + func (m *CustomResourceColumnDefinition) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -227,6 +387,38 @@ func (m *CustomResourceColumnDefinition) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *CustomResourceConversion) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CustomResourceConversion) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Strategy))) + i += copy(dAtA[i:], m.Strategy) + if m.WebhookClientConfig != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.WebhookClientConfig.Size())) + n4, err := m.WebhookClientConfig.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + return i, nil +} + func (m *CustomResourceDefinition) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -245,27 +437,27 @@ func (m *CustomResourceDefinition) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n1, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n5, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n1 + i += n5 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n2, err := m.Spec.MarshalTo(dAtA[i:]) + n6, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n2 + i += n6 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n3, err := m.Status.MarshalTo(dAtA[i:]) + n7, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n3 + i += n7 return i, nil } @@ -295,11 +487,11 @@ func (m *CustomResourceDefinitionCondition) MarshalTo(dAtA []byte) (int, error) dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.LastTransitionTime.Size())) - n4, err := m.LastTransitionTime.MarshalTo(dAtA[i:]) + n8, err := m.LastTransitionTime.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n4 + i += n8 dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) @@ -329,11 +521,11 @@ func (m *CustomResourceDefinitionList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n5, err := m.ListMeta.MarshalTo(dAtA[i:]) + n9, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n9 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -439,11 +631,11 @@ func (m *CustomResourceDefinitionSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Names.Size())) - n6, err := m.Names.MarshalTo(dAtA[i:]) + n10, err := m.Names.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n10 dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Scope))) @@ -452,21 +644,21 @@ func (m *CustomResourceDefinitionSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Validation.Size())) - n7, err := m.Validation.MarshalTo(dAtA[i:]) + n11, err := m.Validation.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n11 } if m.Subresources != nil { dAtA[i] = 0x32 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Subresources.Size())) - n8, err := m.Subresources.MarshalTo(dAtA[i:]) + n12, err := m.Subresources.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n12 } if len(m.Versions) > 0 { for _, msg := range m.Versions { @@ -492,6 +684,16 @@ func (m *CustomResourceDefinitionSpec) MarshalTo(dAtA []byte) (int, error) { i += n } } + if m.Conversion != nil { + dAtA[i] = 0x4a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Conversion.Size())) + n13, err := m.Conversion.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n13 + } return i, nil } @@ -525,11 +727,11 @@ func (m *CustomResourceDefinitionStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.AcceptedNames.Size())) - n9, err := m.AcceptedNames.MarshalTo(dAtA[i:]) + n14, err := m.AcceptedNames.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n14 if len(m.StoredVersions) > 0 { for _, s := range m.StoredVersions { dAtA[i] = 0x1a @@ -583,6 +785,38 @@ func (m *CustomResourceDefinitionVersion) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0 } i++ + if m.Schema != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Schema.Size())) + n15, err := m.Schema.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n15 + } + if m.Subresources != nil { + dAtA[i] = 0x2a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Subresources.Size())) + n16, err := m.Subresources.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n16 + } + if len(m.AdditionalPrinterColumns) > 0 { + for _, msg := range m.AdditionalPrinterColumns { + dAtA[i] = 0x32 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -655,21 +889,21 @@ func (m *CustomResourceSubresources) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n10, err := m.Status.MarshalTo(dAtA[i:]) + n17, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n17 } if m.Scale != nil { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Scale.Size())) - n11, err := m.Scale.MarshalTo(dAtA[i:]) + n18, err := m.Scale.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n18 } return i, nil } @@ -693,11 +927,11 @@ func (m *CustomResourceValidation) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.OpenAPIV3Schema.Size())) - n12, err := m.OpenAPIV3Schema.MarshalTo(dAtA[i:]) + n19, err := m.OpenAPIV3Schema.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n19 } return i, nil } @@ -801,11 +1035,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x42 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Default.Size())) - n13, err := m.Default.MarshalTo(dAtA[i:]) + n20, err := m.Default.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n20 } if m.Maximum != nil { dAtA[i] = 0x49 @@ -932,11 +1166,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Items.Size())) - n14, err := m.Items.MarshalTo(dAtA[i:]) + n21, err := m.Items.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n21 } if len(m.AllOf) > 0 { for _, msg := range m.AllOf { @@ -986,11 +1220,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Not.Size())) - n15, err := m.Not.MarshalTo(dAtA[i:]) + n22, err := m.Not.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n22 } if len(m.Properties) > 0 { keysForProperties := make([]string, 0, len(m.Properties)) @@ -1018,11 +1252,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n16, err := (&v).MarshalTo(dAtA[i:]) + n23, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n23 } } if m.AdditionalProperties != nil { @@ -1031,11 +1265,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.AdditionalProperties.Size())) - n17, err := m.AdditionalProperties.MarshalTo(dAtA[i:]) + n24, err := m.AdditionalProperties.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n24 } if len(m.PatternProperties) > 0 { keysForPatternProperties := make([]string, 0, len(m.PatternProperties)) @@ -1063,11 +1297,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n18, err := (&v).MarshalTo(dAtA[i:]) + n25, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n25 } } if len(m.Dependencies) > 0 { @@ -1096,11 +1330,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n19, err := (&v).MarshalTo(dAtA[i:]) + n26, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n26 } } if m.AdditionalItems != nil { @@ -1109,11 +1343,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.AdditionalItems.Size())) - n20, err := m.AdditionalItems.MarshalTo(dAtA[i:]) + n27, err := m.AdditionalItems.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n27 } if len(m.Definitions) > 0 { keysForDefinitions := make([]string, 0, len(m.Definitions)) @@ -1141,11 +1375,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n21, err := (&v).MarshalTo(dAtA[i:]) + n28, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n28 } } if m.ExternalDocs != nil { @@ -1154,11 +1388,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ExternalDocs.Size())) - n22, err := m.ExternalDocs.MarshalTo(dAtA[i:]) + n29, err := m.ExternalDocs.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n29 } if m.Example != nil { dAtA[i] = 0xa2 @@ -1166,11 +1400,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Example.Size())) - n23, err := m.Example.MarshalTo(dAtA[i:]) + n30, err := m.Example.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n30 } return i, nil } @@ -1194,11 +1428,11 @@ func (m *JSONSchemaPropsOrArray) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Schema.Size())) - n24, err := m.Schema.MarshalTo(dAtA[i:]) + n31, err := m.Schema.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n31 } if len(m.JSONSchemas) > 0 { for _, msg := range m.JSONSchemas { @@ -1242,11 +1476,11 @@ func (m *JSONSchemaPropsOrBool) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Schema.Size())) - n25, err := m.Schema.MarshalTo(dAtA[i:]) + n32, err := m.Schema.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n32 } return i, nil } @@ -1270,11 +1504,11 @@ func (m *JSONSchemaPropsOrStringArray) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Schema.Size())) - n26, err := m.Schema.MarshalTo(dAtA[i:]) + n33, err := m.Schema.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n33 } if len(m.Property) > 0 { for _, s := range m.Property { @@ -1294,6 +1528,78 @@ func (m *JSONSchemaPropsOrStringArray) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *ServiceReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ServiceReference) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i += copy(dAtA[i:], m.Namespace) + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + if m.Path != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Path))) + i += copy(dAtA[i:], *m.Path) + } + return i, nil +} + +func (m *WebhookClientConfig) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WebhookClientConfig) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Service != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Service.Size())) + n34, err := m.Service.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n34 + } + if m.CABundle != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.CABundle))) + i += copy(dAtA[i:], m.CABundle) + } + if m.URL != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.URL))) + i += copy(dAtA[i:], *m.URL) + } + return i, nil +} + func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -1303,14 +1609,60 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return offset + 1 } -func (m *CustomResourceColumnDefinition) Size() (n int) { +func (m *ConversionRequest) Size() (n int) { var l int _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Type) + l = len(m.UID) n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Format) + l = len(m.DesiredAPIVersion) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Objects) > 0 { + for _, e := range m.Objects { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ConversionResponse) Size() (n int) { + var l int + _ = l + l = len(m.UID) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.ConvertedObjects) > 0 { + for _, e := range m.ConvertedObjects { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + l = m.Result.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ConversionReview) Size() (n int) { + var l int + _ = l + if m.Request != nil { + l = m.Request.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Response != nil { + l = m.Response.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *CustomResourceColumnDefinition) Size() (n int) { + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Type) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Format) n += 1 + l + sovGenerated(uint64(l)) l = len(m.Description) n += 1 + l + sovGenerated(uint64(l)) @@ -1320,6 +1672,18 @@ func (m *CustomResourceColumnDefinition) Size() (n int) { return n } +func (m *CustomResourceConversion) Size() (n int) { + var l int + _ = l + l = len(m.Strategy) + n += 1 + l + sovGenerated(uint64(l)) + if m.WebhookClientConfig != nil { + l = m.WebhookClientConfig.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *CustomResourceDefinition) Size() (n int) { var l int _ = l @@ -1419,6 +1783,10 @@ func (m *CustomResourceDefinitionSpec) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.Conversion != nil { + l = m.Conversion.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -1449,6 +1817,20 @@ func (m *CustomResourceDefinitionVersion) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) n += 2 n += 2 + if m.Schema != nil { + l = m.Schema.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Subresources != nil { + l = m.Subresources.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.AdditionalPrinterColumns) > 0 { + for _, e := range m.AdditionalPrinterColumns { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1707,6 +2089,38 @@ func (m *JSONSchemaPropsOrStringArray) Size() (n int) { return n } +func (m *ServiceReference) Size() (n int) { + var l int + _ = l + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if m.Path != nil { + l = len(*m.Path) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *WebhookClientConfig) Size() (n int) { + var l int + _ = l + if m.Service != nil { + l = m.Service.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.CABundle != nil { + l = len(m.CABundle) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.URL != nil { + l = len(*m.URL) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func sovGenerated(x uint64) (n int) { for { n++ @@ -1720,6 +2134,41 @@ func sovGenerated(x uint64) (n int) { func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (this *ConversionRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ConversionRequest{`, + `UID:` + fmt.Sprintf("%v", this.UID) + `,`, + `DesiredAPIVersion:` + fmt.Sprintf("%v", this.DesiredAPIVersion) + `,`, + `Objects:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Objects), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ConversionResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ConversionResponse{`, + `UID:` + fmt.Sprintf("%v", this.UID) + `,`, + `ConvertedObjects:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ConvertedObjects), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `Result:` + strings.Replace(strings.Replace(this.Result.String(), "Status", "k8s_io_apimachinery_pkg_apis_meta_v1.Status", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ConversionReview) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ConversionReview{`, + `Request:` + strings.Replace(fmt.Sprintf("%v", this.Request), "ConversionRequest", "ConversionRequest", 1) + `,`, + `Response:` + strings.Replace(fmt.Sprintf("%v", this.Response), "ConversionResponse", "ConversionResponse", 1) + `,`, + `}`, + }, "") + return s +} func (this *CustomResourceColumnDefinition) String() string { if this == nil { return "nil" @@ -1735,6 +2184,17 @@ func (this *CustomResourceColumnDefinition) String() string { }, "") return s } +func (this *CustomResourceConversion) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&CustomResourceConversion{`, + `Strategy:` + fmt.Sprintf("%v", this.Strategy) + `,`, + `WebhookClientConfig:` + strings.Replace(fmt.Sprintf("%v", this.WebhookClientConfig), "WebhookClientConfig", "WebhookClientConfig", 1) + `,`, + `}`, + }, "") + return s +} func (this *CustomResourceDefinition) String() string { if this == nil { return "nil" @@ -1800,6 +2260,7 @@ func (this *CustomResourceDefinitionSpec) String() string { `Subresources:` + strings.Replace(fmt.Sprintf("%v", this.Subresources), "CustomResourceSubresources", "CustomResourceSubresources", 1) + `,`, `Versions:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Versions), "CustomResourceDefinitionVersion", "CustomResourceDefinitionVersion", 1), `&`, ``, 1) + `,`, `AdditionalPrinterColumns:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.AdditionalPrinterColumns), "CustomResourceColumnDefinition", "CustomResourceColumnDefinition", 1), `&`, ``, 1) + `,`, + `Conversion:` + strings.Replace(fmt.Sprintf("%v", this.Conversion), "CustomResourceConversion", "CustomResourceConversion", 1) + `,`, `}`, }, "") return s @@ -1824,6 +2285,9 @@ func (this *CustomResourceDefinitionVersion) String() string { `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Served:` + fmt.Sprintf("%v", this.Served) + `,`, `Storage:` + fmt.Sprintf("%v", this.Storage) + `,`, + `Schema:` + strings.Replace(fmt.Sprintf("%v", this.Schema), "CustomResourceValidation", "CustomResourceValidation", 1) + `,`, + `Subresources:` + strings.Replace(fmt.Sprintf("%v", this.Subresources), "CustomResourceSubresources", "CustomResourceSubresources", 1) + `,`, + `AdditionalPrinterColumns:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.AdditionalPrinterColumns), "CustomResourceColumnDefinition", "CustomResourceColumnDefinition", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -2009,6 +2473,30 @@ func (this *JSONSchemaPropsOrStringArray) String() string { }, "") return s } +func (this *ServiceReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ServiceReference{`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Path:` + valueToStringGenerated(this.Path) + `,`, + `}`, + }, "") + return s +} +func (this *WebhookClientConfig) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&WebhookClientConfig{`, + `Service:` + strings.Replace(fmt.Sprintf("%v", this.Service), "ServiceReference", "ServiceReference", 1) + `,`, + `CABundle:` + valueToStringGenerated(this.CABundle) + `,`, + `URL:` + valueToStringGenerated(this.URL) + `,`, + `}`, + }, "") + return s +} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -2017,7 +2505,7 @@ func valueToStringGenerated(v interface{}) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("*%v", pv) } -func (m *CustomResourceColumnDefinition) Unmarshal(dAtA []byte) error { +func (m *ConversionRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2040,15 +2528,15 @@ func (m *CustomResourceColumnDefinition) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CustomResourceColumnDefinition: wiretype end group for non-group") + return fmt.Errorf("proto: ConversionRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CustomResourceColumnDefinition: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ConversionRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2073,11 +2561,11 @@ func (m *CustomResourceColumnDefinition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.UID = k8s_io_apimachinery_pkg_types.UID(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DesiredAPIVersion", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2102,42 +2590,13 @@ func (m *CustomResourceColumnDefinition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Type = string(dAtA[iNdEx:postIndex]) + m.DesiredAPIVersion = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Format = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Objects", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2147,68 +2606,22 @@ func (m *CustomResourceColumnDefinition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift + msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex > l { return io.ErrUnexpectedEOF } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) - } - m.Priority = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Priority |= (int32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JSONPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF + m.Objects = append(m.Objects, k8s_io_apimachinery_pkg_runtime.RawExtension{}) + if err := m.Objects[len(m.Objects)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.JSONPath = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2231,7 +2644,7 @@ func (m *CustomResourceColumnDefinition) Unmarshal(dAtA []byte) error { } return nil } -func (m *CustomResourceDefinition) Unmarshal(dAtA []byte) error { +func (m *ConversionResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2254,17 +2667,17 @@ func (m *CustomResourceDefinition) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CustomResourceDefinition: wiretype end group for non-group") + return fmt.Errorf("proto: ConversionResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CustomResourceDefinition: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ConversionResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2274,25 +2687,24 @@ func (m *CustomResourceDefinition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= (int(b) & 0x7F) << shift + stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.UID = k8s_io_apimachinery_pkg_types.UID(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConvertedObjects", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2316,13 +2728,14 @@ func (m *CustomResourceDefinition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.ConvertedObjects = append(m.ConvertedObjects, k8s_io_apimachinery_pkg_runtime.RawExtension{}) + if err := m.ConvertedObjects[len(m.ConvertedObjects)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2346,7 +2759,7 @@ func (m *CustomResourceDefinition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -2371,7 +2784,7 @@ func (m *CustomResourceDefinition) Unmarshal(dAtA []byte) error { } return nil } -func (m *CustomResourceDefinitionCondition) Unmarshal(dAtA []byte) error { +func (m *ConversionReview) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2394,17 +2807,17 @@ func (m *CustomResourceDefinitionCondition) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CustomResourceDefinitionCondition: wiretype end group for non-group") + return fmt.Errorf("proto: ConversionReview: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CustomResourceDefinitionCondition: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ConversionReview: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2414,21 +2827,603 @@ func (m *CustomResourceDefinitionCondition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift + msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex > l { return io.ErrUnexpectedEOF } - m.Type = CustomResourceDefinitionConditionType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex + if m.Request == nil { + m.Request = &ConversionRequest{} + } + if err := m.Request.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Response", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Response == nil { + m.Response = &ConversionResponse{} + } + if err := m.Response.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CustomResourceColumnDefinition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CustomResourceColumnDefinition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CustomResourceColumnDefinition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Format = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + } + m.Priority = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Priority |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JSONPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JSONPath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CustomResourceConversion) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CustomResourceConversion: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CustomResourceConversion: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Strategy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Strategy = ConversionStrategyType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WebhookClientConfig", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.WebhookClientConfig == nil { + m.WebhookClientConfig = &WebhookClientConfig{} + } + if err := m.WebhookClientConfig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CustomResourceDefinition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CustomResourceDefinition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CustomResourceDefinition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CustomResourceDefinitionCondition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CustomResourceDefinitionCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CustomResourceDefinitionCondition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = CustomResourceDefinitionConditionType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) @@ -3176,6 +4171,39 @@ func (m *CustomResourceDefinitionSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conversion", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Conversion == nil { + m.Conversion = &CustomResourceConversion{} + } + if err := m.Conversion.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -3435,6 +4463,103 @@ func (m *CustomResourceDefinitionVersion) Unmarshal(dAtA []byte) error { } } m.Storage = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Schema == nil { + m.Schema = &CustomResourceValidation{} + } + if err := m.Schema.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subresources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Subresources == nil { + m.Subresources = &CustomResourceSubresources{} + } + if err := m.Subresources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AdditionalPrinterColumns", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AdditionalPrinterColumns = append(m.AdditionalPrinterColumns, CustomResourceColumnDefinition{}) + if err := m.AdditionalPrinterColumns[len(m.AdditionalPrinterColumns)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -5318,11 +6443,127 @@ func (m *JSONSchemaProps) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.Definitions[mapkey] = *mapvalue - iNdEx = postIndex - case 35: + m.Definitions[mapkey] = *mapvalue + iNdEx = postIndex + case 35: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExternalDocs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ExternalDocs == nil { + m.ExternalDocs = &ExternalDocumentation{} + } + if err := m.ExternalDocs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 36: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Example", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Example == nil { + m.Example = &JSON{} + } + if err := m.Example.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JSONSchemaPropsOrArray) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JSONSchemaPropsOrArray: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JSONSchemaPropsOrArray: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExternalDocs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5346,16 +6587,16 @@ func (m *JSONSchemaProps) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ExternalDocs == nil { - m.ExternalDocs = &ExternalDocumentation{} + if m.Schema == nil { + m.Schema = &JSONSchemaProps{} } - if err := m.ExternalDocs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Schema.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 36: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Example", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JSONSchemas", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5379,10 +6620,8 @@ func (m *JSONSchemaProps) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Example == nil { - m.Example = &JSON{} - } - if err := m.Example.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.JSONSchemas = append(m.JSONSchemas, JSONSchemaProps{}) + if err := m.JSONSchemas[len(m.JSONSchemas)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5407,7 +6646,7 @@ func (m *JSONSchemaProps) Unmarshal(dAtA []byte) error { } return nil } -func (m *JSONSchemaPropsOrArray) Unmarshal(dAtA []byte) error { +func (m *JSONSchemaPropsOrBool) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5430,13 +6669,33 @@ func (m *JSONSchemaPropsOrArray) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JSONSchemaPropsOrArray: wiretype end group for non-group") + return fmt.Errorf("proto: JSONSchemaPropsOrBool: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JSONSchemaPropsOrArray: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: JSONSchemaPropsOrBool: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Allows", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Allows = bool(v != 0) + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) } @@ -5469,9 +6728,59 @@ func (m *JSONSchemaPropsOrArray) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JSONSchemaPropsOrStringArray) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JSONSchemaPropsOrStringArray: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JSONSchemaPropsOrStringArray: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JSONSchemas", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5495,11 +6804,42 @@ func (m *JSONSchemaPropsOrArray) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.JSONSchemas = append(m.JSONSchemas, JSONSchemaProps{}) - if err := m.JSONSchemas[len(m.JSONSchemas)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Schema == nil { + m.Schema = &JSONSchemaProps{} + } + if err := m.Schema.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Property", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Property = append(m.Property, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -5521,7 +6861,7 @@ func (m *JSONSchemaPropsOrArray) Unmarshal(dAtA []byte) error { } return nil } -func (m *JSONSchemaPropsOrBool) Unmarshal(dAtA []byte) error { +func (m *ServiceReference) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5544,17 +6884,17 @@ func (m *JSONSchemaPropsOrBool) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JSONSchemaPropsOrBool: wiretype end group for non-group") + return fmt.Errorf("proto: ServiceReference: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JSONSchemaPropsOrBool: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ServiceReference: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Allows", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5564,17 +6904,26 @@ func (m *JSONSchemaPropsOrBool) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= (int(b) & 0x7F) << shift + stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } - m.Allows = bool(v != 0) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5584,24 +6933,50 @@ func (m *JSONSchemaPropsOrBool) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= (int(b) & 0x7F) << shift + stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex > l { return io.ErrUnexpectedEOF } - if m.Schema == nil { - m.Schema = &JSONSchemaProps{} + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) } - if err := m.Schema.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF } + s := string(dAtA[iNdEx:postIndex]) + m.Path = &s iNdEx = postIndex default: iNdEx = preIndex @@ -5624,7 +6999,7 @@ func (m *JSONSchemaPropsOrBool) Unmarshal(dAtA []byte) error { } return nil } -func (m *JSONSchemaPropsOrStringArray) Unmarshal(dAtA []byte) error { +func (m *WebhookClientConfig) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5647,15 +7022,15 @@ func (m *JSONSchemaPropsOrStringArray) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JSONSchemaPropsOrStringArray: wiretype end group for non-group") + return fmt.Errorf("proto: WebhookClientConfig: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JSONSchemaPropsOrStringArray: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: WebhookClientConfig: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5679,16 +7054,47 @@ func (m *JSONSchemaPropsOrStringArray) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Schema == nil { - m.Schema = &JSONSchemaProps{} + if m.Service == nil { + m.Service = &ServiceReference{} } - if err := m.Schema.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Service.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Property", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CABundle", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CABundle = append(m.CABundle[:0], dAtA[iNdEx:postIndex]...) + if m.CABundle == nil { + m.CABundle = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field URL", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5713,7 +7119,8 @@ func (m *JSONSchemaPropsOrStringArray) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Property = append(m.Property, string(dAtA[iNdEx:postIndex])) + s := string(dAtA[iNdEx:postIndex]) + m.URL = &s iNdEx = postIndex default: iNdEx = preIndex @@ -5846,149 +7253,177 @@ func init() { } var fileDescriptorGenerated = []byte{ - // 2292 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xdd, 0x6f, 0x5b, 0x49, - 0x15, 0xef, 0xd8, 0x71, 0xe2, 0x8c, 0x93, 0x26, 0x99, 0x6d, 0xca, 0x6d, 0x68, 0xed, 0xd4, 0x65, - 0x57, 0x01, 0xb6, 0x0e, 0x2d, 0xbb, 0xec, 0xb2, 0x12, 0x0f, 0x71, 0x52, 0x50, 0x97, 0xa6, 0x89, - 0xc6, 0x6d, 0x11, 0xec, 0xe7, 0xc4, 0x9e, 0x38, 0xb7, 0xb9, 0x5f, 0xbd, 0x33, 0xd7, 0x4d, 0x24, - 0x40, 0x7c, 0x68, 0x85, 0x84, 0x80, 0x05, 0xb6, 0x42, 0x42, 0xe2, 0x05, 0x24, 0x5e, 0x10, 0x82, - 0x07, 0x78, 0x83, 0x3f, 0xa0, 0x8f, 0xfb, 0xb8, 0x4f, 0x16, 0x35, 0xff, 0x02, 0x12, 0x52, 0x9e, - 0xd0, 0x7c, 0xdc, 0xb9, 0x1f, 0x4e, 0xb6, 0x11, 0x6b, 0x6f, 0xdf, 0x7c, 0xcf, 0x39, 0x73, 0x7e, - 0xbf, 0x39, 0x73, 0xe6, 0xcc, 0x39, 0x09, 0xdc, 0xdd, 0x7f, 0x95, 0x35, 0x6c, 0x7f, 0x75, 0x3f, - 0xda, 0xa1, 0xa1, 0x47, 0x39, 0x65, 0xab, 0x3d, 0xea, 0x75, 0xfc, 0x70, 0x55, 0x2b, 0x48, 0x60, - 0xd3, 0x03, 0x4e, 0x3d, 0x66, 0xfb, 0x1e, 0xbb, 0x4a, 0x02, 0x9b, 0xd1, 0xb0, 0x47, 0xc3, 0xd5, - 0x60, 0xbf, 0x2b, 0x74, 0x2c, 0x6b, 0xb0, 0xda, 0xbb, 0xb6, 0x43, 0x39, 0xb9, 0xb6, 0xda, 0xa5, - 0x1e, 0x0d, 0x09, 0xa7, 0x9d, 0x46, 0x10, 0xfa, 0xdc, 0x47, 0x5f, 0x53, 0xee, 0x1a, 0x19, 0xeb, - 0x77, 0x8c, 0xbb, 0x46, 0xb0, 0xdf, 0x15, 0x3a, 0x96, 0x35, 0x68, 0x68, 0x77, 0x4b, 0x57, 0xbb, - 0x36, 0xdf, 0x8b, 0x76, 0x1a, 0x6d, 0xdf, 0x5d, 0xed, 0xfa, 0x5d, 0x7f, 0x55, 0x7a, 0xdd, 0x89, - 0x76, 0xe5, 0x97, 0xfc, 0x90, 0xbf, 0x14, 0xda, 0xd2, 0x4b, 0x09, 0x79, 0x97, 0xb4, 0xf7, 0x6c, - 0x8f, 0x86, 0x87, 0x09, 0x63, 0x97, 0x72, 0xb2, 0xda, 0x1b, 0xe2, 0xb8, 0xb4, 0x7a, 0xd2, 0xaa, - 0x30, 0xf2, 0xb8, 0xed, 0xd2, 0xa1, 0x05, 0x5f, 0x79, 0xda, 0x02, 0xd6, 0xde, 0xa3, 0x2e, 0xc9, - 0xaf, 0xab, 0x7f, 0x50, 0x80, 0xd5, 0xf5, 0x88, 0x71, 0xdf, 0xc5, 0x94, 0xf9, 0x51, 0xd8, 0xa6, - 0xeb, 0xbe, 0x13, 0xb9, 0xde, 0x06, 0xdd, 0xb5, 0x3d, 0x9b, 0xdb, 0xbe, 0x87, 0x96, 0xe1, 0x84, - 0x47, 0x5c, 0x6a, 0x81, 0x65, 0xb0, 0x32, 0xdd, 0x9c, 0x79, 0xdc, 0xaf, 0x9d, 0x19, 0xf4, 0x6b, - 0x13, 0xb7, 0x89, 0x4b, 0xb1, 0xd4, 0x08, 0x0b, 0x7e, 0x18, 0x50, 0xab, 0x90, 0xb5, 0xb8, 0x73, - 0x18, 0x50, 0x2c, 0x35, 0xe8, 0x05, 0x38, 0xb9, 0xeb, 0x87, 0x2e, 0xe1, 0x56, 0x51, 0xda, 0x9c, - 0xd5, 0x36, 0x93, 0x5f, 0x97, 0x52, 0xac, 0xb5, 0xe8, 0x65, 0x58, 0xe9, 0x50, 0xd6, 0x0e, 0xed, - 0x40, 0x40, 0x5b, 0x13, 0xd2, 0xf8, 0x39, 0x6d, 0x5c, 0xd9, 0x48, 0x54, 0x38, 0x6d, 0x87, 0x5e, - 0x84, 0xe5, 0x20, 0xb4, 0xfd, 0xd0, 0xe6, 0x87, 0x56, 0x69, 0x19, 0xac, 0x94, 0x9a, 0xf3, 0x7a, - 0x4d, 0x79, 0x5b, 0xcb, 0xb1, 0xb1, 0x40, 0xcb, 0xb0, 0xfc, 0x7a, 0x6b, 0xeb, 0xf6, 0x36, 0xe1, - 0x7b, 0xd6, 0xa4, 0x44, 0x98, 0x10, 0xd6, 0xb8, 0x7c, 0x5f, 0x4b, 0xeb, 0x3f, 0x2e, 0x42, 0x2b, - 0x1b, 0x95, 0x54, 0x3c, 0xde, 0x85, 0x65, 0x71, 0x6c, 0x1d, 0xc2, 0x89, 0x8c, 0x49, 0xe5, 0xfa, - 0x97, 0x1a, 0x49, 0x4a, 0x99, 0xe8, 0x27, 0x79, 0x24, 0xac, 0x1b, 0xbd, 0x6b, 0x8d, 0xad, 0x9d, - 0xfb, 0xb4, 0xcd, 0x37, 0x29, 0x27, 0x4d, 0xa4, 0xe9, 0xc1, 0x44, 0x86, 0x8d, 0x57, 0xf4, 0x3d, - 0x38, 0xc1, 0x02, 0xda, 0x96, 0xf1, 0xac, 0x5c, 0x7f, 0xa3, 0xf1, 0x89, 0x12, 0xb6, 0x71, 0xd2, - 0x46, 0x5a, 0x01, 0x6d, 0x27, 0x87, 0x25, 0xbe, 0xb0, 0x84, 0x45, 0xef, 0x01, 0x38, 0xc9, 0x38, - 0xe1, 0x11, 0x93, 0xa7, 0x55, 0xb9, 0xfe, 0xd6, 0xb8, 0x18, 0x48, 0x90, 0x24, 0x19, 0xd4, 0x37, - 0xd6, 0xe0, 0xf5, 0xff, 0x14, 0xe0, 0xe5, 0x93, 0x96, 0xae, 0xfb, 0x5e, 0x47, 0x1d, 0xc7, 0x4d, - 0x9d, 0x7c, 0x2a, 0x3d, 0x5f, 0x4e, 0x27, 0xdf, 0x51, 0xbf, 0xf6, 0xfc, 0x53, 0x1d, 0xa4, 0xb2, - 0xf4, 0xab, 0x66, 0xdf, 0x2a, 0x93, 0x2f, 0x67, 0x89, 0x1d, 0xf5, 0x6b, 0x73, 0x66, 0x59, 0x96, - 0x2b, 0xea, 0x41, 0xe4, 0x10, 0xc6, 0xef, 0x84, 0xc4, 0x63, 0xca, 0xad, 0xed, 0x52, 0x1d, 0xbe, - 0x2f, 0x9c, 0x2e, 0x3d, 0xc4, 0x8a, 0xe6, 0x92, 0x86, 0x44, 0xb7, 0x86, 0xbc, 0xe1, 0x63, 0x10, - 0xc4, 0xc5, 0x0a, 0x29, 0x61, 0xe6, 0xae, 0x98, 0x58, 0x62, 0x29, 0xc5, 0x5a, 0x8b, 0x3e, 0x0f, - 0xa7, 0x5c, 0xca, 0x18, 0xe9, 0x52, 0x79, 0x41, 0xa6, 0x9b, 0x73, 0xda, 0x70, 0x6a, 0x53, 0x89, - 0x71, 0xac, 0xaf, 0x1f, 0x01, 0x78, 0xf1, 0xa4, 0xa8, 0xdd, 0xb2, 0x19, 0x47, 0x6f, 0x0e, 0x5d, - 0x80, 0xc6, 0xe9, 0x76, 0x28, 0x56, 0xcb, 0xf4, 0x37, 0xb7, 0x33, 0x96, 0xa4, 0x92, 0xff, 0xbb, - 0xb0, 0x64, 0x73, 0xea, 0x8a, 0x33, 0x28, 0xae, 0x54, 0xae, 0x7f, 0x6b, 0x4c, 0xb9, 0xd7, 0x9c, - 0xd5, 0x1c, 0x4a, 0x37, 0x05, 0x1a, 0x56, 0xa0, 0xf5, 0x3f, 0x16, 0xe0, 0xa5, 0x93, 0x96, 0x88, - 0x8a, 0xc7, 0x44, 0xc4, 0x03, 0x27, 0x0a, 0x89, 0xa3, 0x33, 0xce, 0x44, 0x7c, 0x5b, 0x4a, 0xb1, - 0xd6, 0x8a, 0x9a, 0xc4, 0x6c, 0xaf, 0x1b, 0x39, 0x24, 0xd4, 0xe9, 0x64, 0x76, 0xdd, 0xd2, 0x72, - 0x6c, 0x2c, 0x50, 0x03, 0x42, 0xb6, 0xe7, 0x87, 0x5c, 0x62, 0x58, 0xc5, 0xe5, 0xa2, 0xf0, 0x2c, - 0x0a, 0x44, 0xcb, 0x48, 0x71, 0xca, 0x42, 0x94, 0xdc, 0x7d, 0xdb, 0xeb, 0xe8, 0x53, 0x37, 0xb7, - 0xf8, 0x9b, 0xb6, 0xd7, 0xc1, 0x52, 0x23, 0xf0, 0x1d, 0x9b, 0x71, 0x21, 0xd1, 0x47, 0x9e, 0x89, - 0xba, 0xb4, 0x34, 0x16, 0x02, 0xbf, 0x4d, 0x38, 0xed, 0xfa, 0xa1, 0x4d, 0x99, 0x35, 0x99, 0xe0, - 0xaf, 0x1b, 0x29, 0x4e, 0x59, 0xd4, 0x7f, 0x35, 0x75, 0x72, 0x92, 0x88, 0x52, 0x82, 0xae, 0xc0, - 0x52, 0x37, 0xf4, 0xa3, 0x40, 0x47, 0xc9, 0x44, 0xfb, 0x1b, 0x42, 0x88, 0x95, 0x4e, 0x64, 0x65, - 0x8f, 0x86, 0xe2, 0xc0, 0x74, 0x88, 0x4c, 0x56, 0xde, 0x53, 0x62, 0x1c, 0xeb, 0xd1, 0x0f, 0x01, - 0x2c, 0x79, 0x3a, 0x38, 0x22, 0xe5, 0xde, 0x1c, 0x53, 0x5e, 0xc8, 0xf0, 0x26, 0x74, 0x55, 0xe4, - 0x15, 0x32, 0x7a, 0x09, 0x96, 0x58, 0xdb, 0x0f, 0xa8, 0x8e, 0x7a, 0x35, 0x36, 0x6a, 0x09, 0xe1, - 0x51, 0xbf, 0x36, 0x1b, 0xbb, 0x93, 0x02, 0xac, 0x8c, 0xd1, 0x4f, 0x00, 0x84, 0x3d, 0xe2, 0xd8, - 0x1d, 0x22, 0xdf, 0xb4, 0x92, 0xa4, 0x3f, 0xda, 0xb4, 0xbe, 0x67, 0xdc, 0xab, 0x43, 0x4b, 0xbe, - 0x71, 0x0a, 0x1a, 0xbd, 0x0f, 0xe0, 0x0c, 0x8b, 0x76, 0x42, 0xbd, 0x8a, 0xc9, 0xd7, 0xaf, 0x72, - 0xfd, 0xdb, 0x23, 0xe5, 0xd2, 0x4a, 0x01, 0x34, 0xe7, 0x07, 0xfd, 0xda, 0x4c, 0x5a, 0x82, 0x33, - 0x04, 0xd0, 0xcf, 0x00, 0x2c, 0xeb, 0x13, 0x66, 0xd6, 0x94, 0xbc, 0xf0, 0x6f, 0x8f, 0xe9, 0x60, - 0x75, 0x46, 0x25, 0xb7, 0x40, 0x0b, 0x18, 0x36, 0x0c, 0xd0, 0x3f, 0x00, 0xb4, 0x48, 0x47, 0x15, - 0x78, 0xe2, 0x6c, 0x87, 0xb6, 0xc7, 0x69, 0xa8, 0x1a, 0x22, 0x66, 0x95, 0x25, 0xbd, 0xd1, 0xbe, - 0x85, 0xf9, 0x66, 0xab, 0xb9, 0xac, 0xd9, 0x59, 0x6b, 0x27, 0xd0, 0xc0, 0x27, 0x12, 0xac, 0xbf, - 0x5f, 0xcc, 0xf7, 0x72, 0xf9, 0xa7, 0x16, 0x3d, 0x02, 0x10, 0xb6, 0xe3, 0x27, 0x8c, 0x59, 0x40, - 0x6e, 0xe9, 0xdd, 0x31, 0x45, 0xdc, 0xbc, 0x95, 0x49, 0xbb, 0x63, 0x44, 0xa2, 0x9a, 0x98, 0xdf, - 0xe8, 0xb7, 0x00, 0xce, 0x92, 0x76, 0x9b, 0x06, 0x9c, 0x76, 0x54, 0x05, 0x2c, 0x7c, 0x0a, 0x97, - 0x7c, 0x51, 0xb3, 0x9a, 0x5d, 0x4b, 0x43, 0xe3, 0x2c, 0x13, 0xf4, 0x1a, 0x3c, 0xcb, 0xb8, 0x1f, - 0xd2, 0x4e, 0x9c, 0x2f, 0xba, 0x3a, 0xa3, 0x41, 0xbf, 0x76, 0xb6, 0x95, 0xd1, 0xe0, 0x9c, 0x65, - 0xfd, 0x37, 0x00, 0xd6, 0x9e, 0x92, 0x8f, 0xa7, 0x68, 0xaf, 0x5f, 0x80, 0x93, 0x72, 0xbb, 0x1d, - 0x19, 0x95, 0x72, 0xaa, 0x5f, 0x92, 0x52, 0xac, 0xb5, 0xa2, 0x9a, 0x0a, 0x7c, 0xf1, 0xc6, 0x17, - 0xa5, 0xa1, 0xa9, 0xa6, 0x2d, 0x25, 0xc6, 0xb1, 0xbe, 0xfe, 0x5f, 0x90, 0x4f, 0x95, 0xd4, 0x25, - 0x6d, 0xb5, 0x89, 0x43, 0xd1, 0x06, 0x9c, 0x17, 0xdd, 0x20, 0xa6, 0x81, 0x63, 0xb7, 0x09, 0x93, - 0xdd, 0xb2, 0xe2, 0x68, 0x69, 0xb7, 0xf3, 0xad, 0x9c, 0x1e, 0x0f, 0xad, 0x40, 0xaf, 0x43, 0xa4, - 0x3a, 0xa4, 0x8c, 0x1f, 0x55, 0xec, 0x4d, 0xaf, 0xd3, 0x1a, 0xb2, 0xc0, 0xc7, 0xac, 0x42, 0xeb, - 0x70, 0xc1, 0x21, 0x3b, 0xd4, 0x69, 0x51, 0x87, 0xb6, 0xb9, 0x1f, 0x4a, 0x57, 0x6a, 0x9e, 0x58, - 0x1c, 0xf4, 0x6b, 0x0b, 0xb7, 0xf2, 0x4a, 0x3c, 0x6c, 0x5f, 0xbf, 0x9c, 0x3f, 0x91, 0xf4, 0xc6, - 0x55, 0xdf, 0xf9, 0xfb, 0x02, 0x5c, 0x3a, 0xb9, 0xa6, 0xa1, 0x1f, 0x25, 0xed, 0xb1, 0xea, 0x7e, - 0xde, 0x1e, 0x57, 0xfd, 0xd4, 0xfd, 0x31, 0x1c, 0xee, 0x8d, 0xd1, 0xf7, 0xc5, 0x53, 0x44, 0x1c, - 0xaa, 0x2f, 0xca, 0x5b, 0x63, 0xa3, 0x20, 0x40, 0x9a, 0xd3, 0xea, 0x95, 0x23, 0x8e, 0x7c, 0xd4, - 0x88, 0x43, 0xeb, 0x7f, 0x02, 0xf9, 0x09, 0x29, 0x79, 0x73, 0xd0, 0xcf, 0x01, 0x9c, 0xf3, 0x03, - 0xea, 0xad, 0x6d, 0xdf, 0xbc, 0xf7, 0xe5, 0x96, 0x1c, 0x3c, 0x75, 0xa8, 0x6e, 0x7f, 0x42, 0x9e, - 0x62, 0x6e, 0x53, 0x0e, 0xb7, 0x43, 0x3f, 0x60, 0xcd, 0xe7, 0x06, 0xfd, 0xda, 0xdc, 0x56, 0x16, - 0x0a, 0xe7, 0xb1, 0xeb, 0x2e, 0x5c, 0xbc, 0x71, 0xc0, 0x69, 0xe8, 0x11, 0x67, 0xc3, 0x6f, 0x47, - 0x2e, 0xf5, 0xb8, 0x22, 0x9a, 0x1b, 0x37, 0xc1, 0x29, 0xc7, 0xcd, 0x4b, 0xb0, 0x18, 0x85, 0x8e, - 0xce, 0xe2, 0x8a, 0x36, 0x2f, 0xde, 0xc5, 0xb7, 0xb0, 0x90, 0xd7, 0x2f, 0xc3, 0x09, 0xc1, 0x13, - 0x5d, 0x80, 0xc5, 0x90, 0x3c, 0x94, 0x5e, 0x67, 0x9a, 0x53, 0xc2, 0x04, 0x93, 0x87, 0x58, 0xc8, - 0xea, 0x7f, 0xbe, 0x08, 0xe7, 0x72, 0x7b, 0x41, 0x4b, 0xb0, 0x60, 0x77, 0x34, 0x07, 0xa8, 0x9d, - 0x16, 0x6e, 0x6e, 0xe0, 0x82, 0xdd, 0x41, 0xaf, 0xc0, 0x49, 0x35, 0xc0, 0x6b, 0xd0, 0x9a, 0x29, - 0x01, 0x52, 0x2a, 0x7a, 0x8f, 0xc4, 0x9d, 0x20, 0xa2, 0xcd, 0x25, 0x07, 0xba, 0xab, 0x6f, 0x89, - 0xe2, 0x40, 0x77, 0xb1, 0x90, 0xfd, 0xbf, 0xb3, 0x76, 0x3c, 0xec, 0x97, 0x4e, 0x31, 0xec, 0x4f, - 0x7e, 0xec, 0xb0, 0x7f, 0x05, 0x96, 0xb8, 0xcd, 0x1d, 0x6a, 0x4d, 0x65, 0x5b, 0xc4, 0x3b, 0x42, - 0x88, 0x95, 0x0e, 0xdd, 0x87, 0x53, 0x1d, 0xba, 0x4b, 0x22, 0x87, 0x5b, 0x65, 0x99, 0x42, 0xeb, - 0x23, 0x48, 0xa1, 0x66, 0x45, 0x54, 0xc5, 0x0d, 0xe5, 0x17, 0xc7, 0x00, 0xe8, 0x79, 0x38, 0xe5, - 0x92, 0x03, 0xdb, 0x8d, 0x5c, 0x6b, 0x7a, 0x19, 0xac, 0x00, 0x65, 0xb6, 0xa9, 0x44, 0x38, 0xd6, - 0x89, 0xca, 0x48, 0x0f, 0xda, 0x4e, 0xc4, 0xec, 0x1e, 0xd5, 0x4a, 0x0b, 0xca, 0x82, 0x6b, 0x2a, - 0xe3, 0x8d, 0x9c, 0x1e, 0x0f, 0xad, 0x90, 0x60, 0xb6, 0x27, 0x17, 0x57, 0x52, 0x60, 0x4a, 0x84, - 0x63, 0x5d, 0x16, 0x4c, 0xdb, 0xcf, 0x9c, 0x04, 0xa6, 0x17, 0x0f, 0xad, 0x40, 0x5f, 0x84, 0xd3, - 0x2e, 0x39, 0xb8, 0x45, 0xbd, 0x2e, 0xdf, 0xb3, 0x66, 0x97, 0xc1, 0x4a, 0xb1, 0x39, 0x3b, 0xe8, - 0xd7, 0xa6, 0x37, 0x63, 0x21, 0x4e, 0xf4, 0xd2, 0xd8, 0xf6, 0xb4, 0xf1, 0xd9, 0x94, 0x71, 0x2c, - 0xc4, 0x89, 0x5e, 0x3c, 0x3a, 0x01, 0xe1, 0xe2, 0x72, 0x59, 0x73, 0xd9, 0x16, 0x7e, 0x5b, 0x89, - 0x71, 0xac, 0x47, 0x2b, 0xb0, 0xec, 0x92, 0x03, 0x39, 0x6e, 0x59, 0xf3, 0xd2, 0xed, 0x8c, 0xe8, - 0xc3, 0x36, 0xb5, 0x0c, 0x1b, 0xad, 0xb4, 0xb4, 0x3d, 0x65, 0xb9, 0x90, 0xb2, 0xd4, 0x32, 0x6c, - 0xb4, 0x22, 0x89, 0x23, 0xcf, 0x7e, 0x10, 0x51, 0x65, 0x8c, 0x64, 0x64, 0x4c, 0x12, 0xdf, 0x4d, - 0x54, 0x38, 0x6d, 0x27, 0xc6, 0x1d, 0x37, 0x72, 0xb8, 0x1d, 0x38, 0x74, 0x6b, 0xd7, 0x7a, 0x4e, - 0xc6, 0x5f, 0x76, 0xce, 0x9b, 0x46, 0x8a, 0x53, 0x16, 0x88, 0xc2, 0x09, 0xea, 0x45, 0xae, 0x75, - 0x4e, 0x36, 0x4c, 0x23, 0x49, 0x41, 0x73, 0x73, 0x6e, 0x78, 0x91, 0x8b, 0xa5, 0x7b, 0xf4, 0x0a, - 0x9c, 0x75, 0xc9, 0x81, 0x28, 0x07, 0x34, 0xe4, 0x62, 0x10, 0x5b, 0x94, 0x9b, 0x5f, 0x10, 0x4d, - 0xca, 0x66, 0x5a, 0x81, 0xb3, 0x76, 0x72, 0xa1, 0xed, 0xa5, 0x16, 0x9e, 0x4f, 0x2d, 0x4c, 0x2b, - 0x70, 0xd6, 0x4e, 0x44, 0x3a, 0xa4, 0x0f, 0x22, 0x3b, 0xa4, 0x1d, 0xeb, 0x33, 0xb2, 0xaf, 0x91, - 0x91, 0xc6, 0x5a, 0x86, 0x8d, 0x16, 0xf5, 0xe2, 0xb9, 0xdc, 0x92, 0xd7, 0xf0, 0xee, 0x68, 0x2b, - 0xf9, 0x56, 0xb8, 0x16, 0x86, 0xe4, 0x50, 0xbd, 0x34, 0xe9, 0x89, 0x1c, 0x31, 0x58, 0x22, 0x8e, - 0xb3, 0xb5, 0x6b, 0x5d, 0x90, 0xb1, 0x1f, 0xf5, 0x0b, 0x62, 0xaa, 0xce, 0x9a, 0x00, 0xc1, 0x0a, - 0x4b, 0x80, 0xfa, 0x9e, 0x48, 0x8d, 0xa5, 0xf1, 0x82, 0x6e, 0x09, 0x10, 0xac, 0xb0, 0xe4, 0x4e, - 0xbd, 0xc3, 0xad, 0x5d, 0xeb, 0xb3, 0x63, 0xde, 0xa9, 0x00, 0xc1, 0x0a, 0x0b, 0xd9, 0xb0, 0xe8, - 0xf9, 0xdc, 0xba, 0x38, 0x96, 0xe7, 0x59, 0x3e, 0x38, 0xb7, 0x7d, 0x8e, 0x05, 0x06, 0xfa, 0x35, - 0x80, 0x30, 0x48, 0x52, 0xf4, 0xd2, 0x48, 0xc6, 0xbd, 0x1c, 0x64, 0x23, 0xc9, 0xed, 0x1b, 0x1e, - 0x0f, 0x0f, 0x93, 0xd1, 0x23, 0x75, 0x07, 0x52, 0x2c, 0xd0, 0x1f, 0x00, 0x3c, 0x97, 0x9e, 0xa8, - 0x0c, 0xbd, 0xaa, 0x8c, 0xc8, 0x9d, 0x51, 0xa7, 0x79, 0xd3, 0xf7, 0x9d, 0xa6, 0x35, 0xe8, 0xd7, - 0xce, 0xad, 0x1d, 0x83, 0x8a, 0x8f, 0xe5, 0x82, 0xfe, 0x02, 0xe0, 0x82, 0xae, 0xa2, 0x29, 0x86, - 0x35, 0x19, 0x40, 0x3a, 0xea, 0x00, 0xe6, 0x71, 0x54, 0x1c, 0x2f, 0xe8, 0x38, 0x2e, 0x0c, 0xe9, - 0xf1, 0x30, 0x35, 0xf4, 0x77, 0x00, 0x67, 0x3a, 0x34, 0xa0, 0x5e, 0x87, 0x7a, 0x6d, 0xc1, 0x75, - 0x79, 0x24, 0x93, 0x66, 0x9e, 0xeb, 0x46, 0x0a, 0x42, 0xd1, 0x6c, 0x68, 0x9a, 0x33, 0x69, 0xd5, - 0x51, 0xbf, 0x76, 0x3e, 0x59, 0x9a, 0xd6, 0xe0, 0x0c, 0x4b, 0xf4, 0x01, 0x80, 0x73, 0xc9, 0x01, - 0xa8, 0x27, 0xe5, 0xf2, 0x18, 0xf3, 0x40, 0xb6, 0xaf, 0x6b, 0x59, 0x40, 0x9c, 0x67, 0x80, 0xfe, - 0x0a, 0x44, 0xa7, 0x16, 0xcf, 0x8d, 0xcc, 0xaa, 0xcb, 0x58, 0xbe, 0x33, 0xf2, 0x58, 0x1a, 0x04, - 0x15, 0xca, 0x17, 0x93, 0x56, 0xd0, 0x68, 0x8e, 0xfa, 0xb5, 0xc5, 0x74, 0x24, 0x8d, 0x02, 0xa7, - 0x19, 0xa2, 0x9f, 0x02, 0x38, 0x43, 0x93, 0x8e, 0x9b, 0x59, 0x57, 0x46, 0x12, 0xc4, 0x63, 0x9b, - 0x78, 0xf5, 0x37, 0xa6, 0x94, 0x8a, 0xe1, 0x0c, 0xb6, 0xe8, 0x20, 0xe9, 0x01, 0x71, 0x03, 0x87, - 0x5a, 0x9f, 0x1b, 0x71, 0x07, 0x79, 0x43, 0xf9, 0xc5, 0x31, 0xc0, 0x92, 0x98, 0x7c, 0x72, 0x37, - 0x07, 0xcd, 0xc3, 0xe2, 0x3e, 0x3d, 0x54, 0x8d, 0x3d, 0x16, 0x3f, 0x51, 0x07, 0x96, 0x7a, 0xc4, - 0x89, 0xe2, 0xe1, 0x6d, 0xc4, 0x55, 0x17, 0x2b, 0xe7, 0xaf, 0x15, 0x5e, 0x05, 0x4b, 0x8f, 0x00, - 0x3c, 0x7f, 0xfc, 0x85, 0x7e, 0xa6, 0xb4, 0x7e, 0x07, 0xe0, 0xc2, 0xd0, 0xdd, 0x3d, 0x86, 0xd1, - 0x83, 0x2c, 0xa3, 0x37, 0x46, 0x7d, 0x09, 0x5b, 0x3c, 0xb4, 0xbd, 0xae, 0xec, 0x3c, 0xd2, 0xf4, - 0x7e, 0x01, 0xe0, 0x7c, 0xfe, 0x3a, 0x3c, 0xcb, 0x78, 0xd5, 0x1f, 0x15, 0xe0, 0xf9, 0xe3, 0x1b, - 0x26, 0x14, 0x9a, 0xc9, 0x70, 0x3c, 0x13, 0x36, 0x4c, 0xa6, 0x4c, 0x33, 0x54, 0xbe, 0x07, 0x60, - 0xe5, 0xbe, 0xb1, 0x8b, 0xff, 0x53, 0x33, 0xf2, 0xd9, 0x3e, 0xae, 0x3f, 0x89, 0x82, 0xe1, 0x34, - 0x6e, 0xfd, 0x6f, 0x00, 0x2e, 0x1e, 0x5b, 0x58, 0xc5, 0x08, 0x4a, 0x1c, 0xc7, 0x7f, 0xa8, 0xfe, - 0x44, 0x93, 0xfa, 0x93, 0xd9, 0x9a, 0x94, 0x62, 0xad, 0x4d, 0x45, 0xaf, 0xf0, 0x69, 0x45, 0xaf, - 0xfe, 0x4f, 0x00, 0x2f, 0x7e, 0x5c, 0x26, 0x3e, 0x93, 0x23, 0x5d, 0x81, 0x65, 0xdd, 0x14, 0x1d, - 0xca, 0xe3, 0xd4, 0x73, 0x80, 0x2e, 0x1a, 0xf2, 0xbf, 0xe7, 0xea, 0x57, 0xf3, 0xea, 0xe3, 0x27, - 0xd5, 0x33, 0x1f, 0x3e, 0xa9, 0x9e, 0xf9, 0xe8, 0x49, 0xf5, 0xcc, 0x0f, 0x06, 0x55, 0xf0, 0x78, - 0x50, 0x05, 0x1f, 0x0e, 0xaa, 0xe0, 0xa3, 0x41, 0x15, 0xfc, 0x6b, 0x50, 0x05, 0xbf, 0xfc, 0x77, - 0xf5, 0xcc, 0x77, 0xa6, 0x34, 0xf8, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x5b, 0x62, 0x04, - 0xd6, 0x21, 0x00, 0x00, + // 2740 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0x1c, 0x47, + 0x15, 0xf7, 0xec, 0x6a, 0xa5, 0x55, 0x4b, 0xb2, 0xa4, 0xb6, 0xe5, 0x8c, 0x85, 0xbd, 0x2b, 0xad, + 0x49, 0x4a, 0x04, 0x7b, 0x15, 0x9b, 0x84, 0x84, 0x54, 0x71, 0xd0, 0x4a, 0x4a, 0x4a, 0xc6, 0xfa, + 0xa0, 0xd7, 0x76, 0x80, 0x7c, 0xb6, 0x66, 0x7b, 0x57, 0x63, 0xcd, 0x97, 0xa7, 0x67, 0x56, 0x52, + 0x05, 0x28, 0x48, 0x2a, 0x05, 0x45, 0x01, 0xa1, 0x88, 0x2f, 0x14, 0x70, 0x00, 0x8a, 0x0b, 0x45, + 0xc1, 0x01, 0x6e, 0xf0, 0x07, 0xf8, 0x98, 0xe2, 0x94, 0xd3, 0x16, 0xde, 0xfc, 0x0b, 0x54, 0x51, + 0xa5, 0x13, 0xd5, 0x1f, 0xd3, 0x33, 0x3b, 0xbb, 0x6b, 0xab, 0xe2, 0xdd, 0x98, 0x9b, 0xe6, 0xbd, + 0xd7, 0xef, 0xf7, 0xfa, 0xf5, 0x7b, 0xaf, 0x5f, 0xbf, 0x15, 0xa8, 0xef, 0xbf, 0x44, 0xcb, 0xa6, + 0xbb, 0xbc, 0x1f, 0xee, 0x12, 0xdf, 0x21, 0x01, 0xa1, 0xcb, 0x4d, 0xe2, 0xd4, 0x5c, 0x7f, 0x59, + 0x32, 0xb0, 0x67, 0x92, 0xc3, 0x80, 0x38, 0xd4, 0x74, 0x1d, 0x7a, 0x05, 0x7b, 0x26, 0x25, 0x7e, + 0x93, 0xf8, 0xcb, 0xde, 0x7e, 0x83, 0xf1, 0x68, 0xa7, 0xc0, 0x72, 0xf3, 0xea, 0x2e, 0x09, 0xf0, + 0xd5, 0xe5, 0x06, 0x71, 0x88, 0x8f, 0x03, 0x52, 0x2b, 0x7b, 0xbe, 0x1b, 0xb8, 0xf0, 0xeb, 0x42, + 0x5d, 0xb9, 0x43, 0xfa, 0x6d, 0xa5, 0xae, 0xec, 0xed, 0x37, 0x18, 0x8f, 0x76, 0x0a, 0x94, 0xa5, + 0xba, 0xf9, 0x2b, 0x0d, 0x33, 0xd8, 0x0b, 0x77, 0xcb, 0x86, 0x6b, 0x2f, 0x37, 0xdc, 0x86, 0xbb, + 0xcc, 0xb5, 0xee, 0x86, 0x75, 0xfe, 0xc5, 0x3f, 0xf8, 0x5f, 0x02, 0x6d, 0xfe, 0xf9, 0xd8, 0x78, + 0x1b, 0x1b, 0x7b, 0xa6, 0x43, 0xfc, 0xa3, 0xd8, 0x62, 0x9b, 0x04, 0x78, 0xb9, 0xd9, 0x65, 0xe3, + 0xfc, 0x72, 0xbf, 0x55, 0x7e, 0xe8, 0x04, 0xa6, 0x4d, 0xba, 0x16, 0x7c, 0xf5, 0x51, 0x0b, 0xa8, + 0xb1, 0x47, 0x6c, 0x9c, 0x5e, 0x57, 0x3a, 0xd6, 0xc0, 0xec, 0xaa, 0xeb, 0x34, 0x89, 0xcf, 0x76, + 0x89, 0xc8, 0xdd, 0x90, 0xd0, 0x00, 0x56, 0x40, 0x36, 0x34, 0x6b, 0xba, 0xb6, 0xa0, 0x2d, 0x8d, + 0x57, 0x9e, 0xbb, 0xdf, 0x2a, 0x9e, 0x6a, 0xb7, 0x8a, 0xd9, 0x5b, 0x1b, 0x6b, 0xc7, 0xad, 0xe2, + 0x62, 0x3f, 0xa4, 0xe0, 0xc8, 0x23, 0xb4, 0x7c, 0x6b, 0x63, 0x0d, 0xb1, 0xc5, 0xf0, 0x55, 0x30, + 0x5b, 0x23, 0xd4, 0xf4, 0x49, 0x6d, 0x65, 0x67, 0xe3, 0xb6, 0xd0, 0xaf, 0x67, 0xb8, 0xc6, 0xf3, + 0x52, 0xe3, 0xec, 0x5a, 0x5a, 0x00, 0x75, 0xaf, 0x81, 0xdf, 0x02, 0x63, 0xee, 0xee, 0x1d, 0x62, + 0x04, 0x54, 0xcf, 0x2e, 0x64, 0x97, 0x26, 0xae, 0x5d, 0x29, 0xc7, 0x27, 0xa8, 0x4c, 0xe0, 0xc7, + 0x26, 0x37, 0x5b, 0x46, 0xf8, 0x60, 0x3d, 0x3a, 0xb9, 0xca, 0xb4, 0x44, 0x1b, 0xdb, 0x16, 0x5a, + 0x50, 0xa4, 0xae, 0xf4, 0x87, 0x0c, 0x80, 0xc9, 0xcd, 0x53, 0xcf, 0x75, 0x28, 0x19, 0xc8, 0xee, + 0x29, 0x98, 0x31, 0xb8, 0xe6, 0x80, 0xd4, 0x24, 0xae, 0x9e, 0xf9, 0x2c, 0xd6, 0xeb, 0x12, 0x7f, + 0x66, 0x35, 0xa5, 0x0e, 0x75, 0x01, 0xc0, 0x9b, 0x60, 0xd4, 0x27, 0x34, 0xb4, 0x02, 0x3d, 0xbb, + 0xa0, 0x2d, 0x4d, 0x5c, 0xbb, 0xdc, 0x17, 0x8a, 0xc7, 0x37, 0x0b, 0xbe, 0x72, 0xf3, 0x6a, 0xb9, + 0x1a, 0xe0, 0x20, 0xa4, 0x95, 0xd3, 0x12, 0x69, 0x14, 0x71, 0x1d, 0x48, 0xea, 0x2a, 0xfd, 0x38, + 0x03, 0x66, 0x92, 0x5e, 0x6a, 0x9a, 0xe4, 0x00, 0x1e, 0x80, 0x31, 0x5f, 0x04, 0x0b, 0xf7, 0xd3, + 0xc4, 0xb5, 0x9d, 0xf2, 0x63, 0xa5, 0x55, 0xb9, 0x2b, 0x08, 0x2b, 0x13, 0xec, 0xcc, 0xe4, 0x07, + 0x8a, 0xd0, 0xe0, 0xbb, 0x20, 0xef, 0xcb, 0x83, 0xe2, 0xd1, 0x34, 0x71, 0xed, 0x9b, 0x03, 0x44, + 0x16, 0x8a, 0x2b, 0x93, 0xed, 0x56, 0x31, 0x1f, 0x7d, 0x21, 0x05, 0x58, 0xfa, 0x28, 0x03, 0x0a, + 0xab, 0x21, 0x0d, 0x5c, 0x1b, 0x11, 0xea, 0x86, 0xbe, 0x41, 0x56, 0x5d, 0x2b, 0xb4, 0x9d, 0x35, + 0x52, 0x37, 0x1d, 0x33, 0x60, 0xd1, 0xba, 0x00, 0x46, 0x1c, 0x6c, 0x13, 0x19, 0x3d, 0x93, 0xd2, + 0xa7, 0x23, 0x5b, 0xd8, 0x26, 0x88, 0x73, 0x98, 0x04, 0x0b, 0x16, 0x99, 0x0b, 0x4a, 0xe2, 0xe6, + 0x91, 0x47, 0x10, 0xe7, 0xc0, 0x67, 0xc0, 0x68, 0xdd, 0xf5, 0x6d, 0x2c, 0xce, 0x71, 0x3c, 0x3e, + 0x99, 0x57, 0x38, 0x15, 0x49, 0x2e, 0x7c, 0x01, 0x4c, 0xd4, 0x08, 0x35, 0x7c, 0xd3, 0x63, 0xd0, + 0xfa, 0x08, 0x17, 0x3e, 0x23, 0x85, 0x27, 0xd6, 0x62, 0x16, 0x4a, 0xca, 0xc1, 0xcb, 0x20, 0xef, + 0xf9, 0xa6, 0xeb, 0x9b, 0xc1, 0x91, 0x9e, 0x5b, 0xd0, 0x96, 0x72, 0x95, 0x19, 0xb9, 0x26, 0xbf, + 0x23, 0xe9, 0x48, 0x49, 0xc0, 0x05, 0x90, 0xbf, 0x5e, 0xdd, 0xde, 0xda, 0xc1, 0xc1, 0x9e, 0x3e, + 0xca, 0x11, 0x46, 0x98, 0x34, 0xca, 0xdf, 0x91, 0xd4, 0xd2, 0x7b, 0x19, 0xa0, 0xa7, 0xbd, 0x12, + 0xb9, 0x14, 0xbe, 0x02, 0xf2, 0x34, 0x60, 0x15, 0xa7, 0x71, 0x24, 0x7d, 0xf2, 0x6c, 0x04, 0x56, + 0x95, 0xf4, 0xe3, 0x56, 0xf1, 0x5c, 0xbc, 0x22, 0xa2, 0x72, 0x7f, 0xa8, 0xb5, 0xf0, 0xb7, 0x1a, + 0x38, 0x73, 0x40, 0x76, 0xf7, 0x5c, 0x77, 0x7f, 0xd5, 0x32, 0x89, 0x13, 0xac, 0xba, 0x4e, 0xdd, + 0x6c, 0xc8, 0x18, 0x40, 0x8f, 0x19, 0x03, 0xaf, 0x75, 0x6b, 0xae, 0x3c, 0xd5, 0x6e, 0x15, 0xcf, + 0xf4, 0x60, 0xa0, 0x5e, 0x76, 0x94, 0xde, 0xcf, 0xa6, 0x9d, 0x90, 0x08, 0x8a, 0x77, 0x40, 0x9e, + 0x25, 0x5b, 0x0d, 0x07, 0x58, 0xa6, 0xcb, 0x73, 0x27, 0x4b, 0x4d, 0x91, 0xd9, 0x9b, 0x24, 0xc0, + 0x15, 0x28, 0xdd, 0x06, 0x62, 0x1a, 0x52, 0x5a, 0xe1, 0xf7, 0xc0, 0x08, 0xf5, 0x88, 0x21, 0xdd, + 0xf1, 0xfa, 0xe3, 0xa6, 0x44, 0x9f, 0x8d, 0x54, 0x3d, 0x62, 0xc4, 0x11, 0xcb, 0xbe, 0x10, 0x87, + 0x85, 0x1f, 0x68, 0x60, 0x94, 0xf2, 0x32, 0x22, 0x4b, 0xcf, 0x9b, 0xc3, 0xb2, 0x20, 0x55, 0xab, + 0xc4, 0x37, 0x92, 0xe0, 0xa5, 0xff, 0x64, 0xc0, 0x62, 0xbf, 0xa5, 0xab, 0xae, 0x53, 0x13, 0xc7, + 0xb1, 0x21, 0x33, 0x50, 0xc4, 0xe3, 0x0b, 0xc9, 0x0c, 0x3c, 0x6e, 0x15, 0x9f, 0x7e, 0xa4, 0x82, + 0x44, 0xaa, 0x7e, 0x4d, 0xed, 0x5b, 0xa4, 0xf3, 0x62, 0xa7, 0x61, 0xc7, 0xad, 0xe2, 0xb4, 0x5a, + 0xd6, 0x69, 0x2b, 0x6c, 0x02, 0x68, 0x61, 0x1a, 0xdc, 0xf4, 0xb1, 0x43, 0x85, 0x5a, 0xd3, 0x26, + 0xd2, 0x7d, 0xcf, 0x9e, 0x2c, 0x3c, 0xd8, 0x8a, 0xca, 0xbc, 0x84, 0x84, 0x37, 0xba, 0xb4, 0xa1, + 0x1e, 0x08, 0xac, 0xba, 0xf8, 0x04, 0x53, 0x55, 0x30, 0x12, 0x75, 0x9f, 0x51, 0x91, 0xe4, 0xc2, + 0x2f, 0x81, 0x31, 0x9b, 0x50, 0x8a, 0x1b, 0x84, 0x57, 0x89, 0xf1, 0xf8, 0x22, 0xdd, 0x14, 0x64, + 0x14, 0xf1, 0x59, 0x17, 0x71, 0xa1, 0x9f, 0xd7, 0x6e, 0x98, 0x34, 0x80, 0x6f, 0x74, 0x25, 0x40, + 0xf9, 0x64, 0x3b, 0x64, 0xab, 0x79, 0xf8, 0xab, 0x12, 0x15, 0x51, 0x12, 0xc1, 0xff, 0x5d, 0x90, + 0x33, 0x03, 0x62, 0x47, 0x37, 0xec, 0x6b, 0x43, 0x8a, 0xbd, 0xca, 0x94, 0xb4, 0x21, 0xb7, 0xc1, + 0xd0, 0x90, 0x00, 0x2d, 0xfd, 0x31, 0x03, 0x2e, 0xf6, 0x5b, 0xc2, 0xca, 0x3e, 0x65, 0x1e, 0xf7, + 0xac, 0xd0, 0xc7, 0x96, 0x8c, 0x38, 0xe5, 0xf1, 0x1d, 0x4e, 0x45, 0x92, 0xcb, 0x0a, 0x33, 0x35, + 0x9d, 0x46, 0x68, 0x61, 0x5f, 0x86, 0x93, 0xda, 0x75, 0x55, 0xd2, 0x91, 0x92, 0x80, 0x65, 0x00, + 0xe8, 0x9e, 0xeb, 0x07, 0x1c, 0x83, 0xb7, 0x46, 0xe3, 0x95, 0xd3, 0xac, 0x40, 0x54, 0x15, 0x15, + 0x25, 0x24, 0xd8, 0xbd, 0xb3, 0x6f, 0x3a, 0x35, 0x79, 0xea, 0x2a, 0x8b, 0xbf, 0x61, 0x3a, 0x35, + 0xc4, 0x39, 0x0c, 0xdf, 0x32, 0x69, 0xc0, 0x28, 0xf2, 0xc8, 0x3b, 0xbc, 0xce, 0x25, 0x95, 0x04, + 0xc3, 0x37, 0x58, 0x6d, 0x76, 0x7d, 0x93, 0x50, 0x7d, 0x34, 0xc6, 0x5f, 0x55, 0x54, 0x94, 0x90, + 0x28, 0xfd, 0x3a, 0xdf, 0x3f, 0x48, 0x58, 0x29, 0x81, 0x97, 0x40, 0xae, 0xe1, 0xbb, 0xa1, 0x27, + 0xbd, 0xa4, 0xbc, 0xfd, 0x2a, 0x23, 0x22, 0xc1, 0x63, 0x51, 0xd9, 0xec, 0x68, 0x26, 0x55, 0x54, + 0x46, 0x2d, 0x64, 0xc4, 0x87, 0x3f, 0xd4, 0x40, 0xce, 0x91, 0xce, 0x61, 0x21, 0xf7, 0xc6, 0x90, + 0xe2, 0x82, 0xbb, 0x37, 0x36, 0x57, 0x78, 0x5e, 0x20, 0xc3, 0xe7, 0x41, 0x8e, 0x1a, 0xae, 0x47, + 0xa4, 0xd7, 0x0b, 0x91, 0x50, 0x95, 0x11, 0x8f, 0x5b, 0xc5, 0xa9, 0x48, 0x1d, 0x27, 0x20, 0x21, + 0x0c, 0x7f, 0xa4, 0x01, 0xd0, 0xc4, 0x96, 0x59, 0xc3, 0xfc, 0x62, 0xcf, 0x71, 0xf3, 0x07, 0x1b, + 0xd6, 0xb7, 0x95, 0x7a, 0x71, 0x68, 0xf1, 0x37, 0x4a, 0x40, 0xc3, 0x0f, 0x35, 0x30, 0x49, 0xc3, + 0x5d, 0x5f, 0xae, 0xa2, 0xbc, 0x05, 0x98, 0xb8, 0xf6, 0xed, 0x81, 0xda, 0x52, 0x4d, 0x00, 0x54, + 0x66, 0xda, 0xad, 0xe2, 0x64, 0x92, 0x82, 0x3a, 0x0c, 0x80, 0x3f, 0xd5, 0x40, 0x5e, 0x9e, 0x30, + 0xd5, 0xc7, 0x78, 0xc2, 0xbf, 0x35, 0xa4, 0x83, 0x95, 0x11, 0x15, 0x67, 0x81, 0x24, 0x50, 0xa4, + 0x2c, 0x80, 0xff, 0xd0, 0x80, 0x8e, 0x6b, 0xa2, 0xc0, 0x63, 0x6b, 0xc7, 0x37, 0x9d, 0x80, 0xf8, + 0xa2, 0x2b, 0xa4, 0x7a, 0x9e, 0x9b, 0x37, 0xd8, 0xbb, 0x30, 0xdd, 0x71, 0x56, 0x16, 0xa4, 0x75, + 0xfa, 0x4a, 0x1f, 0x33, 0x50, 0x5f, 0x03, 0x79, 0xa0, 0x19, 0xaa, 0xf5, 0xd2, 0xc7, 0x87, 0x10, + 0x68, 0x71, 0x67, 0x27, 0xab, 0x43, 0xdc, 0x6e, 0x27, 0xa0, 0x4b, 0x1f, 0x66, 0xd3, 0xad, 0x75, + 0xfa, 0xd2, 0x87, 0xf7, 0x84, 0xb1, 0x62, 0x2b, 0x54, 0xd7, 0xb8, 0x73, 0xdf, 0x19, 0xd2, 0xd9, + 0xab, 0x5b, 0x3b, 0x6e, 0xbc, 0x14, 0x89, 0xa2, 0x84, 0x1d, 0xf0, 0x57, 0x1a, 0x98, 0xc2, 0x86, + 0x41, 0xbc, 0x80, 0xd4, 0x44, 0x2d, 0xce, 0x7c, 0x0e, 0xe5, 0x66, 0x4e, 0x5a, 0x35, 0xb5, 0x92, + 0x84, 0x46, 0x9d, 0x96, 0xc0, 0x97, 0xc1, 0x69, 0x1a, 0xb8, 0x3e, 0xa9, 0x45, 0x91, 0x2b, 0xef, + 0x09, 0xd8, 0x6e, 0x15, 0x4f, 0x57, 0x3b, 0x38, 0x28, 0x25, 0x59, 0xfa, 0x74, 0x04, 0x14, 0x1f, + 0x91, 0x19, 0x27, 0x78, 0xed, 0x3c, 0x03, 0x46, 0xf9, 0x76, 0x6b, 0xdc, 0x2b, 0xf9, 0x44, 0xe7, + 0xc6, 0xa9, 0x48, 0x72, 0x59, 0x5d, 0x67, 0xf8, 0xac, 0xdb, 0xc8, 0x72, 0x41, 0x55, 0xd7, 0xab, + 0x82, 0x8c, 0x22, 0x3e, 0x7c, 0x17, 0x8c, 0x8a, 0x69, 0x06, 0x2f, 0xaa, 0x43, 0x2c, 0x8c, 0x80, + 0xdb, 0xc9, 0xa1, 0x90, 0x84, 0xec, 0x2e, 0x88, 0xb9, 0x27, 0x5d, 0x10, 0x1f, 0x5a, 0x81, 0x46, + 0xff, 0xcf, 0x2b, 0x50, 0xe9, 0xbf, 0x5a, 0x3a, 0xef, 0x13, 0x5b, 0xad, 0x1a, 0xd8, 0x22, 0x70, + 0x0d, 0xcc, 0xb0, 0x47, 0x06, 0x22, 0x9e, 0x65, 0x1a, 0x98, 0xf2, 0x97, 0xa8, 0x08, 0x38, 0x35, + 0x1c, 0xa9, 0xa6, 0xf8, 0xa8, 0x6b, 0x05, 0xbc, 0x0e, 0xa0, 0x68, 0xbc, 0x3b, 0xf4, 0x88, 0x1e, + 0x42, 0xb5, 0xd0, 0xd5, 0x2e, 0x09, 0xd4, 0x63, 0x15, 0x5c, 0x05, 0xb3, 0x16, 0xde, 0x25, 0x56, + 0x95, 0x58, 0xc4, 0x08, 0x5c, 0x9f, 0xab, 0x12, 0x6f, 0xf5, 0xb9, 0x76, 0xab, 0x38, 0x7b, 0x23, + 0xcd, 0x44, 0xdd, 0xf2, 0xa5, 0xc5, 0x74, 0x7a, 0x25, 0x37, 0x2e, 0x9e, 0x33, 0xbf, 0xcb, 0x80, + 0xf9, 0xfe, 0x91, 0x01, 0xdf, 0x8b, 0x5f, 0x5d, 0xa2, 0xa9, 0x7e, 0x6b, 0x58, 0x51, 0x28, 0x9f, + 0x5d, 0xa0, 0xfb, 0xc9, 0x05, 0xbf, 0xcf, 0x3a, 0x1c, 0x6c, 0x45, 0xd3, 0x98, 0x37, 0x87, 0x66, + 0x02, 0x03, 0xa9, 0x8c, 0x8b, 0xe6, 0x09, 0x5b, 0xbc, 0x57, 0xc2, 0x16, 0x29, 0xfd, 0x49, 0x4b, + 0x3f, 0xbc, 0xe3, 0x0c, 0x86, 0x3f, 0xd3, 0xc0, 0xb4, 0xeb, 0x11, 0x67, 0x65, 0x67, 0xe3, 0xf6, + 0x57, 0x44, 0x26, 0x4b, 0x57, 0x6d, 0x3d, 0xa6, 0x9d, 0xd7, 0xab, 0xdb, 0x5b, 0x42, 0xe1, 0x8e, + 0xef, 0x7a, 0xb4, 0x72, 0xa6, 0xdd, 0x2a, 0x4e, 0x6f, 0x77, 0x42, 0xa1, 0x34, 0x76, 0xc9, 0x06, + 0x73, 0xeb, 0x87, 0x01, 0xf1, 0x1d, 0x6c, 0xad, 0xb9, 0x46, 0x68, 0x13, 0x27, 0x10, 0x86, 0xa6, + 0x46, 0x39, 0xda, 0x09, 0x47, 0x39, 0x17, 0x41, 0x36, 0xf4, 0x2d, 0x19, 0xc5, 0x13, 0x6a, 0x54, + 0x89, 0x6e, 0x20, 0x46, 0x2f, 0x2d, 0x82, 0x11, 0x66, 0x27, 0x3c, 0x0f, 0xb2, 0x3e, 0x3e, 0xe0, + 0x5a, 0x27, 0x2b, 0x63, 0x4c, 0x04, 0xe1, 0x03, 0xc4, 0x68, 0xa5, 0x3f, 0x5f, 0x00, 0xd3, 0xa9, + 0xbd, 0xc0, 0x79, 0x90, 0x51, 0xf3, 0x4f, 0x20, 0x95, 0x66, 0x36, 0xd6, 0x50, 0xc6, 0xac, 0xc1, + 0x17, 0x55, 0xf1, 0x15, 0xa0, 0x45, 0x55, 0xcf, 0x39, 0x95, 0xb5, 0xb4, 0xb1, 0x3a, 0x66, 0x48, + 0x54, 0x38, 0x99, 0x0d, 0xa4, 0x2e, 0xb3, 0x44, 0xd8, 0x40, 0xea, 0x88, 0xd1, 0x3e, 0xeb, 0x1c, + 0x2b, 0x1a, 0xa4, 0xe5, 0x4e, 0x30, 0x48, 0x1b, 0x7d, 0xe8, 0x20, 0xed, 0x12, 0xc8, 0x05, 0x66, + 0x60, 0x11, 0x7d, 0xac, 0xf3, 0xe5, 0x71, 0x93, 0x11, 0x91, 0xe0, 0xc1, 0x3b, 0x60, 0xac, 0x46, + 0xea, 0x38, 0xb4, 0x02, 0x3d, 0xcf, 0x43, 0x68, 0x75, 0x00, 0x21, 0x24, 0xa6, 0x9c, 0x6b, 0x42, + 0x2f, 0x8a, 0x00, 0xe0, 0xd3, 0x60, 0xcc, 0xc6, 0x87, 0xa6, 0x1d, 0xda, 0xbc, 0x27, 0xd3, 0x84, + 0xd8, 0xa6, 0x20, 0xa1, 0x88, 0xc7, 0x2a, 0x23, 0x39, 0x34, 0xac, 0x90, 0x9a, 0x4d, 0x22, 0x99, + 0x3a, 0xe0, 0xb7, 0xa7, 0xaa, 0x8c, 0xeb, 0x29, 0x3e, 0xea, 0x5a, 0xc1, 0xc1, 0x4c, 0x87, 0x2f, + 0x9e, 0x48, 0x80, 0x09, 0x12, 0x8a, 0x78, 0x9d, 0x60, 0x52, 0x7e, 0xb2, 0x1f, 0x98, 0x5c, 0xdc, + 0xb5, 0x02, 0x7e, 0x19, 0x8c, 0xdb, 0xf8, 0xf0, 0x06, 0x71, 0x1a, 0xc1, 0x9e, 0x3e, 0xb5, 0xa0, + 0x2d, 0x65, 0x2b, 0x53, 0xed, 0x56, 0x71, 0x7c, 0x33, 0x22, 0xa2, 0x98, 0xcf, 0x85, 0x4d, 0x47, + 0x0a, 0x9f, 0x4e, 0x08, 0x47, 0x44, 0x14, 0xf3, 0x59, 0x07, 0xe1, 0xe1, 0x80, 0x25, 0x97, 0x3e, + 0xdd, 0xf9, 0x32, 0xdc, 0x11, 0x64, 0x14, 0xf1, 0xe1, 0x12, 0xc8, 0xdb, 0xf8, 0x90, 0xbf, 0xe2, + 0xf5, 0x19, 0xae, 0x96, 0x4f, 0x7c, 0x37, 0x25, 0x0d, 0x29, 0x2e, 0x97, 0x34, 0x1d, 0x21, 0x39, + 0x9b, 0x90, 0x94, 0x34, 0xa4, 0xb8, 0x2c, 0x88, 0x43, 0xc7, 0xbc, 0x1b, 0x12, 0x21, 0x0c, 0xb9, + 0x67, 0x54, 0x10, 0xdf, 0x8a, 0x59, 0x28, 0x29, 0xc7, 0x5e, 0xd1, 0x76, 0x68, 0x05, 0xa6, 0x67, + 0x91, 0xed, 0xba, 0x7e, 0x86, 0xfb, 0x9f, 0xf7, 0xc9, 0x9b, 0x8a, 0x8a, 0x12, 0x12, 0x90, 0x80, + 0x11, 0xe2, 0x84, 0xb6, 0x7e, 0x96, 0x5f, 0xec, 0x03, 0x09, 0x41, 0x95, 0x39, 0xeb, 0x4e, 0x68, + 0x23, 0xae, 0x1e, 0xbe, 0x08, 0xa6, 0x6c, 0x7c, 0xc8, 0xca, 0x01, 0xf1, 0x03, 0xf6, 0xbe, 0x9f, + 0xe3, 0x9b, 0x9f, 0x65, 0x1d, 0xe7, 0x66, 0x92, 0x81, 0x3a, 0xe5, 0xf8, 0x42, 0xd3, 0x49, 0x2c, + 0x3c, 0x97, 0x58, 0x98, 0x64, 0xa0, 0x4e, 0x39, 0xe6, 0x69, 0x9f, 0xdc, 0x0d, 0x4d, 0x9f, 0xd4, + 0xf4, 0xa7, 0x78, 0x93, 0x2a, 0xa7, 0xf0, 0x82, 0x86, 0x14, 0x17, 0x36, 0xa3, 0x71, 0x8f, 0xce, + 0xd3, 0xf0, 0xd6, 0x60, 0x2b, 0xf9, 0xb6, 0xbf, 0xe2, 0xfb, 0xf8, 0x48, 0xdc, 0x34, 0xc9, 0x41, + 0x0f, 0xa4, 0x20, 0x87, 0x2d, 0x6b, 0xbb, 0xae, 0x9f, 0xe7, 0xbe, 0x1f, 0xf4, 0x0d, 0xa2, 0xaa, + 0xce, 0x0a, 0x03, 0x41, 0x02, 0x8b, 0x81, 0xba, 0x0e, 0x0b, 0x8d, 0xf9, 0xe1, 0x82, 0x6e, 0x33, + 0x10, 0x24, 0xb0, 0xf8, 0x4e, 0x9d, 0xa3, 0xed, 0xba, 0xfe, 0x85, 0x21, 0xef, 0x94, 0x81, 0x20, + 0x81, 0x05, 0x4d, 0x90, 0x75, 0xdc, 0x40, 0xbf, 0x30, 0x94, 0xeb, 0x99, 0x5f, 0x38, 0x5b, 0x6e, + 0x80, 0x18, 0x06, 0xfc, 0xa5, 0x06, 0x80, 0x17, 0x87, 0xe8, 0xc5, 0x81, 0x4c, 0x11, 0x52, 0x90, + 0xe5, 0x38, 0xb6, 0xd7, 0x9d, 0xc0, 0x3f, 0x8a, 0xdf, 0x91, 0x89, 0x1c, 0x48, 0x58, 0x01, 0x7f, + 0xaf, 0x81, 0xb3, 0xc9, 0x36, 0x59, 0x99, 0x57, 0xe0, 0x1e, 0xb9, 0x39, 0xe8, 0x30, 0xaf, 0xb8, + 0xae, 0x55, 0xd1, 0xdb, 0xad, 0xe2, 0xd9, 0x95, 0x1e, 0xa8, 0xa8, 0xa7, 0x2d, 0xf0, 0x2f, 0x1a, + 0x98, 0x95, 0x55, 0x34, 0x61, 0x61, 0x91, 0x3b, 0x90, 0x0c, 0xda, 0x81, 0x69, 0x1c, 0xe1, 0x47, + 0xf5, 0xeb, 0x71, 0x17, 0x1f, 0x75, 0x9b, 0x06, 0xff, 0xae, 0x81, 0xc9, 0x1a, 0xf1, 0x88, 0x53, + 0x23, 0x8e, 0xc1, 0x6c, 0x5d, 0x18, 0xc8, 0xd8, 0x20, 0x6d, 0xeb, 0x5a, 0x02, 0x42, 0x98, 0x59, + 0x96, 0x66, 0x4e, 0x26, 0x59, 0xc7, 0xad, 0xe2, 0xb9, 0x78, 0x69, 0x92, 0x83, 0x3a, 0xac, 0x84, + 0x1f, 0x69, 0x60, 0x3a, 0x3e, 0x00, 0x71, 0xa5, 0x2c, 0x0e, 0x31, 0x0e, 0x78, 0xfb, 0xba, 0xd2, + 0x09, 0x88, 0xd2, 0x16, 0xc0, 0xbf, 0x6a, 0xac, 0x53, 0x8b, 0xde, 0x7d, 0x54, 0x2f, 0x71, 0x5f, + 0xbe, 0x3d, 0x70, 0x5f, 0x2a, 0x04, 0xe1, 0xca, 0xcb, 0x71, 0x2b, 0xa8, 0x38, 0xc7, 0xad, 0xe2, + 0x5c, 0xd2, 0x93, 0x8a, 0x81, 0x92, 0x16, 0xc2, 0x9f, 0x68, 0x60, 0x92, 0xc4, 0x1d, 0x37, 0xd5, + 0x2f, 0x0d, 0xc4, 0x89, 0x3d, 0x9b, 0x78, 0xf1, 0x52, 0x4f, 0xb0, 0x28, 0xea, 0xc0, 0x66, 0x1d, + 0x24, 0x39, 0xc4, 0xb6, 0x67, 0x11, 0xfd, 0x8b, 0x03, 0xee, 0x20, 0xd7, 0x85, 0x5e, 0x14, 0x01, + 0xcc, 0xb3, 0x97, 0x4f, 0x2a, 0x73, 0xe0, 0x0c, 0xc8, 0xee, 0x13, 0xf9, 0x33, 0x2c, 0x62, 0x7f, + 0xc2, 0x1a, 0xc8, 0x35, 0xb1, 0x15, 0x46, 0x8f, 0xb7, 0x01, 0x57, 0x5d, 0x24, 0x94, 0xbf, 0x9c, + 0x79, 0x49, 0x9b, 0xbf, 0xa7, 0x81, 0x73, 0xbd, 0x13, 0xfa, 0x89, 0x9a, 0xf5, 0x1b, 0x0d, 0xcc, + 0x76, 0xe5, 0x6e, 0x0f, 0x8b, 0xee, 0x76, 0x5a, 0xf4, 0xfa, 0xa0, 0x93, 0xb0, 0x1a, 0xf8, 0xa6, + 0xd3, 0xe0, 0x9d, 0x47, 0xd2, 0xbc, 0x9f, 0x6b, 0x60, 0x26, 0x9d, 0x0e, 0x4f, 0xd2, 0x5f, 0xa5, + 0x7b, 0x19, 0x70, 0xae, 0x77, 0xc3, 0x04, 0x7d, 0xf5, 0x32, 0x1c, 0xce, 0x0b, 0xbb, 0xd7, 0x34, + 0xee, 0x03, 0x0d, 0x4c, 0xdc, 0x51, 0x72, 0xd1, 0x0f, 0x80, 0x03, 0x7f, 0xdb, 0x47, 0xf5, 0x27, + 0x66, 0x50, 0x94, 0xc4, 0x2d, 0xfd, 0x4d, 0x03, 0x73, 0x3d, 0x0b, 0x2b, 0x7b, 0x82, 0x62, 0xcb, + 0x72, 0x0f, 0xc4, 0x88, 0x26, 0x31, 0xff, 0x5c, 0xe1, 0x54, 0x24, 0xb9, 0x09, 0xef, 0x65, 0x3e, + 0x2f, 0xef, 0x95, 0xfe, 0xa9, 0x81, 0x0b, 0x0f, 0x8b, 0xc4, 0x27, 0x72, 0xa4, 0x4b, 0x20, 0x2f, + 0x9b, 0xa2, 0x23, 0x7e, 0x9c, 0xf2, 0x1d, 0x20, 0x8b, 0x06, 0xff, 0xcf, 0x14, 0xf1, 0x57, 0xe9, + 0x7d, 0x0d, 0xcc, 0x54, 0x89, 0xdf, 0x34, 0x0d, 0x82, 0x48, 0x9d, 0xf8, 0xc4, 0x31, 0x08, 0x5c, + 0x06, 0xe3, 0xfc, 0x97, 0x37, 0x0f, 0x1b, 0xd1, 0x58, 0x7a, 0x56, 0xba, 0x7c, 0x7c, 0x2b, 0x62, + 0xa0, 0x58, 0x46, 0x8d, 0xb0, 0x33, 0x7d, 0x47, 0xd8, 0x17, 0xc0, 0x88, 0x17, 0x0f, 0xf8, 0xf2, + 0x8c, 0xcb, 0x67, 0x7a, 0x9c, 0x5a, 0xfa, 0x97, 0x06, 0x7a, 0xfd, 0x97, 0x08, 0x6c, 0x82, 0x31, + 0x2a, 0x8c, 0x93, 0xce, 0xdb, 0x7e, 0x4c, 0xe7, 0xa5, 0xb7, 0x2a, 0x0a, 0x7f, 0x44, 0x8d, 0xc0, + 0x98, 0xff, 0x0c, 0x5c, 0x09, 0x9d, 0x9a, 0x1c, 0xc9, 0x4d, 0x0a, 0xff, 0xad, 0xae, 0x08, 0x1a, + 0x52, 0x5c, 0x78, 0x5e, 0x0c, 0x8f, 0x12, 0x13, 0x99, 0x68, 0x70, 0x54, 0xb9, 0x72, 0xff, 0x41, + 0xe1, 0xd4, 0xc7, 0x0f, 0x0a, 0xa7, 0x3e, 0x79, 0x50, 0x38, 0xf5, 0x83, 0x76, 0x41, 0xbb, 0xdf, + 0x2e, 0x68, 0x1f, 0xb7, 0x0b, 0xda, 0x27, 0xed, 0x82, 0xf6, 0xef, 0x76, 0x41, 0xfb, 0xc5, 0xa7, + 0x85, 0x53, 0xdf, 0x19, 0x93, 0xa6, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xc5, 0xe4, 0x3a, + 0xbb, 0x29, 0x00, 0x00, } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto index b23163d04a49d..8ee83cf567033 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto @@ -28,6 +28,51 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". option go_package = "v1beta1"; +// ConversionRequest describes the conversion request parameters. +message ConversionRequest { + // `uid` is an identifier for the individual request/response. It allows us to distinguish instances of requests which are + // otherwise identical (parallel requests, requests when earlier requests did not modify etc) + // The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. + // It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + optional string uid = 1; + + // `desiredAPIVersion` is the version to convert given objects to. e.g. "myapi.example.com/v1" + optional string desiredAPIVersion = 2; + + // `objects` is the list of CR objects to be converted. + repeated k8s.io.apimachinery.pkg.runtime.RawExtension objects = 3; +} + +// ConversionResponse describes a conversion response. +message ConversionResponse { + // `uid` is an identifier for the individual request/response. + // This should be copied over from the corresponding AdmissionRequest. + optional string uid = 1; + + // `convertedObjects` is the list of converted version of `request.objects` if the `result` is successful otherwise empty. + // The webhook is expected to set apiVersion of these objects to the ConversionRequest.desiredAPIVersion. The list + // must also has the same size as input list with the same objects in the same order(i.e. equal UIDs and object meta) + repeated k8s.io.apimachinery.pkg.runtime.RawExtension convertedObjects = 2; + + // `result` contains the result of conversion with extra details if the conversion failed. `result.status` determines if + // the conversion failed or succeeded. The `result.status` field is required and represent the success or failure of the + // conversion. A successful conversion must set `result.status` to `Success`. A failed conversion must set + // `result.status` to `Failure` and provide more details in `result.message` and return http status 200. The `result.message` + // will be used to construct an error message for the end user. + optional k8s.io.apimachinery.pkg.apis.meta.v1.Status result = 3; +} + +// ConversionReview describes a conversion request/response. +message ConversionReview { + // `request` describes the attributes for the conversion request. + // +optional + optional ConversionRequest request = 1; + + // `response` describes the attributes for the conversion response. + // +optional + optional ConversionResponse response = 2; +} + // CustomResourceColumnDefinition specifies a column for server side printing. message CustomResourceColumnDefinition { // name is a human readable name for the column. @@ -57,6 +102,19 @@ message CustomResourceColumnDefinition { optional string JSONPath = 6; } +// CustomResourceConversion describes how to convert different versions of a CR. +message CustomResourceConversion { + // `strategy` specifies the conversion strategy. Allowed values are: + // - `None`: The converter only change the apiVersion and would not touch any other field in the CR. + // - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option. + optional string strategy = 1; + + // `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`. This field is + // alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // +optional + optional WebhookClientConfig webhookClientConfig = 2; +} + // CustomResourceDefinition represents a resource that should be exposed on the API server. Its name MUST be in the format // <.spec.name>.<.spec.group>. message CustomResourceDefinition { @@ -145,10 +203,14 @@ message CustomResourceDefinitionSpec { optional string scope = 4; // Validation describes the validation methods for CustomResources + // Optional, the global validation schema for all versions. + // Top-level and per-version schemas are mutually exclusive. // +optional optional CustomResourceValidation validation = 5; - // Subresources describes the subresources for CustomResources + // Subresources describes the subresources for CustomResource + // Optional, the global subresources for all versions. + // Top-level and per-version subresources are mutually exclusive. // +optional optional CustomResourceSubresources subresources = 6; @@ -167,8 +229,14 @@ message CustomResourceDefinitionSpec { repeated CustomResourceDefinitionVersion versions = 7; // AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column. + // Optional, the global columns for all versions. + // Top-level and per-version columns are mutually exclusive. // +optional repeated CustomResourceColumnDefinition additionalPrinterColumns = 8; + + // `conversion` defines conversion settings for the CRD. + // +optional + optional CustomResourceConversion conversion = 9; } // CustomResourceDefinitionStatus indicates the state of the CustomResourceDefinition @@ -189,6 +257,7 @@ message CustomResourceDefinitionStatus { repeated string storedVersions = 3; } +// CustomResourceDefinitionVersion describes a version for CRD. message CustomResourceDefinitionVersion { // Name is the version name, e.g. “v1”, “v2beta1”, etc. optional string name = 1; @@ -199,6 +268,30 @@ message CustomResourceDefinitionVersion { // Storage flags the version as storage version. There must be exactly one // flagged as storage version. optional bool storage = 3; + + // Schema describes the schema for CustomResource used in validation, pruning, and defaulting. + // Top-level and per-version schemas are mutually exclusive. + // Per-version schemas must not all be set to identical values (top-level validation schema should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // +optional + optional CustomResourceValidation schema = 4; + + // Subresources describes the subresources for CustomResource + // Top-level and per-version subresources are mutually exclusive. + // Per-version subresources must not all be set to identical values (top-level subresources should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // +optional + optional CustomResourceSubresources subresources = 5; + + // AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column. + // Top-level and per-version columns are mutually exclusive. + // Per-version columns must not all be set to identical values (top-level columns should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // NOTE: CRDs created prior to 1.13 populated the top-level additionalPrinterColumns field by default. To apply an + // update that changes to per-version additionalPrinterColumns, the top-level additionalPrinterColumns field must + // be explicitly set to null + // +optional + repeated CustomResourceColumnDefinition additionalPrinterColumns = 6; } // CustomResourceSubresourceScale defines how to serve the scale subresource for CustomResources. @@ -363,3 +456,67 @@ message JSONSchemaPropsOrStringArray { repeated string property = 2; } +// ServiceReference holds a reference to Service.legacy.k8s.io +message ServiceReference { + // `namespace` is the namespace of the service. + // Required + optional string namespace = 1; + + // `name` is the name of the service. + // Required + optional string name = 2; + + // `path` is an optional URL path which will be sent in any request to + // this service. + // +optional + optional string path = 3; +} + +// WebhookClientConfig contains the information to make a TLS +// connection with the webhook. It has the same field as admissionregistration.v1beta1.WebhookClientConfig. +message WebhookClientConfig { + // `url` gives the location of the webhook, in standard URL form + // (`scheme://host:port/path`). Exactly one of `url` or `service` + // must be specified. + // + // The `host` should not refer to a service running in the cluster; use + // the `service` field instead. The host might be resolved via external + // DNS in some apiservers (e.g., `kube-apiserver` cannot resolve + // in-cluster DNS as that would be a layering violation). `host` may + // also be an IP address. + // + // Please note that using `localhost` or `127.0.0.1` as a `host` is + // risky unless you take great care to run this webhook on all hosts + // which run an apiserver which might need to make calls to this + // webhook. Such installs are likely to be non-portable, i.e., not easy + // to turn up in a new cluster. + // + // The scheme must be "https"; the URL must begin with "https://". + // + // A path is optional, and if present may be any string permissible in + // a URL. You may use the path to pass an arbitrary string to the + // webhook, for example, a cluster identifier. + // + // Attempting to use a user or basic auth e.g. "user:password@" is not + // allowed. Fragments ("#...") and query parameters ("?...") are not + // allowed, either. + // + // +optional + optional string url = 3; + + // `service` is a reference to the service for this webhook. Either + // `service` or `url` must be specified. + // + // If the webhook is running within the cluster, then you should use `service`. + // + // Port 443 will be used if it is open, otherwise it is an error. + // + // +optional + optional ServiceReference service = 1; + + // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // If unspecified, system trust roots on the apiserver are used. + // +optional + optional bytes caBundle = 2; +} + diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/register.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/register.go index 77f849975f878..97bc5431ccf69 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/register.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/register.go @@ -48,6 +48,7 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &CustomResourceDefinition{}, &CustomResourceDefinitionList{}, + &ConversionReview{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go index cab705d92715f..e99d9e49b52dd 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go @@ -18,6 +18,18 @@ package v1beta1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" +) + +// ConversionStrategyType describes different conversion types. +type ConversionStrategyType string + +const ( + // NoneConverter is a converter that only sets apiversion of the CR and leave everything else unchanged. + NoneConverter ConversionStrategyType = "None" + // WebhookConverter is a converter that calls to an external webhook to convert the CR. + WebhookConverter ConversionStrategyType = "Webhook" ) // CustomResourceDefinitionSpec describes how a user wants their resource to appear @@ -35,9 +47,13 @@ type CustomResourceDefinitionSpec struct { // Scope indicates whether this resource is cluster or namespace scoped. Default is namespaced Scope ResourceScope `json:"scope" protobuf:"bytes,4,opt,name=scope,casttype=ResourceScope"` // Validation describes the validation methods for CustomResources + // Optional, the global validation schema for all versions. + // Top-level and per-version schemas are mutually exclusive. // +optional Validation *CustomResourceValidation `json:"validation,omitempty" protobuf:"bytes,5,opt,name=validation"` - // Subresources describes the subresources for CustomResources + // Subresources describes the subresources for CustomResource + // Optional, the global subresources for all versions. + // Top-level and per-version subresources are mutually exclusive. // +optional Subresources *CustomResourceSubresources `json:"subresources,omitempty" protobuf:"bytes,6,opt,name=subresources"` // Versions is the list of all supported versions for this resource. @@ -54,10 +70,93 @@ type CustomResourceDefinitionSpec struct { // +optional Versions []CustomResourceDefinitionVersion `json:"versions,omitempty" protobuf:"bytes,7,rep,name=versions"` // AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column. + // Optional, the global columns for all versions. + // Top-level and per-version columns are mutually exclusive. // +optional AdditionalPrinterColumns []CustomResourceColumnDefinition `json:"additionalPrinterColumns,omitempty" protobuf:"bytes,8,rep,name=additionalPrinterColumns"` + + // `conversion` defines conversion settings for the CRD. + // +optional + Conversion *CustomResourceConversion `json:"conversion,omitempty" protobuf:"bytes,9,opt,name=conversion"` +} + +// CustomResourceConversion describes how to convert different versions of a CR. +type CustomResourceConversion struct { + // `strategy` specifies the conversion strategy. Allowed values are: + // - `None`: The converter only change the apiVersion and would not touch any other field in the CR. + // - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option. + Strategy ConversionStrategyType `json:"strategy" protobuf:"bytes,1,name=strategy"` + + // `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`. This field is + // alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // +optional + WebhookClientConfig *WebhookClientConfig `json:"webhookClientConfig,omitempty" protobuf:"bytes,2,name=webhookClientConfig"` +} + +// WebhookClientConfig contains the information to make a TLS +// connection with the webhook. It has the same field as admissionregistration.v1beta1.WebhookClientConfig. +type WebhookClientConfig struct { + // `url` gives the location of the webhook, in standard URL form + // (`scheme://host:port/path`). Exactly one of `url` or `service` + // must be specified. + // + // The `host` should not refer to a service running in the cluster; use + // the `service` field instead. The host might be resolved via external + // DNS in some apiservers (e.g., `kube-apiserver` cannot resolve + // in-cluster DNS as that would be a layering violation). `host` may + // also be an IP address. + // + // Please note that using `localhost` or `127.0.0.1` as a `host` is + // risky unless you take great care to run this webhook on all hosts + // which run an apiserver which might need to make calls to this + // webhook. Such installs are likely to be non-portable, i.e., not easy + // to turn up in a new cluster. + // + // The scheme must be "https"; the URL must begin with "https://". + // + // A path is optional, and if present may be any string permissible in + // a URL. You may use the path to pass an arbitrary string to the + // webhook, for example, a cluster identifier. + // + // Attempting to use a user or basic auth e.g. "user:password@" is not + // allowed. Fragments ("#...") and query parameters ("?...") are not + // allowed, either. + // + // +optional + URL *string `json:"url,omitempty" protobuf:"bytes,3,opt,name=url"` + + // `service` is a reference to the service for this webhook. Either + // `service` or `url` must be specified. + // + // If the webhook is running within the cluster, then you should use `service`. + // + // Port 443 will be used if it is open, otherwise it is an error. + // + // +optional + Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,1,opt,name=service"` + + // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // If unspecified, system trust roots on the apiserver are used. + // +optional + CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"` +} + +// ServiceReference holds a reference to Service.legacy.k8s.io +type ServiceReference struct { + // `namespace` is the namespace of the service. + // Required + Namespace string `json:"namespace" protobuf:"bytes,1,opt,name=namespace"` + // `name` is the name of the service. + // Required + Name string `json:"name" protobuf:"bytes,2,opt,name=name"` + + // `path` is an optional URL path which will be sent in any request to + // this service. + // +optional + Path *string `json:"path,omitempty" protobuf:"bytes,3,opt,name=path"` } +// CustomResourceDefinitionVersion describes a version for CRD. type CustomResourceDefinitionVersion struct { // Name is the version name, e.g. “v1”, “v2beta1”, etc. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` @@ -66,6 +165,27 @@ type CustomResourceDefinitionVersion struct { // Storage flags the version as storage version. There must be exactly one // flagged as storage version. Storage bool `json:"storage" protobuf:"varint,3,opt,name=storage"` + // Schema describes the schema for CustomResource used in validation, pruning, and defaulting. + // Top-level and per-version schemas are mutually exclusive. + // Per-version schemas must not all be set to identical values (top-level validation schema should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // +optional + Schema *CustomResourceValidation `json:"schema,omitempty" protobuf:"bytes,4,opt,name=schema"` + // Subresources describes the subresources for CustomResource + // Top-level and per-version subresources are mutually exclusive. + // Per-version subresources must not all be set to identical values (top-level subresources should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // +optional + Subresources *CustomResourceSubresources `json:"subresources,omitempty" protobuf:"bytes,5,opt,name=subresources"` + // AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column. + // Top-level and per-version columns are mutually exclusive. + // Per-version columns must not all be set to identical values (top-level columns should be used instead) + // This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature. + // NOTE: CRDs created prior to 1.13 populated the top-level additionalPrinterColumns field by default. To apply an + // update that changes to per-version additionalPrinterColumns, the top-level additionalPrinterColumns field must + // be explicitly set to null + // +optional + AdditionalPrinterColumns []CustomResourceColumnDefinition `json:"additionalPrinterColumns,omitempty" protobuf:"bytes,6,rep,name=additionalPrinterColumns"` } // CustomResourceColumnDefinition specifies a column for server side printing. @@ -263,3 +383,46 @@ type CustomResourceSubresourceScale struct { // +optional LabelSelectorPath *string `json:"labelSelectorPath,omitempty" protobuf:"bytes,3,opt,name=labelSelectorPath"` } + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ConversionReview describes a conversion request/response. +type ConversionReview struct { + metav1.TypeMeta `json:",inline"` + // `request` describes the attributes for the conversion request. + // +optional + Request *ConversionRequest `json:"request,omitempty" protobuf:"bytes,1,opt,name=request"` + // `response` describes the attributes for the conversion response. + // +optional + Response *ConversionResponse `json:"response,omitempty" protobuf:"bytes,2,opt,name=response"` +} + +// ConversionRequest describes the conversion request parameters. +type ConversionRequest struct { + // `uid` is an identifier for the individual request/response. It allows us to distinguish instances of requests which are + // otherwise identical (parallel requests, requests when earlier requests did not modify etc) + // The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. + // It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + UID types.UID `json:"uid" protobuf:"bytes,1,name=uid"` + // `desiredAPIVersion` is the version to convert given objects to. e.g. "myapi.example.com/v1" + DesiredAPIVersion string `json:"desiredAPIVersion" protobuf:"bytes,2,name=desiredAPIVersion"` + // `objects` is the list of CR objects to be converted. + Objects []runtime.RawExtension `json:"objects" protobuf:"bytes,3,rep,name=objects"` +} + +// ConversionResponse describes a conversion response. +type ConversionResponse struct { + // `uid` is an identifier for the individual request/response. + // This should be copied over from the corresponding AdmissionRequest. + UID types.UID `json:"uid" protobuf:"bytes,1,name=uid"` + // `convertedObjects` is the list of converted version of `request.objects` if the `result` is successful otherwise empty. + // The webhook is expected to set apiVersion of these objects to the ConversionRequest.desiredAPIVersion. The list + // must also has the same size as input list with the same objects in the same order(i.e. equal UIDs and object meta) + ConvertedObjects []runtime.RawExtension `json:"convertedObjects" protobuf:"bytes,2,rep,name=convertedObjects"` + // `result` contains the result of conversion with extra details if the conversion failed. `result.status` determines if + // the conversion failed or succeeded. The `result.status` field is required and represent the success or failure of the + // conversion. A successful conversion must set `result.status` to `Success`. A failed conversion must set + // `result.status` to `Failure` and provide more details in `result.message` and return http status 200. The `result.message` + // will be used to construct an error message for the end user. + Result metav1.Status `json:"result" protobuf:"bytes,3,name=result"` +} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go index 32fe1c8af92c9..cab8019b45888 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go @@ -45,6 +45,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*CustomResourceConversion)(nil), (*apiextensions.CustomResourceConversion)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(a.(*CustomResourceConversion), b.(*apiextensions.CustomResourceConversion), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*apiextensions.CustomResourceConversion)(nil), (*CustomResourceConversion)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(a.(*apiextensions.CustomResourceConversion), b.(*CustomResourceConversion), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*CustomResourceDefinition)(nil), (*apiextensions.CustomResourceDefinition)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_CustomResourceDefinition_To_apiextensions_CustomResourceDefinition(a.(*CustomResourceDefinition), b.(*apiextensions.CustomResourceDefinition), scope) }); err != nil { @@ -215,6 +225,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*ServiceReference)(nil), (*apiextensions.ServiceReference)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ServiceReference_To_apiextensions_ServiceReference(a.(*ServiceReference), b.(*apiextensions.ServiceReference), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*apiextensions.ServiceReference)(nil), (*ServiceReference)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(a.(*apiextensions.ServiceReference), b.(*ServiceReference), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*WebhookClientConfig)(nil), (*apiextensions.WebhookClientConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig(a.(*WebhookClientConfig), b.(*apiextensions.WebhookClientConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*apiextensions.WebhookClientConfig)(nil), (*WebhookClientConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig(a.(*apiextensions.WebhookClientConfig), b.(*WebhookClientConfig), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*apiextensions.JSONSchemaProps)(nil), (*JSONSchemaProps)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_apiextensions_JSONSchemaProps_To_v1beta1_JSONSchemaProps(a.(*apiextensions.JSONSchemaProps), b.(*JSONSchemaProps), scope) }); err != nil { @@ -263,6 +293,28 @@ func Convert_apiextensions_CustomResourceColumnDefinition_To_v1beta1_CustomResou return autoConvert_apiextensions_CustomResourceColumnDefinition_To_v1beta1_CustomResourceColumnDefinition(in, out, s) } +func autoConvert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(in *CustomResourceConversion, out *apiextensions.CustomResourceConversion, s conversion.Scope) error { + out.Strategy = apiextensions.ConversionStrategyType(in.Strategy) + out.WebhookClientConfig = (*apiextensions.WebhookClientConfig)(unsafe.Pointer(in.WebhookClientConfig)) + return nil +} + +// Convert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion is an autogenerated conversion function. +func Convert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(in *CustomResourceConversion, out *apiextensions.CustomResourceConversion, s conversion.Scope) error { + return autoConvert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(in, out, s) +} + +func autoConvert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(in *apiextensions.CustomResourceConversion, out *CustomResourceConversion, s conversion.Scope) error { + out.Strategy = ConversionStrategyType(in.Strategy) + out.WebhookClientConfig = (*WebhookClientConfig)(unsafe.Pointer(in.WebhookClientConfig)) + return nil +} + +// Convert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion is an autogenerated conversion function. +func Convert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(in *apiextensions.CustomResourceConversion, out *CustomResourceConversion, s conversion.Scope) error { + return autoConvert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(in, out, s) +} + func autoConvert_v1beta1_CustomResourceDefinition_To_apiextensions_CustomResourceDefinition(in *CustomResourceDefinition, out *apiextensions.CustomResourceDefinition, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta if err := Convert_v1beta1_CustomResourceDefinitionSpec_To_apiextensions_CustomResourceDefinitionSpec(&in.Spec, &out.Spec, s); err != nil { @@ -412,8 +464,19 @@ func autoConvert_v1beta1_CustomResourceDefinitionSpec_To_apiextensions_CustomRes out.Validation = nil } out.Subresources = (*apiextensions.CustomResourceSubresources)(unsafe.Pointer(in.Subresources)) - out.Versions = *(*[]apiextensions.CustomResourceDefinitionVersion)(unsafe.Pointer(&in.Versions)) + if in.Versions != nil { + in, out := &in.Versions, &out.Versions + *out = make([]apiextensions.CustomResourceDefinitionVersion, len(*in)) + for i := range *in { + if err := Convert_v1beta1_CustomResourceDefinitionVersion_To_apiextensions_CustomResourceDefinitionVersion(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Versions = nil + } out.AdditionalPrinterColumns = *(*[]apiextensions.CustomResourceColumnDefinition)(unsafe.Pointer(&in.AdditionalPrinterColumns)) + out.Conversion = (*apiextensions.CustomResourceConversion)(unsafe.Pointer(in.Conversion)) return nil } @@ -439,8 +502,19 @@ func autoConvert_apiextensions_CustomResourceDefinitionSpec_To_v1beta1_CustomRes out.Validation = nil } out.Subresources = (*CustomResourceSubresources)(unsafe.Pointer(in.Subresources)) - out.Versions = *(*[]CustomResourceDefinitionVersion)(unsafe.Pointer(&in.Versions)) + if in.Versions != nil { + in, out := &in.Versions, &out.Versions + *out = make([]CustomResourceDefinitionVersion, len(*in)) + for i := range *in { + if err := Convert_apiextensions_CustomResourceDefinitionVersion_To_v1beta1_CustomResourceDefinitionVersion(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Versions = nil + } out.AdditionalPrinterColumns = *(*[]CustomResourceColumnDefinition)(unsafe.Pointer(&in.AdditionalPrinterColumns)) + out.Conversion = (*CustomResourceConversion)(unsafe.Pointer(in.Conversion)) return nil } @@ -481,6 +555,17 @@ func autoConvert_v1beta1_CustomResourceDefinitionVersion_To_apiextensions_Custom out.Name = in.Name out.Served = in.Served out.Storage = in.Storage + if in.Schema != nil { + in, out := &in.Schema, &out.Schema + *out = new(apiextensions.CustomResourceValidation) + if err := Convert_v1beta1_CustomResourceValidation_To_apiextensions_CustomResourceValidation(*in, *out, s); err != nil { + return err + } + } else { + out.Schema = nil + } + out.Subresources = (*apiextensions.CustomResourceSubresources)(unsafe.Pointer(in.Subresources)) + out.AdditionalPrinterColumns = *(*[]apiextensions.CustomResourceColumnDefinition)(unsafe.Pointer(&in.AdditionalPrinterColumns)) return nil } @@ -493,6 +578,17 @@ func autoConvert_apiextensions_CustomResourceDefinitionVersion_To_v1beta1_Custom out.Name = in.Name out.Served = in.Served out.Storage = in.Storage + if in.Schema != nil { + in, out := &in.Schema, &out.Schema + *out = new(CustomResourceValidation) + if err := Convert_apiextensions_CustomResourceValidation_To_v1beta1_CustomResourceValidation(*in, *out, s); err != nil { + return err + } + } else { + out.Schema = nil + } + out.Subresources = (*CustomResourceSubresources)(unsafe.Pointer(in.Subresources)) + out.AdditionalPrinterColumns = *(*[]CustomResourceColumnDefinition)(unsafe.Pointer(&in.AdditionalPrinterColumns)) return nil } @@ -1123,3 +1219,51 @@ func autoConvert_apiextensions_JSONSchemaPropsOrStringArray_To_v1beta1_JSONSchem func Convert_apiextensions_JSONSchemaPropsOrStringArray_To_v1beta1_JSONSchemaPropsOrStringArray(in *apiextensions.JSONSchemaPropsOrStringArray, out *JSONSchemaPropsOrStringArray, s conversion.Scope) error { return autoConvert_apiextensions_JSONSchemaPropsOrStringArray_To_v1beta1_JSONSchemaPropsOrStringArray(in, out, s) } + +func autoConvert_v1beta1_ServiceReference_To_apiextensions_ServiceReference(in *ServiceReference, out *apiextensions.ServiceReference, s conversion.Scope) error { + out.Namespace = in.Namespace + out.Name = in.Name + out.Path = (*string)(unsafe.Pointer(in.Path)) + return nil +} + +// Convert_v1beta1_ServiceReference_To_apiextensions_ServiceReference is an autogenerated conversion function. +func Convert_v1beta1_ServiceReference_To_apiextensions_ServiceReference(in *ServiceReference, out *apiextensions.ServiceReference, s conversion.Scope) error { + return autoConvert_v1beta1_ServiceReference_To_apiextensions_ServiceReference(in, out, s) +} + +func autoConvert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(in *apiextensions.ServiceReference, out *ServiceReference, s conversion.Scope) error { + out.Namespace = in.Namespace + out.Name = in.Name + out.Path = (*string)(unsafe.Pointer(in.Path)) + return nil +} + +// Convert_apiextensions_ServiceReference_To_v1beta1_ServiceReference is an autogenerated conversion function. +func Convert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(in *apiextensions.ServiceReference, out *ServiceReference, s conversion.Scope) error { + return autoConvert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(in, out, s) +} + +func autoConvert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig(in *WebhookClientConfig, out *apiextensions.WebhookClientConfig, s conversion.Scope) error { + out.URL = (*string)(unsafe.Pointer(in.URL)) + out.Service = (*apiextensions.ServiceReference)(unsafe.Pointer(in.Service)) + out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) + return nil +} + +// Convert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig is an autogenerated conversion function. +func Convert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig(in *WebhookClientConfig, out *apiextensions.WebhookClientConfig, s conversion.Scope) error { + return autoConvert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig(in, out, s) +} + +func autoConvert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig(in *apiextensions.WebhookClientConfig, out *WebhookClientConfig, s conversion.Scope) error { + out.URL = (*string)(unsafe.Pointer(in.URL)) + out.Service = (*ServiceReference)(unsafe.Pointer(in.Service)) + out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) + return nil +} + +// Convert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig is an autogenerated conversion function. +func Convert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig(in *apiextensions.WebhookClientConfig, out *WebhookClientConfig, s conversion.Scope) error { + return autoConvert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig(in, out, s) +} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go index 5e14efbc84c0a..8dd7a87bfcfbe 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go @@ -24,6 +24,88 @@ import ( 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 *ConversionRequest) DeepCopyInto(out *ConversionRequest) { + *out = *in + if in.Objects != nil { + in, out := &in.Objects, &out.Objects + *out = make([]runtime.RawExtension, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionRequest. +func (in *ConversionRequest) DeepCopy() *ConversionRequest { + if in == nil { + return nil + } + out := new(ConversionRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConversionResponse) DeepCopyInto(out *ConversionResponse) { + *out = *in + if in.ConvertedObjects != nil { + in, out := &in.ConvertedObjects, &out.ConvertedObjects + *out = make([]runtime.RawExtension, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Result.DeepCopyInto(&out.Result) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionResponse. +func (in *ConversionResponse) DeepCopy() *ConversionResponse { + if in == nil { + return nil + } + out := new(ConversionResponse) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConversionReview) DeepCopyInto(out *ConversionReview) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.Request != nil { + in, out := &in.Request, &out.Request + *out = new(ConversionRequest) + (*in).DeepCopyInto(*out) + } + if in.Response != nil { + in, out := &in.Response, &out.Response + *out = new(ConversionResponse) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionReview. +func (in *ConversionReview) DeepCopy() *ConversionReview { + if in == nil { + return nil + } + out := new(ConversionReview) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ConversionReview) 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 *CustomResourceColumnDefinition) DeepCopyInto(out *CustomResourceColumnDefinition) { *out = *in @@ -40,6 +122,27 @@ func (in *CustomResourceColumnDefinition) DeepCopy() *CustomResourceColumnDefini return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomResourceConversion) DeepCopyInto(out *CustomResourceConversion) { + *out = *in + if in.WebhookClientConfig != nil { + in, out := &in.WebhookClientConfig, &out.WebhookClientConfig + *out = new(WebhookClientConfig) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceConversion. +func (in *CustomResourceConversion) DeepCopy() *CustomResourceConversion { + if in == nil { + return nil + } + out := new(CustomResourceConversion) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomResourceDefinition) DeepCopyInto(out *CustomResourceDefinition) { *out = *in @@ -161,13 +264,20 @@ func (in *CustomResourceDefinitionSpec) DeepCopyInto(out *CustomResourceDefiniti if in.Versions != nil { in, out := &in.Versions, &out.Versions *out = make([]CustomResourceDefinitionVersion, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.AdditionalPrinterColumns != nil { in, out := &in.AdditionalPrinterColumns, &out.AdditionalPrinterColumns *out = make([]CustomResourceColumnDefinition, len(*in)) copy(*out, *in) } + if in.Conversion != nil { + in, out := &in.Conversion, &out.Conversion + *out = new(CustomResourceConversion) + (*in).DeepCopyInto(*out) + } return } @@ -213,6 +323,21 @@ func (in *CustomResourceDefinitionStatus) DeepCopy() *CustomResourceDefinitionSt // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomResourceDefinitionVersion) DeepCopyInto(out *CustomResourceDefinitionVersion) { *out = *in + if in.Schema != nil { + in, out := &in.Schema, &out.Schema + *out = new(CustomResourceValidation) + (*in).DeepCopyInto(*out) + } + if in.Subresources != nil { + in, out := &in.Subresources, &out.Subresources + *out = new(CustomResourceSubresources) + (*in).DeepCopyInto(*out) + } + if in.AdditionalPrinterColumns != nil { + in, out := &in.AdditionalPrinterColumns, &out.AdditionalPrinterColumns + *out = make([]CustomResourceColumnDefinition, len(*in)) + copy(*out, *in) + } return } @@ -468,3 +593,55 @@ func (in *JSONSchemaPropsOrStringArray) DeepCopy() *JSONSchemaPropsOrStringArray in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceReference) DeepCopyInto(out *ServiceReference) { + *out = *in + if in.Path != nil { + in, out := &in.Path, &out.Path + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceReference. +func (in *ServiceReference) DeepCopy() *ServiceReference { + if in == nil { + return nil + } + out := new(ServiceReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WebhookClientConfig) DeepCopyInto(out *WebhookClientConfig) { + *out = *in + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(string) + **out = **in + } + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = new(ServiceReference) + (*in).DeepCopyInto(*out) + } + if in.CABundle != nil { + in, out := &in.CABundle, &out.CABundle + *out = make([]byte, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookClientConfig. +func (in *WebhookClientConfig) DeepCopy() *WebhookClientConfig { + if in == nil { + return nil + } + out := new(WebhookClientConfig) + in.DeepCopyInto(out) + return out +} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/BUILD b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/BUILD index 7d57434dcf740..1c80d0c5a0d98 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/BUILD +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/BUILD @@ -15,11 +15,13 @@ go_library( "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/validation:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go index 0568bc18102ff..4f16ccce87858 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go @@ -21,11 +21,13 @@ import ( "reflect" "strings" + apiequality "k8s.io/apimachinery/pkg/api/equality" genericvalidation "k8s.io/apimachinery/pkg/api/validation" "k8s.io/apimachinery/pkg/util/sets" validationutil "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/apiserver/pkg/util/webhook" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation" @@ -98,6 +100,17 @@ func ValidateUpdateCustomResourceDefinitionStatus(obj, oldObj *apiextensions.Cus return allErrs } +// ValidateCustomResourceDefinitionVersion statically validates. +func ValidateCustomResourceDefinitionVersion(version *apiextensions.CustomResourceDefinitionVersion, fldPath *field.Path, statusEnabled bool) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, ValidateCustomResourceDefinitionValidation(version.Schema, statusEnabled, fldPath.Child("schema"))...) + allErrs = append(allErrs, ValidateCustomResourceDefinitionSubresources(version.Subresources, fldPath.Child("subresources"))...) + for i := range version.AdditionalPrinterColumns { + allErrs = append(allErrs, ValidateCustomResourceColumnDefinition(&version.AdditionalPrinterColumns[i], fldPath.Child("additionalPrinterColumns").Index(i))...) + } + return allErrs +} + // ValidateCustomResourceDefinitionSpec statically validates func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefinitionSpec, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} @@ -110,13 +123,7 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi allErrs = append(allErrs, field.Invalid(fldPath.Child("group"), spec.Group, "should be a domain with at least one dot")) } - switch spec.Scope { - case "": - allErrs = append(allErrs, field.Required(fldPath.Child("scope"), "")) - case apiextensions.ClusterScoped, apiextensions.NamespaceScoped: - default: - allErrs = append(allErrs, field.NotSupported(fldPath.Child("scope"), spec.Scope, []string{string(apiextensions.ClusterScoped), string(apiextensions.NamespaceScoped)})) - } + allErrs = append(allErrs, validateEnumStrings(fldPath.Child("scope"), string(spec.Scope), []string{string(apiextensions.ClusterScoped), string(apiextensions.NamespaceScoped)}, true)...) storageFlagCount := 0 versionsMap := map[string]bool{} @@ -133,7 +140,32 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi if errs := validationutil.IsDNS1035Label(version.Name); len(errs) > 0 { allErrs = append(allErrs, field.Invalid(fldPath.Child("versions").Index(i).Child("name"), spec.Versions[i].Name, strings.Join(errs, ","))) } + subresources := getSubresourcesForVersion(spec, version.Name) + allErrs = append(allErrs, ValidateCustomResourceDefinitionVersion(&version, fldPath.Child("versions").Index(i), hasStatusEnabled(subresources))...) + } + + // The top-level and per-version fields are mutual exclusive + if spec.Validation != nil && hasPerVersionSchema(spec.Versions) { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("validation"), "top-level and per-version schemas are mutually exclusive")) + } + if spec.Subresources != nil && hasPerVersionSubresources(spec.Versions) { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("subresources"), "top-level and per-version subresources are mutually exclusive")) + } + if len(spec.AdditionalPrinterColumns) > 0 && hasPerVersionColumns(spec.Versions) { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("additionalPrinterColumns"), "top-level and per-version additionalPrinterColumns are mutually exclusive")) + } + + // Per-version fields may not all be set to identical values (top-level field should be used instead) + if hasIdenticalPerVersionSchema(spec.Versions) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("versions"), spec.Versions, "per-version schemas may not all be set to identical values (top-level validation should be used instead)")) } + if hasIdenticalPerVersionSubresources(spec.Versions) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("versions"), spec.Versions, "per-version subresources may not all be set to identical values (top-level subresources should be used instead)")) + } + if hasIdenticalPerVersionColumns(spec.Versions) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("versions"), spec.Versions, "per-version additionalPrinterColumns may not all be set to identical values (top-level additionalPrinterColumns should be used instead)")) + } + if !uniqueNames { allErrs = append(allErrs, field.Invalid(fldPath.Child("versions"), spec.Versions, "must contain unique version names")) } @@ -166,11 +198,7 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi allErrs = append(allErrs, ValidateCustomResourceDefinitionNames(&spec.Names, fldPath.Child("names"))...) if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) { - statusEnabled := false - if spec.Subresources != nil && spec.Subresources.Status != nil { - statusEnabled = true - } - allErrs = append(allErrs, ValidateCustomResourceDefinitionValidation(spec.Validation, statusEnabled, fldPath.Child("validation"))...) + allErrs = append(allErrs, ValidateCustomResourceDefinitionValidation(spec.Validation, hasAnyStatusEnabled(spec), fldPath.Child("validation"))...) } else if spec.Validation != nil { allErrs = append(allErrs, field.Forbidden(fldPath.Child("validation"), "disabled by feature-gate CustomResourceValidation")) } @@ -182,11 +210,59 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi } for i := range spec.AdditionalPrinterColumns { - if errs := ValidateCustomResourceColumnDefinition(&spec.AdditionalPrinterColumns[i], fldPath.Child("columns").Index(i)); len(errs) > 0 { + if errs := ValidateCustomResourceColumnDefinition(&spec.AdditionalPrinterColumns[i], fldPath.Child("additionalPrinterColumns").Index(i)); len(errs) > 0 { allErrs = append(allErrs, errs...) } } + allErrs = append(allErrs, ValidateCustomResourceConversion(spec.Conversion, fldPath.Child("conversion"))...) + + return allErrs +} + +func validateEnumStrings(fldPath *field.Path, value string, accepted []string, required bool) field.ErrorList { + if value == "" { + if required { + return field.ErrorList{field.Required(fldPath, "")} + } + return field.ErrorList{} + } + for _, a := range accepted { + if a == value { + return field.ErrorList{} + } + } + return field.ErrorList{field.NotSupported(fldPath, value, accepted)} +} + +// ValidateCustomResourceConversion statically validates +func ValidateCustomResourceConversion(conversion *apiextensions.CustomResourceConversion, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + if conversion == nil { + return allErrs + } + allErrs = append(allErrs, validateEnumStrings(fldPath.Child("strategy"), string(conversion.Strategy), []string{string(apiextensions.NoneConverter), string(apiextensions.WebhookConverter)}, true)...) + if conversion.Strategy == apiextensions.WebhookConverter { + if conversion.WebhookClientConfig == nil { + if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) { + allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "required when strategy is set to Webhook")) + } else { + allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "required when strategy is set to Webhook, but not allowed because the CustomResourceWebhookConversion feature is disabled")) + } + } else { + cc := conversion.WebhookClientConfig + switch { + case (cc.URL == nil) == (cc.Service == nil): + allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "exactly one of url or service is required")) + case cc.URL != nil: + allErrs = append(allErrs, webhook.ValidateWebhookURL(fldPath.Child("webhookClientConfig").Child("url"), *cc.URL, true)...) + case cc.Service != nil: + allErrs = append(allErrs, webhook.ValidateWebhookService(fldPath.Child("webhookClientConfig").Child("service"), cc.Service.Name, cc.Service.Namespace, cc.Service.Path)...) + } + } + } else if conversion.WebhookClientConfig != nil { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("webhookClientConfig"), "should not be set when strategy is not set to Webhook")) + } return allErrs } @@ -207,6 +283,118 @@ func ValidateCustomResourceDefinitionSpecUpdate(spec, oldSpec *apiextensions.Cus return allErrs } +// getSubresourcesForVersion returns the subresources for given version in given CRD spec. +// NOTE That this function assumes version always exist since it's used by the validation process +// that iterates through the existing versions. +func getSubresourcesForVersion(crd *apiextensions.CustomResourceDefinitionSpec, version string) *apiextensions.CustomResourceSubresources { + if !hasPerVersionSubresources(crd.Versions) { + return crd.Subresources + } + for _, v := range crd.Versions { + if version == v.Name { + return v.Subresources + } + } + return nil +} + +// hasAnyStatusEnabled returns true if given CRD spec has at least one Status Subresource set +// among the top-level and per-version Subresources. +func hasAnyStatusEnabled(crd *apiextensions.CustomResourceDefinitionSpec) bool { + if hasStatusEnabled(crd.Subresources) { + return true + } + for _, v := range crd.Versions { + if hasStatusEnabled(v.Subresources) { + return true + } + } + return false +} + +// hasStatusEnabled returns true if given CRD Subresources has non-nil Status set. +func hasStatusEnabled(subresources *apiextensions.CustomResourceSubresources) bool { + if subresources != nil && subresources.Status != nil { + return true + } + return false +} + +// hasPerVersionSchema returns true if a CRD uses per-version schema. +func hasPerVersionSchema(versions []apiextensions.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if v.Schema != nil { + return true + } + } + return false +} + +// hasPerVersionSubresources returns true if a CRD uses per-version subresources. +func hasPerVersionSubresources(versions []apiextensions.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if v.Subresources != nil { + return true + } + } + return false +} + +// hasPerVersionColumns returns true if a CRD uses per-version columns. +func hasPerVersionColumns(versions []apiextensions.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if len(v.AdditionalPrinterColumns) > 0 { + return true + } + } + return false +} + +// hasIdenticalPerVersionSchema returns true if a CRD sets identical non-nil values +// to all per-version schemas +func hasIdenticalPerVersionSchema(versions []apiextensions.CustomResourceDefinitionVersion) bool { + if len(versions) == 0 { + return false + } + value := versions[0].Schema + for _, v := range versions { + if v.Schema == nil || !apiequality.Semantic.DeepEqual(v.Schema, value) { + return false + } + } + return true +} + +// hasIdenticalPerVersionSubresources returns true if a CRD sets identical non-nil values +// to all per-version subresources +func hasIdenticalPerVersionSubresources(versions []apiextensions.CustomResourceDefinitionVersion) bool { + if len(versions) == 0 { + return false + } + value := versions[0].Subresources + for _, v := range versions { + if v.Subresources == nil || !apiequality.Semantic.DeepEqual(v.Subresources, value) { + return false + } + } + return true +} + +// hasIdenticalPerVersionColumns returns true if a CRD sets identical non-nil values +// to all per-version columns +func hasIdenticalPerVersionColumns(versions []apiextensions.CustomResourceDefinitionVersion) bool { + if len(versions) == 0 { + return false + } + value := versions[0].AdditionalPrinterColumns + for _, v := range versions { + if len(v.AdditionalPrinterColumns) == 0 || !apiequality.Semantic.DeepEqual(v.AdditionalPrinterColumns, value) { + return false + } + } + return true +} + // ValidateCustomResourceDefinitionStatus statically validates func ValidateCustomResourceDefinitionStatus(status *apiextensions.CustomResourceDefinitionStatus, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go index 794142b7072df..692aa8b0c0a1e 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go @@ -49,6 +49,8 @@ func (v validationMatch) matches(err *field.Error) bool { return err.Type == v.errorType && err.Field == v.path.String() } +func strPtr(s string) *string { return &s } + func TestValidateCustomResourceDefinition(t *testing.T) { singleVersionList := []apiextensions.CustomResourceDefinitionVersion{ { @@ -62,6 +64,205 @@ func TestValidateCustomResourceDefinition(t *testing.T) { resource *apiextensions.CustomResourceDefinition errors []validationMatch }{ + { + name: "webhookconfig: blank URL", + resource: &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: "group.com", + Scope: apiextensions.ResourceScope("Cluster"), + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: "plural", + Singular: "singular", + Kind: "Plural", + ListKind: "PluralList", + }, + Versions: []apiextensions.CustomResourceDefinitionVersion{ + { + Name: "version", + Served: true, + Storage: true, + }, + { + Name: "version2", + Served: true, + Storage: false, + }, + }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("Webhook"), + WebhookClientConfig: &apiextensions.WebhookClientConfig{ + URL: strPtr("https://example.com/webhook"), + Service: &apiextensions.ServiceReference{ + Name: "n", + Namespace: "ns", + }, + }, + }, + }, + Status: apiextensions.CustomResourceDefinitionStatus{ + StoredVersions: []string{"version"}, + }, + }, + errors: []validationMatch{ + required("spec", "conversion", "webhookClientConfig"), + }, + }, + { + name: "webhookconfig: both service and URL provided", + resource: &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: "group.com", + Scope: apiextensions.ResourceScope("Cluster"), + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: "plural", + Singular: "singular", + Kind: "Plural", + ListKind: "PluralList", + }, + Versions: []apiextensions.CustomResourceDefinitionVersion{ + { + Name: "version", + Served: true, + Storage: true, + }, + { + Name: "version2", + Served: true, + Storage: false, + }, + }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("Webhook"), + WebhookClientConfig: &apiextensions.WebhookClientConfig{ + URL: strPtr(""), + }, + }, + }, + Status: apiextensions.CustomResourceDefinitionStatus{ + StoredVersions: []string{"version"}, + }, + }, + errors: []validationMatch{ + invalid("spec", "conversion", "webhookClientConfig", "url"), + invalid("spec", "conversion", "webhookClientConfig", "url"), + }, + }, + { + name: "webhookconfig_should_not_be_set", + resource: &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: "group.com", + Scope: apiextensions.ResourceScope("Cluster"), + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: "plural", + Singular: "singular", + Kind: "Plural", + ListKind: "PluralList", + }, + Versions: []apiextensions.CustomResourceDefinitionVersion{ + { + Name: "version", + Served: true, + Storage: true, + }, + { + Name: "version2", + Served: true, + Storage: false, + }, + }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("None"), + WebhookClientConfig: &apiextensions.WebhookClientConfig{ + URL: strPtr("https://example.com/webhook"), + }, + }, + }, + Status: apiextensions.CustomResourceDefinitionStatus{ + StoredVersions: []string{"version"}, + }, + }, + errors: []validationMatch{ + forbidden("spec", "conversion", "webhookClientConfig"), + }, + }, + { + name: "missing_webhookconfig", + resource: &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: "group.com", + Scope: apiextensions.ResourceScope("Cluster"), + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: "plural", + Singular: "singular", + Kind: "Plural", + ListKind: "PluralList", + }, + Versions: []apiextensions.CustomResourceDefinitionVersion{ + { + Name: "version", + Served: true, + Storage: true, + }, + { + Name: "version2", + Served: true, + Storage: false, + }, + }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("Webhook"), + }, + }, + Status: apiextensions.CustomResourceDefinitionStatus{ + StoredVersions: []string{"version"}, + }, + }, + errors: []validationMatch{ + required("spec", "conversion", "webhookClientConfig"), + }, + }, + { + name: "invalid_conversion_strategy", + resource: &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: "group.com", + Scope: apiextensions.ResourceScope("Cluster"), + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: "plural", + Singular: "singular", + Kind: "Plural", + ListKind: "PluralList", + }, + Versions: []apiextensions.CustomResourceDefinitionVersion{ + { + Name: "version", + Served: true, + Storage: true, + }, + { + Name: "version2", + Served: true, + Storage: false, + }, + }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("non_existing_conversion"), + }, + }, + Status: apiextensions.CustomResourceDefinitionStatus{ + StoredVersions: []string{"version"}, + }, + }, + errors: []validationMatch{ + unsupported("spec", "conversion", "strategy"), + }, + }, { name: "no_storage_version", resource: &apiextensions.CustomResourceDefinition{ @@ -87,6 +288,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Storage: false, }, }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("None"), + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, @@ -121,6 +325,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Storage: true, }, }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("None"), + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, @@ -156,6 +363,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Storage: true, }, }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("None"), + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, @@ -185,6 +395,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Storage: true, }, }, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("None"), + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{}, @@ -283,6 +496,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Group: "group.c(*&om", Version: "version", Versions: singleVersionList, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("None"), + }, Names: apiextensions.CustomResourceDefinitionNames{ Plural: "plural", Singular: "singular", @@ -316,7 +532,10 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Group: "group.com", Version: "version", Versions: singleVersionList, - Scope: apiextensions.NamespaceScoped, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("None"), + }, + Scope: apiextensions.NamespaceScoped, Names: apiextensions.CustomResourceDefinitionNames{ Plural: "plural", Singular: "singular", @@ -348,7 +567,10 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Group: "group.com", Version: "version", Versions: singleVersionList, - Scope: apiextensions.NamespaceScoped, + Conversion: &apiextensions.CustomResourceConversion{ + Strategy: apiextensions.ConversionStrategyType("None"), + }, + Scope: apiextensions.NamespaceScoped, Names: apiextensions.CustomResourceDefinitionNames{ Plural: "plural", Singular: "singular", @@ -372,6 +594,55 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, errors: []validationMatch{}, }, + { + name: "per-version fields may not all be set to identical values (top-level field should be used instead)", + resource: &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: "group.com", + Version: "version", + Versions: []apiextensions.CustomResourceDefinitionVersion{ + { + Name: "version", + Served: true, + Storage: true, + Schema: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: validValidationSchema, + }, + Subresources: &apiextensions.CustomResourceSubresources{}, + AdditionalPrinterColumns: []apiextensions.CustomResourceColumnDefinition{{Name: "Alpha", Type: "string", JSONPath: ".spec.alpha"}}, + }, + { + Name: "version2", + Served: true, + Storage: false, + Schema: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: validValidationSchema, + }, + Subresources: &apiextensions.CustomResourceSubresources{}, + AdditionalPrinterColumns: []apiextensions.CustomResourceColumnDefinition{{Name: "Alpha", Type: "string", JSONPath: ".spec.alpha"}}, + }, + }, + Scope: apiextensions.NamespaceScoped, + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: "plural", + Singular: "singular", + Kind: "Plural", + ListKind: "PluralList", + }, + }, + Status: apiextensions.CustomResourceDefinitionStatus{ + StoredVersions: []string{"version"}, + }, + }, + errors: []validationMatch{ + // Per-version schema/subresources/columns may not all be set to identical values. + // Note that the test will fail if we de-duplicate the expected errors below. + invalid("spec", "versions"), + invalid("spec", "versions"), + invalid("spec", "versions"), + }, + }, } for _, tc := range tests { @@ -781,6 +1052,87 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { immutable("spec", "names", "plural"), }, }, + { + name: "top-level and per-version fields are mutually exclusive", + old: &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: "plural.group.com", + ResourceVersion: "42", + }, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: "group.com", + Version: "version", + Versions: []apiextensions.CustomResourceDefinitionVersion{ + { + Name: "version", + Served: true, + Storage: true, + Subresources: &apiextensions.CustomResourceSubresources{}, + }, + { + Name: "version2", + Served: true, + Storage: false, + }, + }, + Scope: apiextensions.NamespaceScoped, + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: "plural", + Singular: "singular", + Kind: "Plural", + ListKind: "PluralList", + }, + }, + Status: apiextensions.CustomResourceDefinitionStatus{ + StoredVersions: []string{"version"}, + }, + }, + resource: &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: "plural.group.com", + ResourceVersion: "42", + }, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: "group.com", + Version: "version", + Versions: []apiextensions.CustomResourceDefinitionVersion{ + { + Name: "version", + Served: true, + Storage: true, + }, + { + Name: "version2", + Served: true, + Storage: false, + Schema: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: validValidationSchema, + }, + Subresources: &apiextensions.CustomResourceSubresources{}, + AdditionalPrinterColumns: []apiextensions.CustomResourceColumnDefinition{{Name: "Alpha", Type: "string", JSONPath: ".spec.alpha"}}, + }, + }, + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: validValidationSchema, + }, + Subresources: &apiextensions.CustomResourceSubresources{}, + Scope: apiextensions.NamespaceScoped, + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: "plural", + Singular: "singular", + Kind: "Plural", + ListKind: "PluralList", + }, + }, + Status: apiextensions.CustomResourceDefinitionStatus{ + StoredVersions: []string{"version"}, + }, + }, + errors: []validationMatch{ + forbidden("spec", "validation"), + forbidden("spec", "subresources"), + }, + }, } for _, tc := range tests { @@ -868,36 +1220,7 @@ func TestValidateCustomResourceDefinitionValidation(t *testing.T) { { name: "all allowed fields at the root of the schema with status", input: apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Description: "This is a description", - Type: "object", - Format: "date-time", - Title: "This is a title", - Maximum: float64Ptr(10), - ExclusiveMaximum: true, - Minimum: float64Ptr(5), - ExclusiveMinimum: true, - MaxLength: int64Ptr(10), - MinLength: int64Ptr(5), - Pattern: "^[a-z]$", - MaxItems: int64Ptr(10), - MinItems: int64Ptr(5), - MultipleOf: float64Ptr(3), - Required: []string{"spec", "status"}, - Items: &apiextensions.JSONSchemaPropsOrArray{ - Schema: &apiextensions.JSONSchemaProps{ - Description: "This is a schema nested under Items", - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "spec": {}, - "status": {}, - }, - ExternalDocs: &apiextensions.ExternalDocumentation{ - Description: "This is an external documentation description", - }, - Example: &example, - }, + OpenAPIV3Schema: validValidationSchema, }, statusEnabled: true, wantError: false, @@ -917,6 +1240,37 @@ func TestValidateCustomResourceDefinitionValidation(t *testing.T) { var example = apiextensions.JSON(`"This is an example"`) +var validValidationSchema = &apiextensions.JSONSchemaProps{ + Description: "This is a description", + Type: "object", + Format: "date-time", + Title: "This is a title", + Maximum: float64Ptr(10), + ExclusiveMaximum: true, + Minimum: float64Ptr(5), + ExclusiveMinimum: true, + MaxLength: int64Ptr(10), + MinLength: int64Ptr(5), + Pattern: "^[a-z]$", + MaxItems: int64Ptr(10), + MinItems: int64Ptr(5), + MultipleOf: float64Ptr(3), + Required: []string{"spec", "status"}, + Items: &apiextensions.JSONSchemaPropsOrArray{ + Schema: &apiextensions.JSONSchemaProps{ + Description: "This is a schema nested under Items", + }, + }, + Properties: map[string]apiextensions.JSONSchemaProps{ + "spec": {}, + "status": {}, + }, + ExternalDocs: &apiextensions.ExternalDocumentation{ + Description: "This is an external documentation description", + }, + Example: &example, +} + func float64Ptr(f float64) *float64 { return &f } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go index 50e7ee880e596..5a01307539d8d 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go @@ -40,6 +40,27 @@ func (in *CustomResourceColumnDefinition) DeepCopy() *CustomResourceColumnDefini return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomResourceConversion) DeepCopyInto(out *CustomResourceConversion) { + *out = *in + if in.WebhookClientConfig != nil { + in, out := &in.WebhookClientConfig, &out.WebhookClientConfig + *out = new(WebhookClientConfig) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceConversion. +func (in *CustomResourceConversion) DeepCopy() *CustomResourceConversion { + if in == nil { + return nil + } + out := new(CustomResourceConversion) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomResourceDefinition) DeepCopyInto(out *CustomResourceDefinition) { *out = *in @@ -161,13 +182,20 @@ func (in *CustomResourceDefinitionSpec) DeepCopyInto(out *CustomResourceDefiniti if in.Versions != nil { in, out := &in.Versions, &out.Versions *out = make([]CustomResourceDefinitionVersion, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.AdditionalPrinterColumns != nil { in, out := &in.AdditionalPrinterColumns, &out.AdditionalPrinterColumns *out = make([]CustomResourceColumnDefinition, len(*in)) copy(*out, *in) } + if in.Conversion != nil { + in, out := &in.Conversion, &out.Conversion + *out = new(CustomResourceConversion) + (*in).DeepCopyInto(*out) + } return } @@ -213,6 +241,21 @@ func (in *CustomResourceDefinitionStatus) DeepCopy() *CustomResourceDefinitionSt // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomResourceDefinitionVersion) DeepCopyInto(out *CustomResourceDefinitionVersion) { *out = *in + if in.Schema != nil { + in, out := &in.Schema, &out.Schema + *out = new(CustomResourceValidation) + (*in).DeepCopyInto(*out) + } + if in.Subresources != nil { + in, out := &in.Subresources, &out.Subresources + *out = new(CustomResourceSubresources) + (*in).DeepCopyInto(*out) + } + if in.AdditionalPrinterColumns != nil { + in, out := &in.AdditionalPrinterColumns, &out.AdditionalPrinterColumns + *out = make([]CustomResourceColumnDefinition, len(*in)) + copy(*out, *in) + } return } @@ -447,3 +490,55 @@ func (in *JSONSchemaPropsOrStringArray) DeepCopy() *JSONSchemaPropsOrStringArray in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceReference) DeepCopyInto(out *ServiceReference) { + *out = *in + if in.Path != nil { + in, out := &in.Path, &out.Path + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceReference. +func (in *ServiceReference) DeepCopy() *ServiceReference { + if in == nil { + return nil + } + out := new(ServiceReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WebhookClientConfig) DeepCopyInto(out *WebhookClientConfig) { + *out = *in + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(string) + **out = **in + } + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = new(ServiceReference) + (*in).DeepCopyInto(*out) + } + if in.CABundle != nil { + in, out := &in.CABundle, &out.CABundle + *out = make([]byte, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookClientConfig. +func (in *WebhookClientConfig) DeepCopy() *WebhookClientConfig { + if in == nil { + return nil + } + out := new(WebhookClientConfig) + in.DeepCopyInto(out) + return out +} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/BUILD b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/BUILD index 7bdf1a397fdd5..5ad15a9b68cba 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/BUILD +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/BUILD @@ -13,6 +13,7 @@ go_library( "customresource_discovery.go", "customresource_discovery_controller.go", "customresource_handler.go", + "helpers.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver", importpath = "k8s.io/apiextensions-apiserver/pkg/apiserver", diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go index e3b3d0a44138c..13c465a557539 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go @@ -136,7 +136,11 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error { Categories: crd.Status.AcceptedNames.Categories, }) - if crd.Spec.Subresources != nil && crd.Spec.Subresources.Status != nil { + subresources, err := getSubresourcesForVersion(crd, version.Version) + if err != nil { + return err + } + if subresources != nil && subresources.Status != nil { apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{ Name: crd.Status.AcceptedNames.Plural + "/status", Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped, @@ -145,7 +149,7 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error { }) } - if crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil { + if subresources != nil && subresources.Scale != nil { apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{ Group: autoscaling.GroupName, Version: "v1", diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go index 697c5e591a154..3903d9fcb4334 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go @@ -220,10 +220,16 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } var handler http.HandlerFunc + subresources, err := getSubresourcesForVersion(crd, requestInfo.APIVersion) + if err != nil { + utilruntime.HandleError(err) + http.Error(w, "the server could not properly serve the CR subresources", http.StatusInternalServerError) + return + } switch { - case subresource == "status" && crd.Spec.Subresources != nil && crd.Spec.Subresources.Status != nil: + case subresource == "status" && subresources != nil && subresources.Status != nil: handler = r.serveStatus(w, req, requestInfo, crdInfo, terminating, supportedTypes) - case subresource == "scale" && crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil: + case subresource == "scale" && subresources != nil && subresources.Scale != nil: handler = r.serveScale(w, req, requestInfo, crdInfo, terminating, supportedTypes) case len(subresource) == 0: handler = r.serveResource(w, req, requestInfo, crdInfo, terminating, supportedTypes) @@ -443,19 +449,28 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource typer := newUnstructuredObjectTyper(parameterScheme) creator := unstructuredCreator{} - validator, _, err := apiservervalidation.NewSchemaValidator(crd.Spec.Validation) + validationSchema, err := getSchemaForVersion(crd, v.Name) + if err != nil { + utilruntime.HandleError(err) + return nil, fmt.Errorf("the server could not properly serve the CR schema") + } + validator, _, err := apiservervalidation.NewSchemaValidator(validationSchema) if err != nil { return nil, err } var statusSpec *apiextensions.CustomResourceSubresourceStatus var statusValidator *validate.SchemaValidator - if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && crd.Spec.Subresources != nil && crd.Spec.Subresources.Status != nil { - statusSpec = crd.Spec.Subresources.Status - + subresources, err := getSubresourcesForVersion(crd, v.Name) + if err != nil { + utilruntime.HandleError(err) + return nil, fmt.Errorf("the server could not properly serve the CR subresources") + } + if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Status != nil { + statusSpec = subresources.Status // for the status subresource, validate only against the status schema - if crd.Spec.Validation != nil && crd.Spec.Validation.OpenAPIV3Schema != nil && crd.Spec.Validation.OpenAPIV3Schema.Properties != nil { - if statusSchema, ok := crd.Spec.Validation.OpenAPIV3Schema.Properties["status"]; ok { + if validationSchema != nil && validationSchema.OpenAPIV3Schema != nil && validationSchema.OpenAPIV3Schema.Properties != nil { + if statusSchema, ok := validationSchema.OpenAPIV3Schema.Properties["status"]; ok { openapiSchema := &spec.Schema{} if err := apiservervalidation.ConvertJSONSchemaProps(&statusSchema, openapiSchema); err != nil { return nil, err @@ -466,17 +481,23 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource } var scaleSpec *apiextensions.CustomResourceSubresourceScale - if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil { - scaleSpec = crd.Spec.Subresources.Scale + if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Scale != nil { + scaleSpec = subresources.Scale } - table, err := tableconvertor.New(crd.Spec.AdditionalPrinterColumns) + columns, err := getColumnsForVersion(crd, v.Name) + if err != nil { + utilruntime.HandleError(err) + return nil, fmt.Errorf("the server could not properly serve the CR columns") + } + table, err := tableconvertor.New(columns) if err != nil { glog.V(2).Infof("The CRD for %v has an invalid printer specification, falling back to default printing: %v", kind, err) } storages[v.Name] = customresource.NewStorage( schema.GroupResource{Group: crd.Spec.Group, Resource: crd.Status.AcceptedNames.Plural}, + schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.Kind}, schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.ListKind}, customresource.NewStrategy( typer, @@ -525,6 +546,9 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource Resource: schema.GroupVersionResource{Group: crd.Spec.Group, Version: v.Name, Resource: crd.Status.AcceptedNames.Plural}, Kind: kind, + // a handler for a specific group-version of a custom resource uses that version as the in-memory representation + HubGroupVersion: kind.GroupVersion(), + MetaGroupVersion: metav1.SchemeGroupVersion, TableConvertor: storages[v.Name].CustomResource, diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/helpers.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/helpers.go new file mode 100644 index 0000000000000..ae77bfcd5a80d --- /dev/null +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/helpers.go @@ -0,0 +1,117 @@ +/* +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 apiserver + +import ( + "fmt" + + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" +) + +// getSchemaForVersion returns the validation schema for given version in given CRD. +func getSchemaForVersion(crd *apiextensions.CustomResourceDefinition, version string) (*apiextensions.CustomResourceValidation, error) { + if !hasPerVersionSchema(crd.Spec.Versions) { + return crd.Spec.Validation, nil + } + if crd.Spec.Validation != nil { + return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version schemas must be mutual exclusive", crd.Name, version) + } + for _, v := range crd.Spec.Versions { + if version == v.Name { + return v.Schema, nil + } + } + return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name) +} + +// getSubresourcesForVersion returns the subresources for given version in given CRD. +func getSubresourcesForVersion(crd *apiextensions.CustomResourceDefinition, version string) (*apiextensions.CustomResourceSubresources, error) { + if !hasPerVersionSubresources(crd.Spec.Versions) { + return crd.Spec.Subresources, nil + } + if crd.Spec.Subresources != nil { + return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version subresources must be mutual exclusive", crd.Name, version) + } + for _, v := range crd.Spec.Versions { + if version == v.Name { + return v.Subresources, nil + } + } + return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name) +} + +// getColumnsForVersion returns the columns for given version in given CRD. +// NOTE: the newly logically-defaulted columns is not pointing to the original CRD object. +// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through +// the original CRD object instead. +func getColumnsForVersion(crd *apiextensions.CustomResourceDefinition, version string) ([]apiextensions.CustomResourceColumnDefinition, error) { + if !hasPerVersionColumns(crd.Spec.Versions) { + return serveDefaultColumnsIfEmpty(crd.Spec.AdditionalPrinterColumns), nil + } + if len(crd.Spec.AdditionalPrinterColumns) > 0 { + return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version additionalPrinterColumns must be mutual exclusive", crd.Name, version) + } + for _, v := range crd.Spec.Versions { + if version == v.Name { + return serveDefaultColumnsIfEmpty(v.AdditionalPrinterColumns), nil + } + } + return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name) +} + +// serveDefaultColumnsIfEmpty applies logically defaulting to columns, if the input columns is empty. +// NOTE: in this way, the newly logically-defaulted columns is not pointing to the original CRD object. +// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through +// the original CRD object instead. +func serveDefaultColumnsIfEmpty(columns []apiextensions.CustomResourceColumnDefinition) []apiextensions.CustomResourceColumnDefinition { + if len(columns) > 0 { + return columns + } + return []apiextensions.CustomResourceColumnDefinition{ + {Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"}, + } +} + +// hasPerVersionSchema returns true if a CRD uses per-version schema. +func hasPerVersionSchema(versions []apiextensions.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if v.Schema != nil { + return true + } + } + return false +} + +// hasPerVersionSubresources returns true if a CRD uses per-version subresources. +func hasPerVersionSubresources(versions []apiextensions.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if v.Subresources != nil { + return true + } + } + return false +} + +// hasPerVersionColumns returns true if a CRD uses per-version columns. +func hasPerVersionColumns(versions []apiextensions.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if len(v.AdditionalPrinterColumns) > 0 { + return true + } + } + return false +} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go index 24e72f91e596d..8af73d2e19630 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go @@ -40,6 +40,12 @@ const ( // // CustomResourceSubresources defines the subresources for CustomResources CustomResourceSubresources utilfeature.Feature = "CustomResourceSubresources" + + // owner: @mbohlool, @roycaihw + // alpha: v1.13 + // + // CustomResourceWebhookConversion defines the webhook conversion for Custom Resources. + CustomResourceWebhookConversion utilfeature.Feature = "CustomResourceWebhookConversion" ) func init() { @@ -50,6 +56,7 @@ func init() { // To add a new feature, define a key for it above and add it here. The features will be // available throughout Kubernetes binaries. var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{ - CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta}, - CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta}, + CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta}, + CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta}, + CustomResourceWebhookConversion: {Default: false, PreRelease: utilfeature.Alpha}, } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/BUILD b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/BUILD index df63d504687a4..1dee954284955 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/BUILD +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/BUILD @@ -64,6 +64,7 @@ go_test( srcs = [ "etcd_test.go", "status_strategy_test.go", + "strategy_test.go", ], embed = [":go_default_library"], deps = [ diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go index 0a94bc5c49487..cb7c8805398fc 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go @@ -40,8 +40,8 @@ type CustomResourceStorage struct { Scale *ScaleREST } -func NewStorage(resource schema.GroupResource, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) CustomResourceStorage { - customResourceREST, customResourceStatusREST := newREST(resource, listKind, strategy, optsGetter, categories, tableConvertor) +func NewStorage(resource schema.GroupResource, kind, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) CustomResourceStorage { + customResourceREST, customResourceStatusREST := newREST(resource, kind, listKind, strategy, optsGetter, categories, tableConvertor) s := CustomResourceStorage{ CustomResource: customResourceREST, @@ -75,9 +75,14 @@ type REST struct { } // newREST returns a RESTStorage object that will work against API services. -func newREST(resource schema.GroupResource, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) (*REST, *StatusREST) { +func newREST(resource schema.GroupResource, kind, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) (*REST, *StatusREST) { store := &genericregistry.Store{ - NewFunc: func() runtime.Object { return &unstructured.Unstructured{} }, + NewFunc: func() runtime.Object { + // set the expected group/version/kind in the new object as a signal to the versioning decoder + ret := &unstructured.Unstructured{} + ret.SetGroupVersionKind(kind) + return ret + }, NewListFunc: func() runtime.Object { // lists are never stored, only manufactured, so stomp in the right kind ret := &unstructured.UnstructuredList{} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go index 0a6870dc05da9..75339730e2365 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go @@ -91,6 +91,7 @@ func newStorage(t *testing.T) (customresource.CustomResourceStorage, *etcdtestin storage := customresource.NewStorage( schema.GroupResource{Group: "mygroup.example.com", Resource: "noxus"}, + kind, schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "NoxuItemList"}, customresource.NewStrategy( typer, diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go index 4895e287af16c..988fdc1fef92d 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go @@ -87,45 +87,46 @@ func (a customResourceStrategy) PrepareForCreate(ctx context.Context, obj runtim // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (a customResourceStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { - if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) || a.status == nil { - return - } - newCustomResourceObject := obj.(*unstructured.Unstructured) oldCustomResourceObject := old.(*unstructured.Unstructured) newCustomResource := newCustomResourceObject.UnstructuredContent() oldCustomResource := oldCustomResourceObject.UnstructuredContent() - // update is not allowed to set status - _, ok1 := newCustomResource["status"] - _, ok2 := oldCustomResource["status"] - switch { - case ok2: - newCustomResource["status"] = oldCustomResource["status"] - case ok1: - delete(newCustomResource, "status") + // If the /status subresource endpoint is installed, update is not allowed to set status. + if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && a.status != nil { + _, ok1 := newCustomResource["status"] + _, ok2 := oldCustomResource["status"] + switch { + case ok2: + newCustomResource["status"] = oldCustomResource["status"] + case ok1: + delete(newCustomResource, "status") + } } - // Any changes to the spec increment the generation number, any changes to the - // status should reflect the generation number of the corresponding object. We push - // the burden of managing the status onto the clients because we can't (in general) - // know here what version of spec the writer of the status has seen. It may seem like - // we can at first -- since obj contains spec -- but in the future we will probably make - // status its own object, and even if we don't, writes may be the result of a - // read-update-write loop, so the contents of spec may not actually be the spec that - // the CustomResource has *seen*. - newSpec, ok1 := newCustomResource["spec"] - oldSpec, ok2 := oldCustomResource["spec"] - - // spec is changed, created or deleted - if (ok1 && ok2 && !apiequality.Semantic.DeepEqual(oldSpec, newSpec)) || (ok1 && !ok2) || (!ok1 && ok2) { + // except for the changes to `metadata`, any other changes + // cause the generation to increment. + newCopyContent := copyNonMetadata(newCustomResource) + oldCopyContent := copyNonMetadata(oldCustomResource) + if !apiequality.Semantic.DeepEqual(newCopyContent, oldCopyContent) { oldAccessor, _ := meta.Accessor(oldCustomResourceObject) newAccessor, _ := meta.Accessor(newCustomResourceObject) newAccessor.SetGeneration(oldAccessor.GetGeneration() + 1) } } +func copyNonMetadata(original map[string]interface{}) map[string]interface{} { + ret := make(map[string]interface{}) + for key, val := range original { + if key == "metadata" { + continue + } + ret[key] = val + } + return ret +} + // Validate validates a new CustomResource. func (a customResourceStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { return a.validator.Validate(ctx, obj, a.scale) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy_test.go new file mode 100644 index 0000000000000..8e8f178700b7d --- /dev/null +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy_test.go @@ -0,0 +1,257 @@ +/* +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 customresource + +import ( + "context" + "reflect" + "testing" + + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func generation1() map[string]interface{} { + return map[string]interface{}{ + "generation": int64(1), + } +} + +func generation2() map[string]interface{} { + return map[string]interface{}{ + "generation": int64(2), + } +} + +func TestStrategyPrepareForUpdate(t *testing.T) { + strategy := customResourceStrategy{} + tcs := []struct { + name string + old *unstructured.Unstructured + obj *unstructured.Unstructured + statusEnabled bool + expected *unstructured.Unstructured + }{ + { + name: "/status is enabled, spec changes increment generation", + statusEnabled: true, + old: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "status": "old", + }, + }, + obj: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "new", + "status": "old", + }, + }, + expected: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation2(), + "spec": "new", + "status": "old", + }, + }, + }, + { + name: "/status is enabled, status changes do not increment generation, status changes removed", + statusEnabled: true, + old: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "status": "old", + }, + }, + obj: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "status": "new", + }, + }, + expected: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "status": "old", + }, + }, + }, + { + name: "/status is enabled, metadata changes do not increment generation", + statusEnabled: true, + old: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "generation": int64(1), + "other": "old", + }, + "spec": "old", + "status": "old", + }, + }, + obj: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "generation": int64(1), + "other": "new", + }, + "spec": "old", + "status": "old", + }, + }, + expected: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "generation": int64(1), + "other": "new", + }, + "spec": "old", + "status": "old", + }, + }, + }, + { + name: "/status is disabled, spec changes increment generation", + statusEnabled: false, + old: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "status": "old", + }, + }, + obj: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "new", + "status": "old", + }, + }, + expected: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation2(), + "spec": "new", + "status": "old", + }, + }, + }, + { + name: "/status is disabled, status changes increment generation", + statusEnabled: false, + old: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "status": "old", + }, + }, + obj: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "status": "new", + }, + }, + expected: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation2(), + "spec": "old", + "status": "new", + }, + }, + }, + { + name: "/status is disabled, other top-level field changes increment generation", + statusEnabled: false, + old: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "image": "old", + "status": "old", + }, + }, + obj: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation1(), + "spec": "old", + "image": "new", + "status": "old", + }, + }, + expected: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": generation2(), + "spec": "old", + "image": "new", + "status": "old", + }, + }, + }, + { + name: "/status is disabled, metadata changes do not increment generation", + statusEnabled: false, + old: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "generation": int64(1), + "other": "old", + }, + "spec": "old", + "status": "old", + }, + }, + obj: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "generation": int64(1), + "other": "new", + }, + "spec": "old", + "status": "old", + }, + }, + expected: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "generation": int64(1), + "other": "new", + }, + "spec": "old", + "status": "old", + }, + }, + }, + } + for _, tc := range tcs { + if tc.statusEnabled { + strategy.status = &apiextensions.CustomResourceSubresourceStatus{} + } else { + strategy.status = nil + } + strategy.PrepareForUpdate(context.TODO(), tc.obj, tc.old) + if !reflect.DeepEqual(tc.obj, tc.expected) { + t.Errorf("test %q failed: expected: %v, got %v", tc.name, tc.expected, tc.obj) + } + } +} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go index a0bebb7a7b0ee..ee3d8eaf042c0 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go @@ -20,6 +20,9 @@ import ( "context" "fmt" + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation" + apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" @@ -29,10 +32,6 @@ import ( "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/names" utilfeature "k8s.io/apiserver/pkg/util/feature" - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation" - apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" ) // strategy implements behavior for CustomResources. @@ -58,9 +57,28 @@ func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { // if the feature gate is disabled, drop the feature. if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) { crd.Spec.Validation = nil + for i := range crd.Spec.Versions { + crd.Spec.Versions[i].Schema = nil + } } if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) { crd.Spec.Subresources = nil + for i := range crd.Spec.Versions { + crd.Spec.Versions[i].Subresources = nil + } + } + // On CREATE, if the CustomResourceWebhookConversion feature gate is off, we auto-clear + // the per-version fields. This is to be consistent with the other built-in types, as the + // apiserver drops unknown fields. + if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) { + for i := range crd.Spec.Versions { + crd.Spec.Versions[i].Schema = nil + crd.Spec.Versions[i].Subresources = nil + crd.Spec.Versions[i].AdditionalPrinterColumns = nil + } + } + if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && crd.Spec.Conversion != nil { + crd.Spec.Conversion.WebhookClientConfig = nil } for _, v := range crd.Spec.Versions { @@ -94,10 +112,41 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) { newCRD.Spec.Validation = nil oldCRD.Spec.Validation = nil + for i := range newCRD.Spec.Versions { + newCRD.Spec.Versions[i].Schema = nil + } + for i := range oldCRD.Spec.Versions { + oldCRD.Spec.Versions[i].Schema = nil + } } if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) { newCRD.Spec.Subresources = nil oldCRD.Spec.Subresources = nil + for i := range newCRD.Spec.Versions { + newCRD.Spec.Versions[i].Subresources = nil + } + for i := range oldCRD.Spec.Versions { + oldCRD.Spec.Versions[i].Subresources = nil + } + } + + // On UPDATE, if the CustomResourceWebhookConversion feature gate is off, we auto-clear + // the per-version fields if the old CRD doesn't use per-version fields already. + // This is to be consistent with the other built-in types, as the apiserver drops unknown + // fields. If the old CRD already uses per-version fields, the CRD is allowed to continue + // use per-version fields. + if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && + !hasPerVersionField(oldCRD.Spec.Versions) { + for i := range newCRD.Spec.Versions { + newCRD.Spec.Versions[i].Schema = nil + newCRD.Spec.Versions[i].Subresources = nil + newCRD.Spec.Versions[i].AdditionalPrinterColumns = nil + } + } + if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && newCRD.Spec.Conversion != nil { + if oldCRD.Spec.Conversion == nil || newCRD.Spec.Conversion.WebhookClientConfig == nil { + newCRD.Spec.Conversion.WebhookClientConfig = nil + } } for _, v := range newCRD.Spec.Versions { @@ -110,6 +159,16 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { } } +// hasPerVersionField returns true if a CRD uses per-version schema/subresources/columns fields. +func hasPerVersionField(versions []apiextensions.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if v.Schema != nil || v.Subresources != nil || len(v.AdditionalPrinterColumns) > 0 { + return true + } + } + return false +} + // Validate validates a new CustomResourceDefinition. func (strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { return validation.ValidateCustomResourceDefinition(obj.(*apiextensions.CustomResourceDefinition)) diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/BUILD b/staging/src/k8s.io/apiextensions-apiserver/test/integration/BUILD index 6929e34e28319..ee8e7059292e8 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/BUILD +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/BUILD @@ -26,6 +26,7 @@ go_test( "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options:go_default_library", + "//staging/src/k8s.io/apiextensions-apiserver/pkg/features: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/api/meta:go_default_library", @@ -40,11 +41,14 @@ go_test( "//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/endpoints/request:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", "//staging/src/k8s.io/client-go/dynamic:go_default_library", "//staging/src/k8s.io/client-go/rest:go_default_library", "//vendor/github.com/coreos/etcd/clientv3:go_default_library", "//vendor/github.com/coreos/etcd/pkg/transport:go_default_library", "//vendor/github.com/ghodss/yaml:go_default_library", + "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/fixtures/resources.go b/staging/src/k8s.io/apiextensions-apiserver/test/integration/fixtures/resources.go index 9a1f2d84845da..7230725d4db28 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/fixtures/resources.go +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/fixtures/resources.go @@ -370,13 +370,13 @@ func DeleteCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceDefi return nil } -// CreateNewScaleClient returns a scale client. -func CreateNewScaleClient(crd *apiextensionsv1beta1.CustomResourceDefinition, config *rest.Config) (scale.ScalesGetter, error) { +// CreateNewVersionedScaleClient returns a scale client. +func CreateNewVersionedScaleClient(crd *apiextensionsv1beta1.CustomResourceDefinition, config *rest.Config, version string) (scale.ScalesGetter, error) { discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) if err != nil { return nil, err } - groupResource, err := discoveryClient.ServerResourcesForGroupVersion(crd.Spec.Group + "/" + crd.Spec.Version) + groupResource, err := discoveryClient.ServerResourcesForGroupVersion(crd.Spec.Group + "/" + version) if err != nil { return nil, err } @@ -386,12 +386,12 @@ func CreateNewScaleClient(crd *apiextensionsv1beta1.CustomResourceDefinition, co Group: metav1.APIGroup{ Name: crd.Spec.Group, Versions: []metav1.GroupVersionForDiscovery{ - {Version: crd.Spec.Version}, + {Version: version}, }, - PreferredVersion: metav1.GroupVersionForDiscovery{Version: crd.Spec.Version}, + PreferredVersion: metav1.GroupVersionForDiscovery{Version: version}, }, VersionedResources: map[string][]metav1.APIResource{ - crd.Spec.Version: groupResource.APIResources, + version: groupResource.APIResources, }, }, } diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/helpers.go b/staging/src/k8s.io/apiextensions-apiserver/test/integration/helpers.go index 76344034564c8..20d63c10007b7 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/helpers.go +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/helpers.go @@ -30,6 +30,8 @@ import ( "k8s.io/client-go/dynamic" ) +var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc() + func instantiateCustomResource(t *testing.T, instanceToCreate *unstructured.Unstructured, client dynamic.ResourceInterface, definition *apiextensionsv1beta1.CustomResourceDefinition) (*unstructured.Unstructured, error) { return instantiateVersionedCustomResource(t, instanceToCreate, client, definition, definition.Spec.Versions[0].Name) } @@ -92,3 +94,97 @@ func updateCustomResourceDefinitionWithRetry(client clientset.Interface, name st } return nil, fmt.Errorf("too many retries after conflicts updating CustomResourceDefinition %q", name) } + +// getSchemaForVersion returns the validation schema for given version in given CRD. +func getSchemaForVersion(crd *apiextensionsv1beta1.CustomResourceDefinition, version string) (*apiextensionsv1beta1.CustomResourceValidation, error) { + if !hasPerVersionSchema(crd.Spec.Versions) { + return crd.Spec.Validation, nil + } + if crd.Spec.Validation != nil { + return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version schemas must be mutual exclusive", crd.Name, version) + } + for _, v := range crd.Spec.Versions { + if version == v.Name { + return v.Schema, nil + } + } + return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name) +} + +// getSubresourcesForVersion returns the subresources for given version in given CRD. +func getSubresourcesForVersion(crd *apiextensionsv1beta1.CustomResourceDefinition, version string) (*apiextensionsv1beta1.CustomResourceSubresources, error) { + if !hasPerVersionSubresources(crd.Spec.Versions) { + return crd.Spec.Subresources, nil + } + if crd.Spec.Subresources != nil { + return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version subresources must be mutual exclusive", crd.Name, version) + } + for _, v := range crd.Spec.Versions { + if version == v.Name { + return v.Subresources, nil + } + } + return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name) +} + +// getColumnsForVersion returns the columns for given version in given CRD. +// NOTE: the newly logically-defaulted columns is not pointing to the original CRD object. +// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through +// the original CRD object instead. +func getColumnsForVersion(crd *apiextensionsv1beta1.CustomResourceDefinition, version string) ([]apiextensionsv1beta1.CustomResourceColumnDefinition, error) { + if !hasPerVersionColumns(crd.Spec.Versions) { + return serveDefaultColumnsIfEmpty(crd.Spec.AdditionalPrinterColumns), nil + } + if len(crd.Spec.AdditionalPrinterColumns) > 0 { + return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version additionalPrinterColumns must be mutual exclusive", crd.Name, version) + } + for _, v := range crd.Spec.Versions { + if version == v.Name { + return serveDefaultColumnsIfEmpty(v.AdditionalPrinterColumns), nil + } + } + return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name) +} + +// serveDefaultColumnsIfEmpty applies logically defaulting to columns, if the input columns is empty. +// NOTE: in this way, the newly logically-defaulted columns is not pointing to the original CRD object. +// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through +// the original CRD object instead. +func serveDefaultColumnsIfEmpty(columns []apiextensionsv1beta1.CustomResourceColumnDefinition) []apiextensionsv1beta1.CustomResourceColumnDefinition { + if len(columns) > 0 { + return columns + } + return []apiextensionsv1beta1.CustomResourceColumnDefinition{ + {Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"}, + } +} + +// hasPerVersionSchema returns true if a CRD uses per-version schema. +func hasPerVersionSchema(versions []apiextensionsv1beta1.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if v.Schema != nil { + return true + } + } + return false +} + +// hasPerVersionSubresources returns true if a CRD uses per-version subresources. +func hasPerVersionSubresources(versions []apiextensionsv1beta1.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if v.Subresources != nil { + return true + } + } + return false +} + +// hasPerVersionColumns returns true if a CRD uses per-version columns. +func hasPerVersionColumns(versions []apiextensionsv1beta1.CustomResourceDefinitionVersion) bool { + for _, v := range versions { + if len(v.AdditionalPrinterColumns) > 0 { + return true + } + } + return false +} diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go b/staging/src/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go index c8c8728ee529a..c3a7c1cb2146e 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go @@ -17,6 +17,7 @@ limitations under the License. package integration import ( + "fmt" "math" "reflect" "sort" @@ -29,45 +30,108 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" "k8s.io/client-go/dynamic" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" "k8s.io/apiextensions-apiserver/test/integration/fixtures" ) var labelSelectorPath = ".status.labelSelector" - -func NewNoxuSubresourcesCRD(scope apiextensionsv1beta1.ResourceScope) *apiextensionsv1beta1.CustomResourceDefinition { - return &apiextensionsv1beta1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "noxus.mygroup.example.com"}, - Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ - Group: "mygroup.example.com", - Version: "v1beta1", - Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ - Plural: "noxus", - Singular: "nonenglishnoxu", - Kind: "WishIHadChosenNoxu", - ShortNames: []string{"foo", "bar", "abc", "def"}, - ListKind: "NoxuItemList", +var anotherLabelSelectorPath = ".status.anotherLabelSelector" + +func NewNoxuSubresourcesCRDs(scope apiextensionsv1beta1.ResourceScope) []*apiextensionsv1beta1.CustomResourceDefinition { + return []*apiextensionsv1beta1.CustomResourceDefinition{ + // CRD that uses top-level subresources + { + ObjectMeta: metav1.ObjectMeta{Name: "noxus.mygroup.example.com"}, + Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ + Group: "mygroup.example.com", + Version: "v1beta1", + Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ + Plural: "noxus", + Singular: "nonenglishnoxu", + Kind: "WishIHadChosenNoxu", + ShortNames: []string{"foo", "bar", "abc", "def"}, + ListKind: "NoxuItemList", + }, + Scope: scope, + Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Served: true, + Storage: true, + }, + { + Name: "v1", + Served: true, + Storage: false, + }, + }, + Subresources: &apiextensionsv1beta1.CustomResourceSubresources{ + Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{}, + Scale: &apiextensionsv1beta1.CustomResourceSubresourceScale{ + SpecReplicasPath: ".spec.replicas", + StatusReplicasPath: ".status.replicas", + LabelSelectorPath: &labelSelectorPath, + }, + }, }, - Scope: scope, - Subresources: &apiextensionsv1beta1.CustomResourceSubresources{ - Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{}, - Scale: &apiextensionsv1beta1.CustomResourceSubresourceScale{ - SpecReplicasPath: ".spec.replicas", - StatusReplicasPath: ".status.replicas", - LabelSelectorPath: &labelSelectorPath, + }, + // CRD that uses per-version subresources + { + ObjectMeta: metav1.ObjectMeta{Name: "noxus.mygroup.example.com"}, + Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ + Group: "mygroup.example.com", + Version: "v1beta1", + Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ + Plural: "noxus", + Singular: "nonenglishnoxu", + Kind: "WishIHadChosenNoxu", + ShortNames: []string{"foo", "bar", "abc", "def"}, + ListKind: "NoxuItemList", + }, + Scope: scope, + Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Served: true, + Storage: true, + Subresources: &apiextensionsv1beta1.CustomResourceSubresources{ + Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{}, + Scale: &apiextensionsv1beta1.CustomResourceSubresourceScale{ + SpecReplicasPath: ".spec.replicas", + StatusReplicasPath: ".status.replicas", + LabelSelectorPath: &labelSelectorPath, + }, + }, + }, + { + Name: "v1", + Served: true, + Storage: false, + Subresources: &apiextensionsv1beta1.CustomResourceSubresources{ + Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{}, + Scale: &apiextensionsv1beta1.CustomResourceSubresourceScale{ + SpecReplicasPath: ".spec.replicas", + StatusReplicasPath: ".status.replicas", + LabelSelectorPath: &anotherLabelSelectorPath, + }, + }, + }, }, }, }, } } -func NewNoxuSubresourceInstance(namespace, name string) *unstructured.Unstructured { +func NewNoxuSubresourceInstance(namespace, name, version string) *unstructured.Unstructured { return &unstructured.Unstructured{ Object: map[string]interface{}{ - "apiVersion": "mygroup.example.com/v1beta1", + "apiVersion": fmt.Sprintf("mygroup.example.com/%s", version), "kind": "WishIHadChosenNoxu", "metadata": map[string]interface{}{ "namespace": namespace, @@ -85,112 +149,120 @@ func NewNoxuSubresourceInstance(namespace, name string) *unstructured.Unstructur } func TestStatusSubresource(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { t.Fatal(err) } defer tearDown() - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - _, err = instantiateCustomResource(t, NewNoxuSubresourceInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - - // status should not be set after creation - if val, ok := gottenNoxuInstance.Object["status"]; ok { - t.Fatalf("status should not be set after creation, got %v", val) - } - - // .status.num = 20 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // .spec.num = 20 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "spec", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // UpdateStatus should not update spec. - // Check that .spec.num = 10 and .status.num = 20 - updatedStatusInstance, err := noxuResourceClient.UpdateStatus(gottenNoxuInstance, metav1.UpdateOptions{}) - if err != nil { - t.Fatalf("unable to update status: %v", err) - } - - specNum, found, err := unstructured.NestedInt64(updatedStatusInstance.Object, "spec", "num") - if !found || err != nil { - t.Fatalf("unable to get .spec.num") - } - if specNum != int64(10) { - t.Fatalf(".spec.num: expected: %v, got: %v", int64(10), specNum) - } - - statusNum, found, err := unstructured.NestedInt64(updatedStatusInstance.Object, "status", "num") - if !found || err != nil { - t.Fatalf("unable to get .status.num") - } - if statusNum != int64(20) { - t.Fatalf(".status.num: expected: %v, got: %v", int64(20), statusNum) - } - - gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - - // .status.num = 40 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(40), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // .spec.num = 40 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(40), "spec", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // Update should not update status. - // Check that .spec.num = 40 and .status.num = 20 - updatedInstance, err := noxuResourceClient.Update(gottenNoxuInstance, metav1.UpdateOptions{}) - if err != nil { - t.Fatalf("unable to update instance: %v", err) - } - - specNum, found, err = unstructured.NestedInt64(updatedInstance.Object, "spec", "num") - if !found || err != nil { - t.Fatalf("unable to get .spec.num") - } - if specNum != int64(40) { - t.Fatalf(".spec.num: expected: %v, got: %v", int64(40), specNum) - } - - statusNum, found, err = unstructured.NestedInt64(updatedInstance.Object, "status", "num") - if !found || err != nil { - t.Fatalf("unable to get .status.num") - } - if statusNum != int64(20) { - t.Fatalf(".status.num: expected: %v, got: %v", int64(20), statusNum) + noxuDefinitions := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.NamespaceScoped) + for _, noxuDefinition := range noxuDefinitions { + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + + ns := "not-the-default" + for _, v := range noxuDefinition.Spec.Versions { + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + _, err = instantiateVersionedCustomResource(t, NewNoxuSubresourceInstance(ns, "foo", v.Name), noxuResourceClient, noxuDefinition, v.Name) + if err != nil { + t.Fatalf("unable to create noxu instance: %v", err) + } + gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + // status should not be set after creation + if val, ok := gottenNoxuInstance.Object["status"]; ok { + t.Fatalf("status should not be set after creation, got %v", val) + } + + // .status.num = 20 + err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "status", "num") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // .spec.num = 20 + err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "spec", "num") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // UpdateStatus should not update spec. + // Check that .spec.num = 10 and .status.num = 20 + updatedStatusInstance, err := noxuResourceClient.UpdateStatus(gottenNoxuInstance, metav1.UpdateOptions{}) + if err != nil { + t.Fatalf("unable to update status: %v", err) + } + + specNum, found, err := unstructured.NestedInt64(updatedStatusInstance.Object, "spec", "num") + if !found || err != nil { + t.Fatalf("unable to get .spec.num") + } + if specNum != int64(10) { + t.Fatalf(".spec.num: expected: %v, got: %v", int64(10), specNum) + } + + statusNum, found, err := unstructured.NestedInt64(updatedStatusInstance.Object, "status", "num") + if !found || err != nil { + t.Fatalf("unable to get .status.num") + } + if statusNum != int64(20) { + t.Fatalf(".status.num: expected: %v, got: %v", int64(20), statusNum) + } + + gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + // .status.num = 40 + err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(40), "status", "num") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // .spec.num = 40 + err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(40), "spec", "num") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Update should not update status. + // Check that .spec.num = 40 and .status.num = 20 + updatedInstance, err := noxuResourceClient.Update(gottenNoxuInstance, metav1.UpdateOptions{}) + if err != nil { + t.Fatalf("unable to update instance: %v", err) + } + + specNum, found, err = unstructured.NestedInt64(updatedInstance.Object, "spec", "num") + if !found || err != nil { + t.Fatalf("unable to get .spec.num") + } + if specNum != int64(40) { + t.Fatalf(".spec.num: expected: %v, got: %v", int64(40), specNum) + } + + statusNum, found, err = unstructured.NestedInt64(updatedInstance.Object, "status", "num") + if !found || err != nil { + t.Fatalf("unable to get .status.num") + } + if statusNum != int64(20) { + t.Fatalf(".status.num: expected: %v, got: %v", int64(20), statusNum) + } + noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}) + } + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } } } func TestScaleSubresource(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() groupResource := schema.GroupResource{ Group: "mygroup.example.com", Resource: "noxus", @@ -211,117 +283,132 @@ func TestScaleSubresource(t *testing.T) { t.Fatal(err) } - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - - // set invalid json path for specReplicasPath - noxuDefinition.Spec.Subresources.Scale.SpecReplicasPath = "foo,bar" - _, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err == nil { - t.Fatalf("unexpected non-error: specReplicasPath should be a valid json path under .spec") - } - - noxuDefinition.Spec.Subresources.Scale.SpecReplicasPath = ".spec.replicas" - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - _, err = instantiateCustomResource(t, NewNoxuSubresourceInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - scaleClient, err := fixtures.CreateNewScaleClient(noxuDefinition, config) - if err != nil { - t.Fatal(err) - } - - // set .status.labelSelector = bar - gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - err = unstructured.SetNestedField(gottenNoxuInstance.Object, "bar", "status", "labelSelector") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - _, err = noxuResourceClient.UpdateStatus(gottenNoxuInstance, metav1.UpdateOptions{}) - if err != nil { - t.Fatalf("unable to update status: %v", err) - } - - // get the scale object - gottenScale, err := scaleClient.Scales("not-the-default").Get(groupResource, "foo") - if err != nil { - t.Fatal(err) - } - if gottenScale.Spec.Replicas != 3 { - t.Fatalf("Scale.Spec.Replicas: expected: %v, got: %v", 3, gottenScale.Spec.Replicas) - } - if gottenScale.Status.Selector != "bar" { - t.Fatalf("Scale.Status.Selector: expected: %v, got: %v", "bar", gottenScale.Status.Selector) - } - - // check self link - expectedSelfLink := "/apis/mygroup.example.com/v1beta1/namespaces/not-the-default/noxus/foo/scale" - if gottenScale.GetSelfLink() != expectedSelfLink { - t.Fatalf("Scale.Metadata.SelfLink: expected: %v, got: %v", expectedSelfLink, gottenScale.GetSelfLink()) - } - - // update the scale object - // check that spec is updated, but status is not - gottenScale.Spec.Replicas = 5 - gottenScale.Status.Selector = "baz" - updatedScale, err := scaleClient.Scales("not-the-default").Update(groupResource, gottenScale) - if err != nil { - t.Fatal(err) - } - if updatedScale.Spec.Replicas != 5 { - t.Fatalf("replicas: expected: %v, got: %v", 5, updatedScale.Spec.Replicas) - } - if updatedScale.Status.Selector != "bar" { - t.Fatalf("scale should not update status: expected %v, got: %v", "bar", updatedScale.Status.Selector) - } - - // check that .spec.replicas = 5, but status is not updated - updatedNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - specReplicas, found, err := unstructured.NestedInt64(updatedNoxuInstance.Object, "spec", "replicas") - if !found || err != nil { - t.Fatalf("unable to get .spec.replicas") - } - if specReplicas != 5 { - t.Fatalf("replicas: expected: %v, got: %v", 5, specReplicas) - } - statusLabelSelector, found, err := unstructured.NestedString(updatedNoxuInstance.Object, "status", "labelSelector") - if !found || err != nil { - t.Fatalf("unable to get .status.labelSelector") - } - if statusLabelSelector != "bar" { - t.Fatalf("scale should not update status: expected %v, got: %v", "bar", statusLabelSelector) - } - - // validate maximum value - // set .spec.replicas = math.MaxInt64 - gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(math.MaxInt64), "spec", "replicas") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - _, err = noxuResourceClient.Update(gottenNoxuInstance, metav1.UpdateOptions{}) - if err == nil { - t.Fatalf("unexpected non-error: .spec.replicas should be less than 2147483647") + noxuDefinitions := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.NamespaceScoped) + for _, noxuDefinition := range noxuDefinitions { + for _, v := range noxuDefinition.Spec.Versions { + // Start with a new CRD, so that the object doesn't have resourceVersion + noxuDefinition := noxuDefinition.DeepCopy() + + subresources, err := getSubresourcesForVersion(noxuDefinition, v.Name) + if err != nil { + t.Fatal(err) + } + // set invalid json path for specReplicasPath + subresources.Scale.SpecReplicasPath = "foo,bar" + _, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err == nil { + t.Fatalf("unexpected non-error: specReplicasPath should be a valid json path under .spec") + } + + subresources.Scale.SpecReplicasPath = ".spec.replicas" + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + + ns := "not-the-default" + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + _, err = instantiateVersionedCustomResource(t, NewNoxuSubresourceInstance(ns, "foo", v.Name), noxuResourceClient, noxuDefinition, v.Name) + if err != nil { + t.Fatalf("unable to create noxu instance: %v", err) + } + + scaleClient, err := fixtures.CreateNewVersionedScaleClient(noxuDefinition, config, v.Name) + if err != nil { + t.Fatal(err) + } + + // set .status.labelSelector = bar + gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + err = unstructured.SetNestedField(gottenNoxuInstance.Object, "bar", strings.Split((*subresources.Scale.LabelSelectorPath)[1:], ".")...) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + _, err = noxuResourceClient.UpdateStatus(gottenNoxuInstance, metav1.UpdateOptions{}) + if err != nil { + t.Fatalf("unable to update status: %v", err) + } + + // get the scale object + gottenScale, err := scaleClient.Scales("not-the-default").Get(groupResource, "foo") + if err != nil { + t.Fatal(err) + } + if gottenScale.Spec.Replicas != 3 { + t.Fatalf("Scale.Spec.Replicas: expected: %v, got: %v", 3, gottenScale.Spec.Replicas) + } + if gottenScale.Status.Selector != "bar" { + t.Fatalf("Scale.Status.Selector: expected: %v, got: %v", "bar", gottenScale.Status.Selector) + } + + // check self link + expectedSelfLink := fmt.Sprintf("/apis/mygroup.example.com/%s/namespaces/not-the-default/noxus/foo/scale", v.Name) + if gottenScale.GetSelfLink() != expectedSelfLink { + t.Fatalf("Scale.Metadata.SelfLink: expected: %v, got: %v", expectedSelfLink, gottenScale.GetSelfLink()) + } + + // update the scale object + // check that spec is updated, but status is not + gottenScale.Spec.Replicas = 5 + gottenScale.Status.Selector = "baz" + updatedScale, err := scaleClient.Scales("not-the-default").Update(groupResource, gottenScale) + if err != nil { + t.Fatal(err) + } + if updatedScale.Spec.Replicas != 5 { + t.Fatalf("replicas: expected: %v, got: %v", 5, updatedScale.Spec.Replicas) + } + if updatedScale.Status.Selector != "bar" { + t.Fatalf("scale should not update status: expected %v, got: %v", "bar", updatedScale.Status.Selector) + } + + // check that .spec.replicas = 5, but status is not updated + updatedNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + specReplicas, found, err := unstructured.NestedInt64(updatedNoxuInstance.Object, "spec", "replicas") + if !found || err != nil { + t.Fatalf("unable to get .spec.replicas") + } + if specReplicas != 5 { + t.Fatalf("replicas: expected: %v, got: %v", 5, specReplicas) + } + statusLabelSelector, found, err := unstructured.NestedString(updatedNoxuInstance.Object, strings.Split((*subresources.Scale.LabelSelectorPath)[1:], ".")...) + if !found || err != nil { + t.Fatalf("unable to get %s", *subresources.Scale.LabelSelectorPath) + } + if statusLabelSelector != "bar" { + t.Fatalf("scale should not update status: expected %v, got: %v", "bar", statusLabelSelector) + } + + // validate maximum value + // set .spec.replicas = math.MaxInt64 + gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(math.MaxInt64), "spec", "replicas") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + _, err = noxuResourceClient.Update(gottenNoxuInstance, metav1.UpdateOptions{}) + if err == nil { + t.Fatalf("unexpected non-error: .spec.replicas should be less than 2147483647") + } + noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}) + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } + } } } func TestValidationSchemaWithStatus(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, config, _, err := fixtures.StartDefaultServer(t) if err != nil { t.Fatal(err) @@ -338,7 +425,7 @@ func TestValidationSchemaWithStatus(t *testing.T) { } // fields other than properties in root schema are not allowed - noxuDefinition := newNoxuValidationCRD(apiextensionsv1beta1.NamespaceScoped) + noxuDefinition := newNoxuValidationCRDs(apiextensionsv1beta1.NamespaceScoped)[0] noxuDefinition.Spec.Subresources = &apiextensionsv1beta1.CustomResourceSubresources{ Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{}, } @@ -369,6 +456,7 @@ func TestValidationSchemaWithStatus(t *testing.T) { } func TestValidateOnlyStatus(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { t.Fatal(err) @@ -403,59 +491,79 @@ func TestValidateOnlyStatus(t *testing.T) { }, } - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{ - OpenAPIV3Schema: schema, - } - - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - - // set .spec.num = 10 and .status.num = 10 - noxuInstance := NewNoxuSubresourceInstance(ns, "foo") - err = unstructured.SetNestedField(noxuInstance.Object, int64(10), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - createdNoxuInstance, err := instantiateCustomResource(t, noxuInstance, noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - // update the spec with .spec.num = 15, expecting no error - err = unstructured.SetNestedField(createdNoxuInstance.Object, int64(15), "spec", "num") - if err != nil { - t.Fatalf("unexpected error setting .spec.num: %v", err) - } - createdNoxuInstance, err = noxuResourceClient.UpdateStatus(createdNoxuInstance, metav1.UpdateOptions{}) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - // update with .status.num = 15, expecting an error - err = unstructured.SetNestedField(createdNoxuInstance.Object, int64(15), "status", "num") - if err != nil { - t.Fatalf("unexpected error setting .status.num: %v", err) - } - createdNoxuInstance, err = noxuResourceClient.UpdateStatus(createdNoxuInstance, metav1.UpdateOptions{}) - if err == nil { - t.Fatal("expected error, but got none") - } - statusError, isStatus := err.(*apierrors.StatusError) - if !isStatus || statusError == nil { - t.Fatalf("expected status error, got %T: %v", err, err) - } - if !strings.Contains(statusError.Error(), "Invalid value") { - t.Fatalf("expected 'Invalid value' in error, got: %v", err) + noxuDefinitions := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.NamespaceScoped) + for i, noxuDefinition := range noxuDefinitions { + if i == 0 { + noxuDefinition.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: schema, + } + } else { + noxuDefinition.Spec.Versions[0].Schema = &apiextensionsv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: schema, + } + schemaWithDescription := schema.DeepCopy() + schemaWithDescription.Description = "test" + noxuDefinition.Spec.Versions[1].Schema = &apiextensionsv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: schemaWithDescription, + } + } + + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + ns := "not-the-default" + for _, v := range noxuDefinition.Spec.Versions { + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + + // set .spec.num = 10 and .status.num = 10 + noxuInstance := NewNoxuSubresourceInstance(ns, "foo", v.Name) + err = unstructured.SetNestedField(noxuInstance.Object, int64(10), "status", "num") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + createdNoxuInstance, err := instantiateVersionedCustomResource(t, noxuInstance, noxuResourceClient, noxuDefinition, v.Name) + if err != nil { + t.Fatalf("unable to create noxu instance: %v", err) + } + + // update the spec with .spec.num = 15, expecting no error + err = unstructured.SetNestedField(createdNoxuInstance.Object, int64(15), "spec", "num") + if err != nil { + t.Fatalf("unexpected error setting .spec.num: %v", err) + } + createdNoxuInstance, err = noxuResourceClient.UpdateStatus(createdNoxuInstance, metav1.UpdateOptions{}) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + // update with .status.num = 15, expecting an error + err = unstructured.SetNestedField(createdNoxuInstance.Object, int64(15), "status", "num") + if err != nil { + t.Fatalf("unexpected error setting .status.num: %v", err) + } + createdNoxuInstance, err = noxuResourceClient.UpdateStatus(createdNoxuInstance, metav1.UpdateOptions{}) + if err == nil { + t.Fatal("expected error, but got none") + } + statusError, isStatus := err.(*apierrors.StatusError) + if !isStatus || statusError == nil { + t.Fatalf("expected status error, got %T: %v", err, err) + } + if !strings.Contains(statusError.Error(), "Invalid value") { + t.Fatalf("expected 'Invalid value' in error, got: %v", err) + } + noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}) + } + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } } } func TestSubresourcesDiscovery(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, config, _, err := fixtures.StartDefaultServer(t) if err != nil { t.Fatal(err) @@ -471,140 +579,157 @@ func TestSubresourcesDiscovery(t *testing.T) { t.Fatal(err) } - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } + noxuDefinitions := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.NamespaceScoped) + for _, noxuDefinition := range noxuDefinitions { + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } - group := "mygroup.example.com" - version := "v1beta1" + for _, v := range noxuDefinition.Spec.Versions { + group := "mygroup.example.com" + version := v.Name - resources, err := apiExtensionClient.Discovery().ServerResourcesForGroupVersion(group + "/" + version) - if err != nil { - t.Fatal(err) - } + resources, err := apiExtensionClient.Discovery().ServerResourcesForGroupVersion(group + "/" + version) + if err != nil { + t.Fatal(err) + } - if len(resources.APIResources) != 3 { - t.Fatalf("Expected exactly the resources \"noxus\", \"noxus/status\" and \"noxus/scale\" in group version %v/%v via discovery, got: %v", group, version, resources.APIResources) - } + if len(resources.APIResources) != 3 { + t.Fatalf("Expected exactly the resources \"noxus\", \"noxus/status\" and \"noxus/scale\" in group version %v/%v via discovery, got: %v", group, version, resources.APIResources) + } - // check discovery info for status - status := resources.APIResources[1] + // check discovery info for status + status := resources.APIResources[1] - if status.Name != "noxus/status" { - t.Fatalf("incorrect status via discovery: expected name: %v, got: %v", "noxus/status", status.Name) - } + if status.Name != "noxus/status" { + t.Fatalf("incorrect status via discovery: expected name: %v, got: %v", "noxus/status", status.Name) + } - if status.Namespaced != true { - t.Fatalf("incorrect status via discovery: expected namespace: %v, got: %v", true, status.Namespaced) - } + if status.Namespaced != true { + t.Fatalf("incorrect status via discovery: expected namespace: %v, got: %v", true, status.Namespaced) + } - if status.Kind != "WishIHadChosenNoxu" { - t.Fatalf("incorrect status via discovery: expected kind: %v, got: %v", "WishIHadChosenNoxu", status.Kind) - } + if status.Kind != "WishIHadChosenNoxu" { + t.Fatalf("incorrect status via discovery: expected kind: %v, got: %v", "WishIHadChosenNoxu", status.Kind) + } - expectedVerbs := []string{"get", "patch", "update"} - sort.Strings(status.Verbs) - if !reflect.DeepEqual([]string(status.Verbs), expectedVerbs) { - t.Fatalf("incorrect status via discovery: expected: %v, got: %v", expectedVerbs, status.Verbs) - } + expectedVerbs := []string{"get", "patch", "update"} + sort.Strings(status.Verbs) + if !reflect.DeepEqual([]string(status.Verbs), expectedVerbs) { + t.Fatalf("incorrect status via discovery: expected: %v, got: %v", expectedVerbs, status.Verbs) + } - // check discovery info for scale - scale := resources.APIResources[2] + // check discovery info for scale + scale := resources.APIResources[2] - if scale.Group != autoscaling.GroupName { - t.Fatalf("incorrect scale via discovery: expected group: %v, got: %v", autoscaling.GroupName, scale.Group) - } + if scale.Group != autoscaling.GroupName { + t.Fatalf("incorrect scale via discovery: expected group: %v, got: %v", autoscaling.GroupName, scale.Group) + } - if scale.Version != "v1" { - t.Fatalf("incorrect scale via discovery: expected version: %v, got %v", "v1", scale.Version) - } + if scale.Version != "v1" { + t.Fatalf("incorrect scale via discovery: expected version: %v, got %v", "v1", scale.Version) + } - if scale.Name != "noxus/scale" { - t.Fatalf("incorrect scale via discovery: expected name: %v, got: %v", "noxus/scale", scale.Name) - } + if scale.Name != "noxus/scale" { + t.Fatalf("incorrect scale via discovery: expected name: %v, got: %v", "noxus/scale", scale.Name) + } - if scale.Namespaced != true { - t.Fatalf("incorrect scale via discovery: expected namespace: %v, got: %v", true, scale.Namespaced) - } + if scale.Namespaced != true { + t.Fatalf("incorrect scale via discovery: expected namespace: %v, got: %v", true, scale.Namespaced) + } - if scale.Kind != "Scale" { - t.Fatalf("incorrect scale via discovery: expected kind: %v, got: %v", "Scale", scale.Kind) - } + if scale.Kind != "Scale" { + t.Fatalf("incorrect scale via discovery: expected kind: %v, got: %v", "Scale", scale.Kind) + } - sort.Strings(scale.Verbs) - if !reflect.DeepEqual([]string(scale.Verbs), expectedVerbs) { - t.Fatalf("incorrect scale via discovery: expected: %v, got: %v", expectedVerbs, scale.Verbs) + sort.Strings(scale.Verbs) + if !reflect.DeepEqual([]string(scale.Verbs), expectedVerbs) { + t.Fatalf("incorrect scale via discovery: expected: %v, got: %v", expectedVerbs, scale.Verbs) + } + } + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } } } func TestGeneration(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { t.Fatal(err) } defer tearDown() - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - _, err = instantiateCustomResource(t, NewNoxuSubresourceInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - // .metadata.generation = 1 - gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - if gottenNoxuInstance.GetGeneration() != 1 { - t.Fatalf(".metadata.generation should be 1 after creation") - } - - // .status.num = 20 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // UpdateStatus does not increment generation - updatedStatusInstance, err := noxuResourceClient.UpdateStatus(gottenNoxuInstance, metav1.UpdateOptions{}) - if err != nil { - t.Fatalf("unable to update status: %v", err) - } - if updatedStatusInstance.GetGeneration() != 1 { - t.Fatalf("updating status should not increment .metadata.generation: expected: %v, got: %v", 1, updatedStatusInstance.GetGeneration()) - } - - gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - - // .spec.num = 20 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "spec", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // Update increments generation - updatedInstance, err := noxuResourceClient.Update(gottenNoxuInstance, metav1.UpdateOptions{}) - if err != nil { - t.Fatalf("unable to update instance: %v", err) - } - if updatedInstance.GetGeneration() != 2 { - t.Fatalf("updating spec should increment .metadata.generation: expected: %v, got: %v", 2, updatedStatusInstance.GetGeneration()) + noxuDefinitions := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.NamespaceScoped) + for _, noxuDefinition := range noxuDefinitions { + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + + ns := "not-the-default" + for _, v := range noxuDefinition.Spec.Versions { + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + _, err = instantiateVersionedCustomResource(t, NewNoxuSubresourceInstance(ns, "foo", v.Name), noxuResourceClient, noxuDefinition, v.Name) + if err != nil { + t.Fatalf("unable to create noxu instance: %v", err) + } + + // .metadata.generation = 1 + gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + if gottenNoxuInstance.GetGeneration() != 1 { + t.Fatalf(".metadata.generation should be 1 after creation") + } + + // .status.num = 20 + err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "status", "num") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // UpdateStatus does not increment generation + updatedStatusInstance, err := noxuResourceClient.UpdateStatus(gottenNoxuInstance, metav1.UpdateOptions{}) + if err != nil { + t.Fatalf("unable to update status: %v", err) + } + if updatedStatusInstance.GetGeneration() != 1 { + t.Fatalf("updating status should not increment .metadata.generation: expected: %v, got: %v", 1, updatedStatusInstance.GetGeneration()) + } + + gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + // .spec.num = 20 + err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "spec", "num") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Update increments generation + updatedInstance, err := noxuResourceClient.Update(gottenNoxuInstance, metav1.UpdateOptions{}) + if err != nil { + t.Fatalf("unable to update instance: %v", err) + } + if updatedInstance.GetGeneration() != 2 { + t.Fatalf("updating spec should increment .metadata.generation: expected: %v, got: %v", 2, updatedStatusInstance.GetGeneration()) + } + noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}) + } + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } } } func TestSubresourcePatch(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() groupResource := schema.GroupResource{ Group: "mygroup.example.com", Resource: "noxus", @@ -625,146 +750,155 @@ func TestSubresourcePatch(t *testing.T) { t.Fatal(err) } - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - - t.Logf("Creating foo") - _, err = instantiateCustomResource(t, NewNoxuSubresourceInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - scaleClient, err := fixtures.CreateNewScaleClient(noxuDefinition, config) - if err != nil { - t.Fatal(err) - } - - t.Logf("Patching .status.num to 999") - patch := []byte(`{"spec": {"num":999}, "status": {"num":999}}`) - patchedNoxuInstance, err := noxuResourceClient.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}, "status") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num") // .status.num should be 999 - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num") // .spec.num should remain 10 - rv, found, err := unstructured.NestedString(patchedNoxuInstance.UnstructuredContent(), "metadata", "resourceVersion") - if err != nil { - t.Fatal(err) - } - if !found { - t.Fatalf("metadata.resourceVersion not found") - } - - // this call waits for the resourceVersion to be reached in the cache before returning. - // We need to do this because the patch gets its initial object from the storage, and the cache serves that. - // If it is out of date, then our initial patch is applied to an old resource version, which conflicts - // and then the updated object shows a conflicting diff, which permanently fails the patch. - // This gives expected stability in the patch without retrying on an known number of conflicts below in the test. - // See https://issue.k8s.io/42644 - _, err = noxuResourceClient.Get("foo", metav1.GetOptions{ResourceVersion: patchedNoxuInstance.GetResourceVersion()}) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // no-op patch - t.Logf("Patching .status.num again to 999") - patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}, "status") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - // make sure no-op patch does not increment resourceVersion - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num") - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num") - expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion") - - // empty patch - t.Logf("Applying empty patch") - patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`), metav1.UpdateOptions{}, "status") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - // an empty patch is a no-op patch. make sure it does not increment resourceVersion - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num") - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num") - expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion") - - t.Logf("Patching .spec.replicas to 7") - patch = []byte(`{"spec": {"replicas":7}, "status": {"replicas":7}}`) - patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}, "scale") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 7, "spec", "replicas") - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 0, "status", "replicas") // .status.replicas should remain 0 - rv, found, err = unstructured.NestedString(patchedNoxuInstance.UnstructuredContent(), "metadata", "resourceVersion") - if err != nil { - t.Fatal(err) - } - if !found { - t.Fatalf("metadata.resourceVersion not found") - } - - // this call waits for the resourceVersion to be reached in the cache before returning. - // We need to do this because the patch gets its initial object from the storage, and the cache serves that. - // If it is out of date, then our initial patch is applied to an old resource version, which conflicts - // and then the updated object shows a conflicting diff, which permanently fails the patch. - // This gives expected stability in the patch without retrying on an known number of conflicts below in the test. - // See https://issue.k8s.io/42644 - _, err = noxuResourceClient.Get("foo", metav1.GetOptions{ResourceVersion: patchedNoxuInstance.GetResourceVersion()}) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // Scale.Spec.Replicas = 7 but Scale.Status.Replicas should remain 0 - gottenScale, err := scaleClient.Scales("not-the-default").Get(groupResource, "foo") - if err != nil { - t.Fatal(err) - } - if gottenScale.Spec.Replicas != 7 { - t.Fatalf("Scale.Spec.Replicas: expected: %v, got: %v", 7, gottenScale.Spec.Replicas) - } - if gottenScale.Status.Replicas != 0 { - t.Fatalf("Scale.Status.Replicas: expected: %v, got: %v", 0, gottenScale.Spec.Replicas) - } - - // no-op patch - t.Logf("Patching .spec.replicas again to 7") - patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}, "scale") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - // make sure no-op patch does not increment resourceVersion - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 7, "spec", "replicas") - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 0, "status", "replicas") - expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion") - - // empty patch - t.Logf("Applying empty patch") - patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`), metav1.UpdateOptions{}, "scale") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - // an empty patch is a no-op patch. make sure it does not increment resourceVersion - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 7, "spec", "replicas") - expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 0, "status", "replicas") - expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion") - - // make sure strategic merge patch is not supported for both status and scale - _, err = noxuResourceClient.Patch("foo", types.StrategicMergePatchType, patch, metav1.UpdateOptions{}, "status") - if err == nil { - t.Fatalf("unexpected non-error: strategic merge patch is not supported for custom resources") - } - - _, err = noxuResourceClient.Patch("foo", types.StrategicMergePatchType, patch, metav1.UpdateOptions{}, "scale") - if err == nil { - t.Fatalf("unexpected non-error: strategic merge patch is not supported for custom resources") + noxuDefinitions := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.NamespaceScoped) + for _, noxuDefinition := range noxuDefinitions { + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + + ns := "not-the-default" + for _, v := range noxuDefinition.Spec.Versions { + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + + t.Logf("Creating foo") + _, err = instantiateVersionedCustomResource(t, NewNoxuSubresourceInstance(ns, "foo", v.Name), noxuResourceClient, noxuDefinition, v.Name) + if err != nil { + t.Fatalf("unable to create noxu instance: %v", err) + } + + scaleClient, err := fixtures.CreateNewVersionedScaleClient(noxuDefinition, config, v.Name) + if err != nil { + t.Fatal(err) + } + + t.Logf("Patching .status.num to 999") + patch := []byte(`{"spec": {"num":999}, "status": {"num":999}}`) + patchedNoxuInstance, err := noxuResourceClient.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}, "status") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num") // .status.num should be 999 + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num") // .spec.num should remain 10 + rv, found, err := unstructured.NestedString(patchedNoxuInstance.UnstructuredContent(), "metadata", "resourceVersion") + if err != nil { + t.Fatal(err) + } + if !found { + t.Fatalf("metadata.resourceVersion not found") + } + + // this call waits for the resourceVersion to be reached in the cache before returning. + // We need to do this because the patch gets its initial object from the storage, and the cache serves that. + // If it is out of date, then our initial patch is applied to an old resource version, which conflicts + // and then the updated object shows a conflicting diff, which permanently fails the patch. + // This gives expected stability in the patch without retrying on an known number of conflicts below in the test. + // See https://issue.k8s.io/42644 + _, err = noxuResourceClient.Get("foo", metav1.GetOptions{ResourceVersion: patchedNoxuInstance.GetResourceVersion()}) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // no-op patch + t.Logf("Patching .status.num again to 999") + patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}, "status") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + // make sure no-op patch does not increment resourceVersion + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num") + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num") + expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion") + + // empty patch + t.Logf("Applying empty patch") + patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`), metav1.UpdateOptions{}, "status") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // an empty patch is a no-op patch. make sure it does not increment resourceVersion + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "status", "num") + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 10, "spec", "num") + expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion") + + t.Logf("Patching .spec.replicas to 7") + patch = []byte(`{"spec": {"replicas":7}, "status": {"replicas":7}}`) + patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}, "scale") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 7, "spec", "replicas") + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 0, "status", "replicas") // .status.replicas should remain 0 + rv, found, err = unstructured.NestedString(patchedNoxuInstance.UnstructuredContent(), "metadata", "resourceVersion") + if err != nil { + t.Fatal(err) + } + if !found { + t.Fatalf("metadata.resourceVersion not found") + } + + // this call waits for the resourceVersion to be reached in the cache before returning. + // We need to do this because the patch gets its initial object from the storage, and the cache serves that. + // If it is out of date, then our initial patch is applied to an old resource version, which conflicts + // and then the updated object shows a conflicting diff, which permanently fails the patch. + // This gives expected stability in the patch without retrying on an known number of conflicts below in the test. + // See https://issue.k8s.io/42644 + _, err = noxuResourceClient.Get("foo", metav1.GetOptions{ResourceVersion: patchedNoxuInstance.GetResourceVersion()}) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Scale.Spec.Replicas = 7 but Scale.Status.Replicas should remain 0 + gottenScale, err := scaleClient.Scales("not-the-default").Get(groupResource, "foo") + if err != nil { + t.Fatal(err) + } + if gottenScale.Spec.Replicas != 7 { + t.Fatalf("Scale.Spec.Replicas: expected: %v, got: %v", 7, gottenScale.Spec.Replicas) + } + if gottenScale.Status.Replicas != 0 { + t.Fatalf("Scale.Status.Replicas: expected: %v, got: %v", 0, gottenScale.Spec.Replicas) + } + + // no-op patch + t.Logf("Patching .spec.replicas again to 7") + patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}, "scale") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + // make sure no-op patch does not increment resourceVersion + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 7, "spec", "replicas") + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 0, "status", "replicas") + expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion") + + // empty patch + t.Logf("Applying empty patch") + patchedNoxuInstance, err = noxuResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`), metav1.UpdateOptions{}, "scale") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + // an empty patch is a no-op patch. make sure it does not increment resourceVersion + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 7, "spec", "replicas") + expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 0, "status", "replicas") + expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion") + + // make sure strategic merge patch is not supported for both status and scale + _, err = noxuResourceClient.Patch("foo", types.StrategicMergePatchType, patch, metav1.UpdateOptions{}, "status") + if err == nil { + t.Fatalf("unexpected non-error: strategic merge patch is not supported for custom resources") + } + + _, err = noxuResourceClient.Patch("foo", types.StrategicMergePatchType, patch, metav1.UpdateOptions{}, "scale") + if err == nil { + t.Fatalf("unexpected non-error: strategic merge patch is not supported for custom resources") + } + noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}) + } + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } } } diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/table_test.go b/staging/src/k8s.io/apiextensions-apiserver/test/integration/table_test.go index 7aab4f4086d3e..a10a72ecca4fd 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/table_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/table_test.go @@ -28,10 +28,14 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/types" + utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" "k8s.io/apiextensions-apiserver/test/integration/fixtures" ) @@ -48,12 +52,32 @@ func newTableCRD() *apiextensionsv1beta1.CustomResourceDefinition { ListKind: "TablemList", }, Scope: apiextensionsv1beta1.ClusterScoped, - AdditionalPrinterColumns: []apiextensionsv1beta1.CustomResourceColumnDefinition{ - {Name: "Age", Type: "date", JSONPath: ".metadata.creationTimestamp"}, - {Name: "Alpha", Type: "string", JSONPath: ".spec.alpha"}, - {Name: "Beta", Type: "integer", Description: "the beta field", Format: "int64", Priority: 42, JSONPath: ".spec.beta"}, - {Name: "Gamma", Type: "integer", Description: "a column with wrongly typed values", JSONPath: ".spec.gamma"}, - {Name: "Epsilon", Type: "string", Description: "an array of integers as string", JSONPath: ".spec.epsilon"}, + Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Served: true, + Storage: false, + AdditionalPrinterColumns: []apiextensionsv1beta1.CustomResourceColumnDefinition{ + {Name: "Age", Type: "date", JSONPath: ".metadata.creationTimestamp"}, + {Name: "Alpha", Type: "string", JSONPath: ".spec.alpha"}, + {Name: "Beta", Type: "integer", Description: "the beta field", Format: "int64", Priority: 42, JSONPath: ".spec.beta"}, + {Name: "Gamma", Type: "integer", Description: "a column with wrongly typed values", JSONPath: ".spec.gamma"}, + {Name: "Epsilon", Type: "string", Description: "an array of integers as string", JSONPath: ".spec.epsilon"}, + }, + }, + { + Name: "v1", + Served: true, + Storage: true, + AdditionalPrinterColumns: []apiextensionsv1beta1.CustomResourceColumnDefinition{ + {Name: "Age", Type: "date", JSONPath: ".metadata.creationTimestamp"}, + {Name: "Alpha", Type: "string", JSONPath: ".spec.alpha"}, + {Name: "Beta", Type: "integer", Description: "the beta field", Format: "int64", Priority: 42, JSONPath: ".spec.beta"}, + {Name: "Gamma", Type: "integer", Description: "a column with wrongly typed values", JSONPath: ".spec.gamma"}, + {Name: "Epsilon", Type: "string", Description: "an array of integers as string", JSONPath: ".spec.epsilon"}, + {Name: "Zeta", Type: "integer", Description: "the zeta field", Format: "int64", Priority: 42, JSONPath: ".spec.zeta"}, + }, + }, }, }, } @@ -62,7 +86,7 @@ func newTableCRD() *apiextensionsv1beta1.CustomResourceDefinition { func newTableInstance(name string) *unstructured.Unstructured { return &unstructured.Unstructured{ Object: map[string]interface{}{ - "apiVersion": "mygroup.example.com/v1beta1", + "apiVersion": "mygroup.example.com/v1", "kind": "Table", "metadata": map[string]interface{}{ "name": name, @@ -73,12 +97,14 @@ func newTableInstance(name string) *unstructured.Unstructured { "gamma": "bar", "delta": "hello", "epsilon": []int64{1, 2, 3}, + "zeta": 5, }, }, } } func TestTableGet(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, config, _, err := fixtures.StartDefaultServer(t) if err != nil { t.Fatal(err) @@ -107,107 +133,219 @@ func TestTableGet(t *testing.T) { } t.Logf("table crd created: %#v", crd) - crClient := newNamespacedCustomResourceClient("", dynamicClient, crd) + crClient := newNamespacedCustomResourceVersionedClient("", dynamicClient, crd, "v1") foo, err := crClient.Create(newTableInstance("foo"), metav1.CreateOptions{}) if err != nil { t.Fatalf("unable to create noxu instance: %v", err) } t.Logf("foo created: %#v", foo.UnstructuredContent()) - gv := schema.GroupVersion{Group: crd.Spec.Group, Version: crd.Spec.Version} - gvk := gv.WithKind(crd.Spec.Names.Kind) + for i, v := range crd.Spec.Versions { + gv := schema.GroupVersion{Group: crd.Spec.Group, Version: v.Name} + gvk := gv.WithKind(crd.Spec.Names.Kind) - scheme := runtime.NewScheme() - codecs := serializer.NewCodecFactory(scheme) - parameterCodec := runtime.NewParameterCodec(scheme) - metav1.AddToGroupVersion(scheme, gv) - scheme.AddKnownTypes(gv, &metav1beta1.Table{}, &metav1beta1.TableOptions{}) - scheme.AddKnownTypes(metav1beta1.SchemeGroupVersion, &metav1beta1.Table{}, &metav1beta1.TableOptions{}) + scheme := runtime.NewScheme() + codecs := serializer.NewCodecFactory(scheme) + parameterCodec := runtime.NewParameterCodec(scheme) + metav1.AddToGroupVersion(scheme, gv) + scheme.AddKnownTypes(gv, &metav1beta1.Table{}, &metav1beta1.TableOptions{}) + scheme.AddKnownTypes(metav1beta1.SchemeGroupVersion, &metav1beta1.Table{}, &metav1beta1.TableOptions{}) - crConfig := *config - crConfig.GroupVersion = &gv - crConfig.APIPath = "/apis" - crConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: codecs} - crRestClient, err := rest.RESTClientFor(&crConfig) + crConfig := *config + crConfig.GroupVersion = &gv + crConfig.APIPath = "/apis" + crConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: codecs} + crRestClient, err := rest.RESTClientFor(&crConfig) + if err != nil { + t.Fatal(err) + } + + ret, err := crRestClient.Get(). + Resource(crd.Spec.Names.Plural). + SetHeader("Accept", fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName)). + VersionedParams(&metav1beta1.TableOptions{}, parameterCodec). + Do(). + Get() + if err != nil { + t.Fatalf("failed to list %v resources: %v", gvk, err) + } + + tbl, ok := ret.(*metav1beta1.Table) + if !ok { + t.Fatalf("expected metav1beta1.Table, got %T", ret) + } + t.Logf("%v table list: %#v", gvk, tbl) + + columns, err := getColumnsForVersion(crd, v.Name) + if err != nil { + t.Fatal(err) + } + expectColumnNum := len(columns) + 1 + if got, expected := len(tbl.ColumnDefinitions), expectColumnNum; got != expected { + t.Errorf("expected %d headers, got %d", expected, got) + } else { + age := metav1beta1.TableColumnDefinition{Name: "Age", Type: "date", Format: "", Description: "Custom resource definition column (in JSONPath format): .metadata.creationTimestamp", Priority: 0} + if got, expected := tbl.ColumnDefinitions[1], age; got != expected { + t.Errorf("expected column definition %#v, got %#v", expected, got) + } + + alpha := metav1beta1.TableColumnDefinition{Name: "Alpha", Type: "string", Format: "", Description: "Custom resource definition column (in JSONPath format): .spec.alpha", Priority: 0} + if got, expected := tbl.ColumnDefinitions[2], alpha; got != expected { + t.Errorf("expected column definition %#v, got %#v", expected, got) + } + + beta := metav1beta1.TableColumnDefinition{Name: "Beta", Type: "integer", Format: "int64", Description: "the beta field", Priority: 42} + if got, expected := tbl.ColumnDefinitions[3], beta; got != expected { + t.Errorf("expected column definition %#v, got %#v", expected, got) + } + + gamma := metav1beta1.TableColumnDefinition{Name: "Gamma", Type: "integer", Description: "a column with wrongly typed values"} + if got, expected := tbl.ColumnDefinitions[4], gamma; got != expected { + t.Errorf("expected column definition %#v, got %#v", expected, got) + } + + epsilon := metav1beta1.TableColumnDefinition{Name: "Epsilon", Type: "string", Description: "an array of integers as string"} + if got, expected := tbl.ColumnDefinitions[5], epsilon; got != expected { + t.Errorf("expected column definition %#v, got %#v", expected, got) + } + + // Validate extra column for v1 + if i == 1 { + zeta := metav1beta1.TableColumnDefinition{Name: "Zeta", Type: "integer", Format: "int64", Description: "the zeta field", Priority: 42} + if got, expected := tbl.ColumnDefinitions[6], zeta; got != expected { + t.Errorf("expected column definition %#v, got %#v", expected, got) + } + } + } + if got, expected := len(tbl.Rows), 1; got != expected { + t.Errorf("expected %d rows, got %d", expected, got) + } else if got, expected := len(tbl.Rows[0].Cells), expectColumnNum; got != expected { + t.Errorf("expected %d cells, got %d", expected, got) + } else { + if got, expected := tbl.Rows[0].Cells[0], "foo"; got != expected { + t.Errorf("expected cell[0] to equal %q, got %q", expected, got) + } + if s, ok := tbl.Rows[0].Cells[1].(string); !ok { + t.Errorf("expected cell[1] to be a string, got: %#v", tbl.Rows[0].Cells[1]) + } else { + dur, err := time.ParseDuration(s) + if err != nil { + t.Errorf("expected cell[1] to be a duration: %v", err) + } else if abs(dur.Seconds()) > 30.0 { + t.Errorf("expected cell[1] to be a small age, but got: %v", dur) + } + } + if got, expected := tbl.Rows[0].Cells[2], "foo_123"; got != expected { + t.Errorf("expected cell[2] to equal %q, got %q", expected, got) + } + if got, expected := tbl.Rows[0].Cells[3], int64(10); got != expected { + t.Errorf("expected cell[3] to equal %#v, got %#v", expected, got) + } + if got, expected := tbl.Rows[0].Cells[4], interface{}(nil); got != expected { + t.Errorf("expected cell[4] to equal %#v although the type does not match the column, got %#v", expected, got) + } + if got, expected := tbl.Rows[0].Cells[5], "[1 2 3]"; got != expected { + t.Errorf("expected cell[5] to equal %q, got %q", expected, got) + } + // Validate extra column for v1 + if i == 1 { + if got, expected := tbl.Rows[0].Cells[6], int64(5); got != expected { + t.Errorf("expected cell[6] to equal %q, got %q", expected, got) + } + } + } + } +} + +// TestColumnsPatch tests the case that a CRD was created with no top-level or +// per-version columns. One should be able to PATCH the CRD setting per-version columns. +func TestColumnsPatch(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() + tearDown, config, _, err := fixtures.StartDefaultServer(t) if err != nil { t.Fatal(err) } + defer tearDown() - ret, err := crRestClient.Get(). - Resource(crd.Spec.Names.Plural). - SetHeader("Accept", fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName)). - VersionedParams(&metav1beta1.TableOptions{}, parameterCodec). - Do(). - Get() + apiExtensionClient, err := clientset.NewForConfig(config) if err != nil { - t.Fatalf("failed to list %v resources: %v", gvk, err) + t.Fatal(err) } - tbl, ok := ret.(*metav1beta1.Table) - if !ok { - t.Fatalf("expected metav1beta1.Table, got %T", ret) + dynamicClient, err := dynamic.NewForConfig(config) + if err != nil { + t.Fatal(err) } - t.Logf("%v table list: %#v", gvk, tbl) - if got, expected := len(tbl.ColumnDefinitions), 6; got != expected { - t.Errorf("expected %d headers, got %d", expected, got) - } else { - age := metav1beta1.TableColumnDefinition{Name: "Age", Type: "date", Format: "", Description: "Custom resource definition column (in JSONPath format): .metadata.creationTimestamp", Priority: 0} - if got, expected := tbl.ColumnDefinitions[1], age; got != expected { - t.Errorf("expected column definition %#v, got %#v", expected, got) - } + // CRD with no top-level and per-version columns should be created successfully + crd := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.NamespaceScoped)[0] + crd, err = fixtures.CreateNewCustomResourceDefinition(crd, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } - alpha := metav1beta1.TableColumnDefinition{Name: "Alpha", Type: "string", Format: "", Description: "Custom resource definition column (in JSONPath format): .spec.alpha", Priority: 0} - if got, expected := tbl.ColumnDefinitions[2], alpha; got != expected { - t.Errorf("expected column definition %#v, got %#v", expected, got) - } + // One should be able to patch the CRD to use per-version columns. The top-level columns + // should not be defaulted during creation, and apiserver should not return validation + // error about top-level and per-version columns being mutual exclusive. + patch := []byte(`{"spec":{"versions":[{"name":"v1beta1","served":true,"storage":true,"additionalPrinterColumns":[{"name":"Age","type":"date","JSONPath":".metadata.creationTimestamp"}]},{"name":"v1","served":true,"storage":false,"additionalPrinterColumns":[{"name":"Age2","type":"date","JSONPath":".metadata.creationTimestamp"}]}]}}`) - beta := metav1beta1.TableColumnDefinition{Name: "Beta", Type: "integer", Format: "int64", Description: "the beta field", Priority: 42} - if got, expected := tbl.ColumnDefinitions[3], beta; got != expected { - t.Errorf("expected column definition %#v, got %#v", expected, got) - } + _, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Patch(crd.Name, types.MergePatchType, patch) + if err != nil { + t.Fatal(err) + } - gamma := metav1beta1.TableColumnDefinition{Name: "Gamma", Type: "integer", Description: "a column with wrongly typed values"} - if got, expected := tbl.ColumnDefinitions[4], gamma; got != expected { - t.Errorf("expected column definition %#v, got %#v", expected, got) - } + crd, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + t.Logf("columns crd patched: %#v", crd) +} - epsilon := metav1beta1.TableColumnDefinition{Name: "Epsilon", Type: "string", Description: "an array of integers as string"} - if got, expected := tbl.ColumnDefinitions[5], epsilon; got != expected { - t.Errorf("expected column definition %#v, got %#v", expected, got) - } +// TestPatchCleanTopLevelColumns tests the case that a CRD was created with top-level columns. +// One should be able to PATCH the CRD cleaning the top-level columns and setting per-version +// columns. +func TestPatchCleanTopLevelColumns(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() + tearDown, config, _, err := fixtures.StartDefaultServer(t) + if err != nil { + t.Fatal(err) } - if got, expected := len(tbl.Rows), 1; got != expected { - t.Errorf("expected %d rows, got %d", expected, got) - } else if got, expected := len(tbl.Rows[0].Cells), 6; got != expected { - t.Errorf("expected %d cells, got %d", expected, got) - } else { - if got, expected := tbl.Rows[0].Cells[0], "foo"; got != expected { - t.Errorf("expected cell[0] to equal %q, got %q", expected, got) - } - if s, ok := tbl.Rows[0].Cells[1].(string); !ok { - t.Errorf("expected cell[1] to be a string, got: %#v", tbl.Rows[0].Cells[1]) - } else { - dur, err := time.ParseDuration(s) - if err != nil { - t.Errorf("expected cell[1] to be a duration: %v", err) - } else if abs(dur.Seconds()) > 30.0 { - t.Errorf("expected cell[1] to be a small age, but got: %v", dur) - } - } - if got, expected := tbl.Rows[0].Cells[2], "foo_123"; got != expected { - t.Errorf("expected cell[2] to equal %q, got %q", expected, got) - } - if got, expected := tbl.Rows[0].Cells[3], int64(10); got != expected { - t.Errorf("expected cell[3] to equal %#v, got %#v", expected, got) - } - if got, expected := tbl.Rows[0].Cells[4], interface{}(nil); got != expected { - t.Errorf("expected cell[4] to equal %#v although the type does not match the column, got %#v", expected, got) - } - if got, expected := tbl.Rows[0].Cells[5], "[1 2 3]"; got != expected { - t.Errorf("expected cell[5] to equal %q, got %q", expected, got) - } + defer tearDown() + + apiExtensionClient, err := clientset.NewForConfig(config) + if err != nil { + t.Fatal(err) + } + + dynamicClient, err := dynamic.NewForConfig(config) + if err != nil { + t.Fatal(err) + } + + crd := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.NamespaceScoped)[0] + crd.Spec.AdditionalPrinterColumns = []apiextensionsv1beta1.CustomResourceColumnDefinition{ + {Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"}, + } + crd, err = fixtures.CreateNewCustomResourceDefinition(crd, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + t.Logf("columns crd created: %#v", crd) + + // One should be able to patch the CRD to use per-version columns by cleaning + // the top-level columns. + patch := []byte(`{"spec":{"additionalPrinterColumns":null,"versions":[{"name":"v1beta1","served":true,"storage":true,"additionalPrinterColumns":[{"name":"Age","type":"date","JSONPath":".metadata.creationTimestamp"}]},{"name":"v1","served":true,"storage":false,"additionalPrinterColumns":[{"name":"Age2","type":"date","JSONPath":".metadata.creationTimestamp"}]}]}}`) + + _, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Patch(crd.Name, types.MergePatchType, patch) + if err != nil { + t.Fatal(err) + } + + crd, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{}) + if err != nil { + t.Fatal(err) } + t.Logf("columns crd patched: %#v", crd) } func abs(x float64) float64 { diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/validation_test.go b/staging/src/k8s.io/apiextensions-apiserver/test/integration/validation_test.go index 37f9d09438150..3c3322fcd014e 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/validation_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/validation_test.go @@ -17,6 +17,7 @@ limitations under the License. package integration import ( + "fmt" "strings" "testing" "time" @@ -25,8 +26,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/wait" + utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" "k8s.io/apiextensions-apiserver/test/integration/fixtures" ) @@ -84,64 +88,114 @@ func TestForProperValidationErrors(t *testing.T) { } } -func newNoxuValidationCRD(scope apiextensionsv1beta1.ResourceScope) *apiextensionsv1beta1.CustomResourceDefinition { - return &apiextensionsv1beta1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "noxus.mygroup.example.com"}, - Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ - Group: "mygroup.example.com", - Version: "v1beta1", - Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ - Plural: "noxus", - Singular: "nonenglishnoxu", - Kind: "WishIHadChosenNoxu", - ShortNames: []string{"foo", "bar", "abc", "def"}, - ListKind: "NoxuItemList", +func newNoxuValidationCRDs(scope apiextensionsv1beta1.ResourceScope) []*apiextensionsv1beta1.CustomResourceDefinition { + validationSchema := &apiextensionsv1beta1.JSONSchemaProps{ + Required: []string{"alpha", "beta"}, + AdditionalProperties: &apiextensionsv1beta1.JSONSchemaPropsOrBool{ + Allows: true, + }, + Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ + "alpha": { + Description: "Alpha is an alphanumeric string with underscores", + Type: "string", + Pattern: "^[a-zA-Z0-9_]*$", + }, + "beta": { + Description: "Minimum value of beta is 10", + Type: "number", + Minimum: float64Ptr(10), }, - Scope: apiextensionsv1beta1.NamespaceScoped, - Validation: &apiextensionsv1beta1.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{ - Required: []string{"alpha", "beta"}, - AdditionalProperties: &apiextensionsv1beta1.JSONSchemaPropsOrBool{ - Allows: true, + "gamma": { + Description: "Gamma is restricted to foo, bar and baz", + Type: "string", + Enum: []apiextensionsv1beta1.JSON{ + { + Raw: []byte(`"foo"`), }, - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "alpha": { - Description: "Alpha is an alphanumeric string with underscores", - Type: "string", - Pattern: "^[a-zA-Z0-9_]*$", - }, - "beta": { - Description: "Minimum value of beta is 10", - Type: "number", - Minimum: float64Ptr(10), - }, - "gamma": { - Description: "Gamma is restricted to foo, bar and baz", - Type: "string", - Enum: []apiextensionsv1beta1.JSON{ - { - Raw: []byte(`"foo"`), - }, - { - Raw: []byte(`"bar"`), - }, - { - Raw: []byte(`"baz"`), - }, - }, + { + Raw: []byte(`"bar"`), + }, + { + Raw: []byte(`"baz"`), + }, + }, + }, + "delta": { + Description: "Delta is a string with a maximum length of 5 or a number with a minimum value of 0", + AnyOf: []apiextensionsv1beta1.JSONSchemaProps{ + { + Type: "string", + MaxLength: int64Ptr(5), + }, + { + Type: "number", + Minimum: float64Ptr(0), + }, + }, + }, + }, + } + validationSchemaWithDescription := validationSchema.DeepCopy() + validationSchemaWithDescription.Description = "test" + return []*apiextensionsv1beta1.CustomResourceDefinition{ + { + ObjectMeta: metav1.ObjectMeta{Name: "noxus.mygroup.example.com"}, + Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ + Group: "mygroup.example.com", + Version: "v1beta1", + Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ + Plural: "noxus", + Singular: "nonenglishnoxu", + Kind: "WishIHadChosenNoxu", + ShortNames: []string{"foo", "bar", "abc", "def"}, + ListKind: "NoxuItemList", + }, + Scope: apiextensionsv1beta1.NamespaceScoped, + Validation: &apiextensionsv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: validationSchema, + }, + Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Served: true, + Storage: true, + }, + { + Name: "v1", + Served: true, + Storage: false, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "noxus.mygroup.example.com"}, + Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ + Group: "mygroup.example.com", + Version: "v1beta1", + Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ + Plural: "noxus", + Singular: "nonenglishnoxu", + Kind: "WishIHadChosenNoxu", + ShortNames: []string{"foo", "bar", "abc", "def"}, + ListKind: "NoxuItemList", + }, + Scope: apiextensionsv1beta1.NamespaceScoped, + Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Served: true, + Storage: true, + Schema: &apiextensionsv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: validationSchema, }, - "delta": { - Description: "Delta is a string with a maximum length of 5 or a number with a minimum value of 0", - AnyOf: []apiextensionsv1beta1.JSONSchemaProps{ - { - Type: "string", - MaxLength: int64Ptr(5), - }, - { - Type: "number", - Minimum: float64Ptr(0), - }, - }, + }, + { + Name: "v1", + Served: true, + Storage: false, + Schema: &apiextensionsv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: validationSchemaWithDescription, }, }, }, @@ -168,253 +222,320 @@ func newNoxuValidationInstance(namespace, name string) *unstructured.Unstructure } func TestCustomResourceValidation(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { t.Fatal(err) } defer tearDown() - noxuDefinition := newNoxuValidationCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } + noxuDefinitions := newNoxuValidationCRDs(apiextensionsv1beta1.NamespaceScoped) + for _, noxuDefinition := range noxuDefinitions { + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - _, err = instantiateCustomResource(t, newNoxuValidationInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) + ns := "not-the-default" + for _, v := range noxuDefinition.Spec.Versions { + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + instanceToCreate := newNoxuValidationInstance(ns, "foo") + instanceToCreate.Object["apiVersion"] = fmt.Sprintf("%s/%s", noxuDefinition.Spec.Group, v.Name) + _, err = instantiateVersionedCustomResource(t, instanceToCreate, noxuResourceClient, noxuDefinition, v.Name) + if err != nil { + t.Fatalf("unable to create noxu instance: %v", err) + } + noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}) + } + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } } } func TestCustomResourceUpdateValidation(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { t.Fatal(err) } defer tearDown() - noxuDefinition := newNoxuValidationCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } + noxuDefinitions := newNoxuValidationCRDs(apiextensionsv1beta1.NamespaceScoped) + for _, noxuDefinition := range noxuDefinitions { + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - _, err = instantiateCustomResource(t, newNoxuValidationInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } + ns := "not-the-default" + for _, v := range noxuDefinition.Spec.Versions { + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + instanceToCreate := newNoxuValidationInstance(ns, "foo") + instanceToCreate.Object["apiVersion"] = fmt.Sprintf("%s/%s", noxuDefinition.Spec.Group, v.Name) + _, err = instantiateVersionedCustomResource(t, instanceToCreate, noxuResourceClient, noxuDefinition, v.Name) + if err != nil { + t.Fatalf("unable to create noxu instance: %v", err) + } - gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } + gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } - // invalidate the instance - gottenNoxuInstance.Object = map[string]interface{}{ - "apiVersion": "mygroup.example.com/v1beta1", - "kind": "WishIHadChosenNoxu", - "metadata": map[string]interface{}{ - "namespace": "not-the-default", - "name": "foo", - }, - "gamma": "bar", - "delta": "hello", - } + // invalidate the instance + gottenNoxuInstance.Object = map[string]interface{}{ + "apiVersion": "mygroup.example.com/v1beta1", + "kind": "WishIHadChosenNoxu", + "metadata": map[string]interface{}{ + "namespace": "not-the-default", + "name": "foo", + }, + "gamma": "bar", + "delta": "hello", + } - _, err = noxuResourceClient.Update(gottenNoxuInstance, metav1.UpdateOptions{}) - if err == nil { - t.Fatalf("unexpected non-error: alpha and beta should be present while updating %v", gottenNoxuInstance) + _, err = noxuResourceClient.Update(gottenNoxuInstance, metav1.UpdateOptions{}) + if err == nil { + t.Fatalf("unexpected non-error: alpha and beta should be present while updating %v", gottenNoxuInstance) + } + noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}) + } + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } } } func TestCustomResourceValidationErrors(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { t.Fatal(err) } defer tearDown() - noxuDefinition := newNoxuValidationCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) + noxuDefinitions := newNoxuValidationCRDs(apiextensionsv1beta1.NamespaceScoped) + for _, noxuDefinition := range noxuDefinitions { + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } - tests := []struct { - name string - instanceFn func() *unstructured.Unstructured - expectedError string - }{ - { - name: "bad alpha", - instanceFn: func() *unstructured.Unstructured { - instance := newNoxuValidationInstance(ns, "foo") - instance.Object["alpha"] = "foo_123!" - return instance + ns := "not-the-default" + + tests := []struct { + name string + instanceFn func() *unstructured.Unstructured + expectedError string + }{ + { + name: "bad alpha", + instanceFn: func() *unstructured.Unstructured { + instance := newNoxuValidationInstance(ns, "foo") + instance.Object["alpha"] = "foo_123!" + return instance + }, + expectedError: "alpha in body should match '^[a-zA-Z0-9_]*$'", }, - expectedError: "alpha in body should match '^[a-zA-Z0-9_]*$'", - }, - { - name: "bad beta", - instanceFn: func() *unstructured.Unstructured { - instance := newNoxuValidationInstance(ns, "foo") - instance.Object["beta"] = 5 - return instance + { + name: "bad beta", + instanceFn: func() *unstructured.Unstructured { + instance := newNoxuValidationInstance(ns, "foo") + instance.Object["beta"] = 5 + return instance + }, + expectedError: "beta in body should be greater than or equal to 10", }, - expectedError: "beta in body should be greater than or equal to 10", - }, - { - name: "bad gamma", - instanceFn: func() *unstructured.Unstructured { - instance := newNoxuValidationInstance(ns, "foo") - instance.Object["gamma"] = "qux" - return instance + { + name: "bad gamma", + instanceFn: func() *unstructured.Unstructured { + instance := newNoxuValidationInstance(ns, "foo") + instance.Object["gamma"] = "qux" + return instance + }, + expectedError: "gamma in body should be one of [foo bar baz]", }, - expectedError: "gamma in body should be one of [foo bar baz]", - }, - { - name: "bad delta", - instanceFn: func() *unstructured.Unstructured { - instance := newNoxuValidationInstance(ns, "foo") - instance.Object["delta"] = "foobarbaz" - return instance + { + name: "bad delta", + instanceFn: func() *unstructured.Unstructured { + instance := newNoxuValidationInstance(ns, "foo") + instance.Object["delta"] = "foobarbaz" + return instance + }, + expectedError: "must validate at least one schema (anyOf)\ndelta in body should be at most 5 chars long", }, - expectedError: "must validate at least one schema (anyOf)\ndelta in body should be at most 5 chars long", - }, - { - name: "absent alpha and beta", - instanceFn: func() *unstructured.Unstructured { - instance := newNoxuValidationInstance(ns, "foo") - instance.Object = map[string]interface{}{ - "apiVersion": "mygroup.example.com/v1beta1", - "kind": "WishIHadChosenNoxu", - "metadata": map[string]interface{}{ - "namespace": "not-the-default", - "name": "foo", - }, - "gamma": "bar", - "delta": "hello", - } - return instance + { + name: "absent alpha and beta", + instanceFn: func() *unstructured.Unstructured { + instance := newNoxuValidationInstance(ns, "foo") + instance.Object = map[string]interface{}{ + "apiVersion": "mygroup.example.com/v1beta1", + "kind": "WishIHadChosenNoxu", + "metadata": map[string]interface{}{ + "namespace": "not-the-default", + "name": "foo", + }, + "gamma": "bar", + "delta": "hello", + } + return instance + }, + expectedError: ".alpha in body is required\n.beta in body is required", }, - expectedError: ".alpha in body is required\n.beta in body is required", - }, - } + } - for _, tc := range tests { - _, err := noxuResourceClient.Create(tc.instanceFn(), metav1.CreateOptions{}) - if err == nil { - t.Errorf("%v: expected %v", tc.name, tc.expectedError) - continue + for _, tc := range tests { + for _, v := range noxuDefinition.Spec.Versions { + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + instanceToCreate := tc.instanceFn() + instanceToCreate.Object["apiVersion"] = fmt.Sprintf("%s/%s", noxuDefinition.Spec.Group, v.Name) + _, err := noxuResourceClient.Create(instanceToCreate, metav1.CreateOptions{}) + if err == nil { + t.Errorf("%v: expected %v", tc.name, tc.expectedError) + continue + } + // this only works when status errors contain the expect kind and version, so this effectively tests serializations too + if !strings.Contains(err.Error(), tc.expectedError) { + t.Errorf("%v: expected %v, got %v", tc.name, tc.expectedError, err) + continue + } + } } - // this only works when status errors contain the expect kind and version, so this effectively tests serializations too - if !strings.Contains(err.Error(), tc.expectedError) { - t.Errorf("%v: expected %v, got %v", tc.name, tc.expectedError, err) - continue + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) } } } func TestCRValidationOnCRDUpdate(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { t.Fatal(err) } defer tearDown() - noxuDefinition := newNoxuValidationCRD(apiextensionsv1beta1.NamespaceScoped) + noxuDefinitions := newNoxuValidationCRDs(apiextensionsv1beta1.NamespaceScoped) + for i, noxuDefinition := range noxuDefinitions { + for _, v := range noxuDefinition.Spec.Versions { + // Re-define the CRD to make sure we start with a clean CRD + noxuDefinition := newNoxuValidationCRDs(apiextensionsv1beta1.NamespaceScoped)[i] + validationSchema, err := getSchemaForVersion(noxuDefinition, v.Name) + if err != nil { + t.Fatal(err) + } - // set stricter schema - noxuDefinition.Spec.Validation.OpenAPIV3Schema.Required = []string{"alpha", "beta", "epsilon"} + // set stricter schema + validationSchema.OpenAPIV3Schema.Required = []string{"alpha", "beta", "epsilon"} - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } - ns := "not-the-default" - noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - - // CR is rejected - _, err = instantiateCustomResource(t, newNoxuValidationInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err == nil { - t.Fatalf("unexpected non-error: CR should be rejected") - } + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + ns := "not-the-default" + noxuResourceClient := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name) + instanceToCreate := newNoxuValidationInstance(ns, "foo") + instanceToCreate.Object["apiVersion"] = fmt.Sprintf("%s/%s", noxuDefinition.Spec.Group, v.Name) + + // CR is rejected + _, err = instantiateVersionedCustomResource(t, instanceToCreate, noxuResourceClient, noxuDefinition, v.Name) + if err == nil { + t.Fatalf("unexpected non-error: CR should be rejected") + } - // update the CRD to a less stricter schema - _, err = updateCustomResourceDefinitionWithRetry(apiExtensionClient, "noxus.mygroup.example.com", func(crd *apiextensionsv1beta1.CustomResourceDefinition) { - crd.Spec.Validation.OpenAPIV3Schema.Required = []string{"alpha", "beta"} - }) - if err != nil { - t.Fatal(err) - } + // update the CRD to a less stricter schema + _, err = updateCustomResourceDefinitionWithRetry(apiExtensionClient, "noxus.mygroup.example.com", func(crd *apiextensionsv1beta1.CustomResourceDefinition) { + validationSchema, err := getSchemaForVersion(crd, v.Name) + if err != nil { + t.Fatal(err) + } + validationSchema.OpenAPIV3Schema.Required = []string{"alpha", "beta"} + }) + if err != nil { + t.Fatal(err) + } - // CR is now accepted - err = wait.Poll(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) { - _, err := noxuResourceClient.Create(newNoxuValidationInstance(ns, "foo"), metav1.CreateOptions{}) - if statusError, isStatus := err.(*apierrors.StatusError); isStatus { - if strings.Contains(statusError.Error(), "is invalid") { - return false, nil + // CR is now accepted + err = wait.Poll(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) { + _, err := noxuResourceClient.Create(instanceToCreate, metav1.CreateOptions{}) + if _, isStatus := err.(*apierrors.StatusError); isStatus { + if apierrors.IsInvalid(err) { + return false, nil + } + } + if err != nil { + return false, err + } + return true, nil + }) + if err != nil { + t.Fatal(err) + } + noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}) + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) } } - if err != nil { - return false, err - } - return true, nil - }) - if err != nil { - t.Fatal(err) } } func TestForbiddenFieldsInSchema(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { t.Fatal(err) } defer tearDown() - noxuDefinition := newNoxuValidationCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition.Spec.Validation.OpenAPIV3Schema.AdditionalProperties.Allows = false + noxuDefinitions := newNoxuValidationCRDs(apiextensionsv1beta1.NamespaceScoped) + for i, noxuDefinition := range noxuDefinitions { + for _, v := range noxuDefinition.Spec.Versions { + // Re-define the CRD to make sure we start with a clean CRD + noxuDefinition := newNoxuValidationCRDs(apiextensionsv1beta1.NamespaceScoped)[i] + validationSchema, err := getSchemaForVersion(noxuDefinition, v.Name) + if err != nil { + t.Fatal(err) + } + validationSchema.OpenAPIV3Schema.AdditionalProperties.Allows = false - _, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err == nil { - t.Fatalf("unexpected non-error: additionalProperties cannot be set to false") - } + _, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err == nil { + t.Fatalf("unexpected non-error: additionalProperties cannot be set to false") + } - noxuDefinition.Spec.Validation.OpenAPIV3Schema.Properties["zeta"] = apiextensionsv1beta1.JSONSchemaProps{ - Type: "array", - UniqueItems: true, - } - noxuDefinition.Spec.Validation.OpenAPIV3Schema.AdditionalProperties.Allows = true + validationSchema.OpenAPIV3Schema.Properties["zeta"] = apiextensionsv1beta1.JSONSchemaProps{ + Type: "array", + UniqueItems: true, + } + validationSchema.OpenAPIV3Schema.AdditionalProperties.Allows = true - _, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err == nil { - t.Fatalf("unexpected non-error: uniqueItems cannot be set to true") - } + _, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err == nil { + t.Fatalf("unexpected non-error: uniqueItems cannot be set to true") + } - noxuDefinition.Spec.Validation.OpenAPIV3Schema.Ref = strPtr("#/definition/zeta") - noxuDefinition.Spec.Validation.OpenAPIV3Schema.Properties["zeta"] = apiextensionsv1beta1.JSONSchemaProps{ - Type: "array", - UniqueItems: false, - } + validationSchema.OpenAPIV3Schema.Ref = strPtr("#/definition/zeta") + validationSchema.OpenAPIV3Schema.Properties["zeta"] = apiextensionsv1beta1.JSONSchemaProps{ + Type: "array", + UniqueItems: false, + } - _, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err == nil { - t.Fatal("unexpected non-error: $ref cannot be non-empty string") - } + _, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err == nil { + t.Fatal("unexpected non-error: $ref cannot be non-empty string") + } - noxuDefinition.Spec.Validation.OpenAPIV3Schema.Ref = nil + validationSchema.OpenAPIV3Schema.Ref = nil - noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + if err := fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil { + t.Fatal(err) + } + } } } diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/versioning_test.go b/staging/src/k8s.io/apiextensions-apiserver/test/integration/versioning_test.go index 7d305b081fdde..7a813ab49cf57 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/versioning_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/versioning_test.go @@ -17,14 +17,116 @@ limitations under the License. package integration import ( + "fmt" + "net/http" "reflect" "testing" + "time" + + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apiextensions-apiserver/test/integration/fixtures" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +func TestInternalVersionIsHandlerVersion(t *testing.T) { + tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) + if err != nil { + t.Fatal(err) + } + defer tearDown() + + noxuDefinition := fixtures.NewMultipleVersionNoxuCRD(apiextensionsv1beta1.NamespaceScoped) + + assert.Equal(t, "v1beta1", noxuDefinition.Spec.Versions[0].Name) + assert.Equal(t, "v1beta2", noxuDefinition.Spec.Versions[1].Name) + assert.True(t, noxuDefinition.Spec.Versions[1].Storage) + + noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) + if err != nil { + t.Fatal(err) + } + + ns := "not-the-default" + + noxuNamespacedResourceClientV1beta1 := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, "v1beta1") // use the non-storage version v1beta1 + + t.Logf("Creating foo") + noxuInstanceToCreate := fixtures.NewNoxuInstance(ns, "foo") + _, err = noxuNamespacedResourceClientV1beta1.Create(noxuInstanceToCreate, metav1.CreateOptions{}) + if err != nil { + t.Fatal(err) + } + + // update validation via update because the cache priming in CreateNewCustomResourceDefinition will fail otherwise + t.Logf("Updating CRD to validate apiVersion") + noxuDefinition, err = updateCustomResourceDefinitionWithRetry(apiExtensionClient, noxuDefinition.Name, func(crd *apiextensionsv1beta1.CustomResourceDefinition) { + crd.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{ + Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ + "apiVersion": { + Pattern: "^mygroup.example.com/v1beta1$", // this means we can only patch via the v1beta1 handler version + }, + }, + Required: []string{"apiVersion"}, + }, + } + }) + assert.NoError(t, err) + + time.Sleep(time.Second) + + // patches via handler version v1beta1 should succeed (validation allows that API version) + { + t.Logf("patch of handler version v1beta1 (non-storage version) should succeed") + i := 0 + err = wait.PollImmediate(time.Millisecond*100, wait.ForeverTestTimeout, func() (bool, error) { + patch := []byte(fmt.Sprintf(`{"i": %d}`, i)) + i++ + + _, err := noxuNamespacedResourceClientV1beta1.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}) + if err != nil { + // work around "grpc: the client connection is closing" error + // TODO: fix the grpc error + if err, ok := err.(*errors.StatusError); ok && err.Status().Code == http.StatusInternalServerError { + return false, nil + } + return false, err + } + return true, nil + }) + assert.NoError(t, err) + } + + // patches via handler version matching storage version should fail (validation does not allow that API version) + { + t.Logf("patch of handler version v1beta2 (storage version) should fail") + i := 0 + noxuNamespacedResourceClientV1beta2 := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, "v1beta2") // use the storage version v1beta2 + err = wait.PollImmediate(time.Millisecond*100, wait.ForeverTestTimeout, func() (bool, error) { + patch := []byte(fmt.Sprintf(`{"i": %d}`, i)) + i++ + + _, err := noxuNamespacedResourceClientV1beta2.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{}) + assert.NotNil(t, err) + + // work around "grpc: the client connection is closing" error + // TODO: fix the grpc error + if err, ok := err.(*errors.StatusError); ok && err.Status().Code == http.StatusInternalServerError { + return false, nil + } + + assert.Contains(t, err.Error(), "apiVersion") + return true, nil + }) + assert.NoError(t, err) + } +} + func TestVersionedNamspacedScopedCRD(t *testing.T) { tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) if err != nil { diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/yaml_test.go b/staging/src/k8s.io/apiextensions-apiserver/test/integration/yaml_test.go index 45e5176b00050..1d3154d997f72 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/yaml_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/yaml_test.go @@ -27,10 +27,13 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/types" + utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" "k8s.io/client-go/dynamic" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" "k8s.io/apiextensions-apiserver/test/integration/fixtures" ) @@ -354,6 +357,7 @@ values: } func TestYAMLSubresource(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceWebhookConversion, true)() tearDown, config, _, err := fixtures.StartDefaultServer(t) if err != nil { t.Fatal(err) @@ -369,7 +373,7 @@ func TestYAMLSubresource(t *testing.T) { t.Fatal(err) } - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.ClusterScoped) + noxuDefinition := NewNoxuSubresourcesCRDs(apiextensionsv1beta1.ClusterScoped)[0] noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) if err != nil { t.Fatal(err) diff --git a/staging/src/k8s.io/apimachinery/Godeps/Godeps.json b/staging/src/k8s.io/apimachinery/Godeps/Godeps.json index cb500974baacb..4add6c378dbf5 100644 --- a/staging/src/k8s.io/apimachinery/Godeps/Godeps.json +++ b/staging/src/k8s.io/apimachinery/Godeps/Godeps.json @@ -128,31 +128,31 @@ }, { "ImportPath": "golang.org/x/net/html", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/html/atom", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/websocket", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/text/secure/bidirule", @@ -180,7 +180,7 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" } ] } diff --git a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go index bcc032df9dd6b..e736a9861400c 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" "net/http" + "reflect" "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -82,7 +83,20 @@ func (u *UnexpectedObjectError) Error() string { func FromObject(obj runtime.Object) error { switch t := obj.(type) { case *metav1.Status: - return &StatusError{*t} + return &StatusError{ErrStatus: *t} + case runtime.Unstructured: + var status metav1.Status + obj := t.UnstructuredContent() + if !reflect.DeepEqual(obj["kind"], "Status") { + break + } + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(t.UnstructuredContent(), &status); err != nil { + return err + } + if status.APIVersion != "v1" && status.APIVersion != "meta.k8s.io/v1" { + break + } + return &StatusError{ErrStatus: status} } return &UnexpectedObjectError{obj} } diff --git a/staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper/test_restmapper.go b/staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper/test_restmapper.go index a08b42b826ec9..ede58c254b7ee 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper/test_restmapper.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper/test_restmapper.go @@ -24,7 +24,7 @@ import ( ) // TestOnlyStaticRESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order: -// 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy +// 1. legacy kube group preferred version, extensions preferred version, metrics preferred version, legacy // kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version, // all other groups alphabetical. // TODO callers of this method should be updated to build their own specific restmapper based on their scheme for their tests diff --git a/staging/src/k8s.io/apimachinery/pkg/api/resource/generated.proto b/staging/src/k8s.io/apimachinery/pkg/api/resource/generated.proto index 2c615d51bf20b..acc9044452287 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/resource/generated.proto +++ b/staging/src/k8s.io/apimachinery/pkg/api/resource/generated.proto @@ -27,9 +27,9 @@ option go_package = "resource"; // Quantity is a fixed-point representation of a number. // It provides convenient marshaling/unmarshaling in JSON and YAML, // in addition to String() and Int64() accessors. -// +// // The serialization format is: -// +// // ::= // (Note that may be empty, from the "" case in .) // ::= 0 | 1 | ... | 9 @@ -43,16 +43,16 @@ option go_package = "resource"; // ::= m | "" | k | M | G | T | P | E // (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.) // ::= "e" | "E" -// +// // No matter which of the three exponent forms is used, no quantity may represent // a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal // places. Numbers larger or more precise will be capped or rounded up. // (E.g.: 0.1m will rounded up to 1m.) // This may be extended in the future if we require larger or smaller quantities. -// +// // When a Quantity is parsed from a string, it will remember the type of suffix // it had, and will use the same type again when it is serialized. -// +// // Before serializing, Quantity will be put in "canonical form". // This means that Exponent/suffix will be adjusted up or down (with a // corresponding increase or decrease in Mantissa) such that: @@ -60,22 +60,22 @@ option go_package = "resource"; // b. No fractional digits will be emitted // c. The exponent (or suffix) is as large as possible. // The sign will be omitted unless the number is negative. -// +// // Examples: // 1.5 will be serialized as "1500m" // 1.5Gi will be serialized as "1536Mi" -// +// // Note that the quantity will NEVER be internally represented by a // floating point number. That is the whole point of this exercise. -// +// // Non-canonical values will still parse as long as they are well formed, // but will be re-emitted in their canonical form. (So always use canonical // form, or don't diff.) -// +// // This format is intended to make it difficult to use these numbers without // writing some sort of special handling code in the hopes that that will // cause implementors to also use a fixed point implementation. -// +// // +protobuf=true // +protobuf.embed=string // +protobuf.options.marshal=false diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/OWNERS b/staging/src/k8s.io/apimachinery/pkg/apis/OWNERS new file mode 100644 index 0000000000000..bae178f8175ea --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/apis/OWNERS @@ -0,0 +1,9 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto index eb3237f2b7179..989f076a1031d 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto @@ -107,7 +107,7 @@ message APIResourceList { // APIVersions lists the versions that are available, to allow clients to // discover the API at /api, which is the root path of the legacy v1 API. -// +// // +protobuf.options.(gogoproto.goproto_stringer)=false // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object message APIVersions { @@ -211,7 +211,7 @@ message GetOptions { // GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying // concepts during lookup stages without having partially valid types -// +// // +protobuf.options.(gogoproto.goproto_stringer)=false message GroupKind { optional string group = 1; @@ -221,7 +221,7 @@ message GroupKind { // GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying // concepts during lookup stages without having partially valid types -// +// // +protobuf.options.(gogoproto.goproto_stringer)=false message GroupResource { optional string group = 1; @@ -230,7 +230,7 @@ message GroupResource { } // GroupVersion contains the "group" and the "version", which uniquely identifies the API. -// +// // +protobuf.options.(gogoproto.goproto_stringer)=false message GroupVersion { optional string group = 1; @@ -251,7 +251,7 @@ message GroupVersionForDiscovery { // GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion // to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling -// +// // +protobuf.options.(gogoproto.goproto_stringer)=false message GroupVersionKind { optional string group = 1; @@ -263,7 +263,7 @@ message GroupVersionKind { // GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion // to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling -// +// // +protobuf.options.(gogoproto.goproto_stringer)=false message GroupVersionResource { optional string group = 1; @@ -411,7 +411,7 @@ message ListOptions { // more results are available. Servers may choose not to support the limit argument and will return // all of the available results. If limit is specified and the continue field is empty, clients may // assume that no more results are available. This field is not supported if watch is true. - // + // // The server guarantees that the objects returned when using continue will be identical to issuing // a single list call without a limit - that is, no objects created, modified, or deleted after the // first request is issued will be included in any subsequent continued requests. This is sometimes @@ -432,14 +432,14 @@ message ListOptions { // a list starting from the next key, but from the latest snapshot, which is inconsistent from the // previous list results - objects that are created, modified, or deleted after the first list request // will be included in the response, as long as their keys are after the "next key". - // + // // This field is not supported when watch is true. Clients may start a watch from the last // resourceVersion value returned by the server and not miss any modifications. optional string continue = 8; } // MicroTime is version of Time with microsecond level precision. -// +// // +protobuf.options.marshal=false // +protobuf.as=Timestamp // +protobuf.options.(gogoproto.goproto_stringer)=false @@ -475,12 +475,12 @@ message ObjectMeta { // The provided value has the same validation rules as the Name field, // and may be truncated by the length of the suffix required to make the value // unique on the server. - // + // // If this field is specified and the generated name exists, the server will // NOT return a 409 - instead, it will either return 201 Created or 500 with Reason // ServerTimeout indicating a unique name could not be found in the time allotted, and the client // should retry (optionally after the time indicated in the Retry-After header). - // + // // Applied only if Name is not specified. // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency // +optional @@ -490,7 +490,7 @@ message ObjectMeta { // equivalent to the "default" namespace, but "default" is the canonical representation. // Not all objects are required to be scoped to a namespace - the value of this field for // those objects will be empty. - // + // // Must be a DNS_LABEL. // Cannot be updated. // More info: http://kubernetes.io/docs/user-guide/namespaces @@ -506,7 +506,7 @@ message ObjectMeta { // UID is the unique in time and space value for this object. It is typically generated by // the server on successful creation of a resource and is not allowed to change on PUT // operations. - // + // // Populated by the system. // Read-only. // More info: http://kubernetes.io/docs/user-guide/identifiers#uids @@ -518,7 +518,7 @@ message ObjectMeta { // concurrency, change detection, and the watch operation on a resource or set of resources. // Clients must treat these values as opaque and passed unmodified back to the server. // They may only be valid for a particular resource or set of resources. - // + // // Populated by the system. // Read-only. // Value must be treated as opaque by clients and . @@ -534,7 +534,7 @@ message ObjectMeta { // CreationTimestamp is a timestamp representing the server time when this object was // created. It is not guaranteed to be set in happens-before order across separate operations. // Clients may not set this value. It is represented in RFC3339 form and is in UTC. - // + // // Populated by the system. // Read-only. // Null for lists. @@ -556,7 +556,7 @@ message ObjectMeta { // exist after this timestamp, until an administrator or automated process can determine the // resource is fully terminated. // If not set, graceful deletion of the object has not been requested. - // + // // Populated by the system when a graceful deletion is requested. // Read-only. // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata @@ -598,7 +598,7 @@ message ObjectMeta { // this object has been completely initialized. Otherwise, the object is considered uninitialized // and is hidden (in list/watch and get calls) from clients that haven't explicitly asked to // observe uninitialized objects. - // + // // When an object is created, the system will populate this list with the current set of initializers. // Only privileged users may set or modify this list. Once it is empty, it may not be modified further // by any user. @@ -620,8 +620,8 @@ message ObjectMeta { } // OwnerReference contains enough information to let you identify an owning -// object. Currently, an owning object must be in the same namespace, so there -// is no namespace field. +// object. An owning object must be in the same namespace as the dependent, or +// be cluster-scoped, so there is no namespace field. message OwnerReference { // API version of the referent. optional string apiVersion = 5; @@ -734,7 +734,7 @@ message StatusCause { // Arrays are zero-indexed. Fields may appear more than once in an array of // causes due to fields having multiple errors. // Optional. - // + // // Examples: // "name" - the field "name" on the current resource // "items[0].name" - the field "name" on the first array entry in "items" @@ -785,7 +785,7 @@ message StatusDetails { // Time is a wrapper around time.Time which supports correct // marshaling to YAML and JSON. Wrappers are provided for many // of the factory methods that the time package offers. -// +// // +protobuf.options.marshal=false // +protobuf.as=Timestamp // +protobuf.options.(gogoproto.goproto_stringer)=false @@ -821,7 +821,7 @@ message Timestamp { // TypeMeta describes an individual object in an API response or request // with strings representing the type of the object and its API schema version. // Structures that are versioned or persisted should inline TypeMeta. -// +// // +k8s:deepcopy-gen=false message TypeMeta { // Kind is a string value representing the REST resource this object represents. @@ -852,7 +852,7 @@ message UpdateOptions { } // Verbs masks the value so protobuf can generate -// +// // +protobuf.nullable=true // +protobuf.options.(gogoproto.goproto_stringer)=false message Verbs { @@ -862,7 +862,7 @@ message Verbs { } // Event represents a single event to a watched resource. -// +// // +protobuf=true // +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index 4d3a55d716974..8f488ba7ea4df 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -286,8 +286,8 @@ const ( ) // OwnerReference contains enough information to let you identify an owning -// object. Currently, an owning object must be in the same namespace, so there -// is no namespace field. +// object. An owning object must be in the same namespace as the dependent, or +// be cluster-scoped, so there is no namespace field. type OwnerReference struct { // API version of the referent. APIVersion string `json:"apiVersion" protobuf:"bytes,5,opt,name=apiVersion"` diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go index 35e800f8a4889..679e709e8e39c 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go @@ -240,7 +240,7 @@ func (ObjectMeta) SwaggerDoc() map[string]string { } var map_OwnerReference = map[string]string{ - "": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.", + "": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "apiVersion": "API version of the referent.", "kind": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", "name": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names", diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/generated.proto b/staging/src/k8s.io/apimachinery/pkg/runtime/generated.proto index fb61ac96a9300..0e212ec941fff 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/generated.proto +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/generated.proto @@ -25,11 +25,11 @@ package k8s.io.apimachinery.pkg.runtime; option go_package = "runtime"; // RawExtension is used to hold extensions in external versions. -// +// // To use this, make a field which has RawExtension as its type in your external, versioned // struct, and Object in your internal struct. You also need to register your // various plugin types. -// +// // // Internal package: // type MyAPIObject struct { // runtime.TypeMeta `json:",inline"` @@ -38,7 +38,7 @@ option go_package = "runtime"; // type PluginA struct { // AOption string `json:"aOption"` // } -// +// // // External package: // type MyAPIObject struct { // runtime.TypeMeta `json:",inline"` @@ -47,7 +47,7 @@ option go_package = "runtime"; // type PluginA struct { // AOption string `json:"aOption"` // } -// +// // // On the wire, the JSON will look something like this: // { // "kind":"MyAPIObject", @@ -57,7 +57,7 @@ option go_package = "runtime"; // "aOption":"foo", // }, // } -// +// // So what happens? Decode first uses json or yaml to unmarshal the serialized data into // your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. // The next step is to copy (using pkg/conversion) into the internal struct. The runtime @@ -65,13 +65,13 @@ option go_package = "runtime"; // JSON stored in RawExtension, turning it into the correct object type, and storing it // in the Object. (TODO: In the case where the object is of an unknown type, a // runtime.Unknown object will be created and stored.) -// +// // +k8s:deepcopy-gen=true // +protobuf=true // +k8s:openapi-gen=true message RawExtension { // Raw is the underlying serialization of this object. - // + // // TODO: Determine how to detect ContentType and ContentEncoding of 'Raw' data. optional bytes raw = 1; } @@ -83,10 +83,10 @@ message RawExtension { // ... // other fields // } // func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind -// +// // TypeMeta is provided here for convenience. You may use it directly from this package or define // your own with the same fields. -// +// // +k8s:deepcopy-gen=false // +protobuf=true // +k8s:openapi-gen=true @@ -103,7 +103,7 @@ message TypeMeta { // TypeMeta features-- kind, version, etc. // TODO: Make this object have easy access to field based accessors and settors for // metadata and field mutatation. -// +// // +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +protobuf=true diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go index a5ae3ac4bb7f7..00184710760b6 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go @@ -18,6 +18,7 @@ package versioning import ( "io" + "reflect" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -90,7 +91,16 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru into = versioned.Last() } - obj, gvk, err := c.decoder.Decode(data, defaultGVK, into) + // If the into object is unstructured and expresses an opinion about its group/version, + // create a new instance of the type so we always exercise the conversion path (skips short-circuiting on `into == obj`) + decodeInto := into + if into != nil { + if _, ok := into.(runtime.Unstructured); ok && !into.GetObjectKind().GroupVersionKind().GroupVersion().Empty() { + decodeInto = reflect.New(reflect.TypeOf(into).Elem()).Interface().(runtime.Object) + } + } + + obj, gvk, err := c.decoder.Decode(data, defaultGVK, decodeInto) if err != nil { return nil, gvk, err } diff --git a/staging/src/k8s.io/apimachinery/pkg/util/intstr/generated.proto b/staging/src/k8s.io/apimachinery/pkg/util/intstr/generated.proto index 1c3ec732e7c3c..e79fb9e57266b 100644 --- a/staging/src/k8s.io/apimachinery/pkg/util/intstr/generated.proto +++ b/staging/src/k8s.io/apimachinery/pkg/util/intstr/generated.proto @@ -29,7 +29,7 @@ option go_package = "intstr"; // inner type. This allows you to have, for example, a JSON field that can // accept a name or number. // TODO: Rename to Int32OrString -// +// // +protobuf=true // +protobuf.options.(gogoproto.goproto_stringer)=false // +k8s:openapi-gen=true diff --git a/staging/src/k8s.io/apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiserver/Godeps/Godeps.json index 55373dcb56f6c..200da2d902d85 100644 --- a/staging/src/k8s.io/apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiserver/Godeps/Godeps.json @@ -40,295 +40,295 @@ }, { "ImportPath": "github.com/coreos/etcd/alarm", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/auth", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/client", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/concurrency", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/namespace", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3/naming", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/compactor", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/discovery", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/embed", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/error", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/etcdhttp", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2v3", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3client", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/auth", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb/gw", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/membership", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/stats", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/integration", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease/leasehttp", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/lease/leasepb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc/backend", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/adt", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/contention", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/cors", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/cpuutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/crc", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/debugutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/httputil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/idutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/ioutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/logutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/netutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/pbutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/runtime", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/schedule", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/srv", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/testutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/wait", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/adapter", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/cache", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/raft", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/raft/raftpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/rafthttp", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/snap", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/snap/snappb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/store", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/version", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/wal", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/wal/walpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/go-oidc", @@ -336,19 +336,19 @@ }, { "ImportPath": "github.com/coreos/go-semver/semver", - "Rev": "568e959cd89871e61434c1143528d9162da89ef2" + "Rev": "e214231b295a8ea9479f11b70b35d5acf3556d9b" }, { "ImportPath": "github.com/coreos/go-systemd/daemon", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/coreos/go-systemd/journal", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/coreos/pkg/capnslog", - "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" + "Rev": "97fdf19511ea361ae1c100dd393cc47f8dcfa1e1" }, { "ImportPath": "github.com/davecgh/go-spew/spew", @@ -392,19 +392,19 @@ }, { "ImportPath": "github.com/go-openapi/jsonpointer", - "Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98" + "Rev": "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004" }, { "ImportPath": "github.com/go-openapi/jsonreference", - "Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272" + "Rev": "8483a886a90412cd6858df4ea3483dce9c8e35a3" }, { "ImportPath": "github.com/go-openapi/spec", - "Rev": "1de3e0542de65ad8d75452a595886fdd0befb363" + "Rev": "5bae59e25b21498baea7f9d46e9c147ec106a42e" }, { "ImportPath": "github.com/go-openapi/swag", - "Rev": "f3f9494671f93fcff853e3c6e9e948b3eb71e590" + "Rev": "5899d5c5e619fda5fa86e14795a835f473ca284c" }, { "ImportPath": "github.com/gogo/protobuf/gogoproto", @@ -490,6 +490,10 @@ "ImportPath": "github.com/gregjones/httpcache/diskcache", "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" }, + { + "ImportPath": "github.com/grpc-ecosystem/go-grpc-middleware", + "Rev": "498ae206fc3cfe81cd82e48c1d4354026fa5f9ec" + }, { "ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus", "Rev": "2500245aa6110c562d17020fb31a2c133d737799" @@ -634,6 +638,38 @@ "ImportPath": "github.com/xiang90/probing", "Rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2" }, + { + "ImportPath": "go.uber.org/atomic", + "Rev": "8dc6146f7569370a472715e178d8ae31172ee6da" + }, + { + "ImportPath": "go.uber.org/multierr", + "Rev": "ddea229ff1dff9e6fe8a6c0344ac73b09e81fce5" + }, + { + "ImportPath": "go.uber.org/zap", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/buffer", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/bufferpool", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/color", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/internal/exit", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, + { + "ImportPath": "go.uber.org/zap/zapcore", + "Rev": "67bc79d13d155c02fd008f721863ff8cc5f30659" + }, { "ImportPath": "golang.org/x/crypto/bcrypt", "Rev": "de0752318171da717af4ce24d0a2e8626afaeb11" @@ -680,35 +716,35 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/internal/timeseries", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/trace", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/websocket", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -1884,28 +1920,32 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/client-go/discovery", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/client-go/dynamic", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/client-go/informers", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/apiserver/pkg/apis/OWNERS b/staging/src/k8s.io/apiserver/pkg/apis/OWNERS new file mode 100644 index 0000000000000..bae178f8175ea --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/OWNERS @@ -0,0 +1,9 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/OWNERS b/staging/src/k8s.io/apiserver/pkg/apis/audit/OWNERS new file mode 100644 index 0000000000000..8389778900fe4 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/OWNERS @@ -0,0 +1,7 @@ +# approval on api packages bubbles to api-approvers +reviewers: +- sig-auth-audit-approvers +- sig-auth-audit-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1/generated.proto b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1/generated.proto index 4baad752efe51..c7242222c9461 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1/generated.proto +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1/generated.proto @@ -121,17 +121,17 @@ message GroupResources { optional string group = 1; // Resources is a list of resources this rule applies to. - // + // // For example: // 'pods' matches pods. // 'pods/log' matches the log subresource of pods. // '*' matches all resources and their subresources. // 'pods/*' matches all subresources of pods. // '*/scale' matches all scale subresources. - // + // // If wildcard is present, the validation rule will ensure resources do not // overlap with each other. - // + // // An empty list implies all resources and subresources in this API groups apply. // +optional repeated string resources = 2; diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/generated.proto b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/generated.proto index 507f5889b73e6..2a0773d1967cb 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/generated.proto +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/generated.proto @@ -128,17 +128,17 @@ message GroupResources { optional string group = 1; // Resources is a list of resources this rule applies to. - // + // // For example: // 'pods' matches pods. // 'pods/log' matches the log subresource of pods. // '*' matches all resources and their subresources. // 'pods/*' matches all subresources of pods. // '*/scale' matches all scale subresources. - // + // // If wildcard is present, the validation rule will ensure resources do not // overlap with each other. - // + // // An empty list implies all resources and subresources in this API groups apply. // +optional repeated string resources = 2; diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1beta1/generated.proto b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1beta1/generated.proto index 2ea4c6a605926..23ed8910aa845 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1beta1/generated.proto +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1beta1/generated.proto @@ -131,17 +131,17 @@ message GroupResources { optional string group = 1; // Resources is a list of resources this rule applies to. - // + // // For example: // 'pods' matches pods. // 'pods/log' matches the log subresource of pods. // '*' matches all resources and their subresources. // 'pods/*' matches all subresources of pods. // '*/scale' matches all scale subresources. - // + // // If wildcard is present, the validation rule will ensure resources do not // overlap with each other. - // + // // An empty list implies all resources and subresources in this API groups apply. // +optional repeated string resources = 2; diff --git a/staging/src/k8s.io/apiserver/pkg/apis/config/OWNERS b/staging/src/k8s.io/apiserver/pkg/apis/config/OWNERS deleted file mode 100644 index 2f7b10df4b902..0000000000000 --- a/staging/src/k8s.io/apiserver/pkg/apis/config/OWNERS +++ /dev/null @@ -1,7 +0,0 @@ -approvers: -- api-approvers -- sttts -- luxas -reviewers: -- api-reviewers -- hanxiaoshuai diff --git a/staging/src/k8s.io/apiserver/pkg/audit/OWNERS b/staging/src/k8s.io/apiserver/pkg/audit/OWNERS new file mode 100644 index 0000000000000..178ce84a5ce3e --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/audit/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-audit-approvers +reviewers: +- sig-auth-audit-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/OWNERS b/staging/src/k8s.io/apiserver/pkg/authentication/OWNERS new file mode 100644 index 0000000000000..c607d2aa8c5fe --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/authentication/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers +reviewers: +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/BUILD b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/BUILD index 1d25f33a21a37..a8a5395dc923a 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/BUILD @@ -5,7 +5,8 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ - "helpers.go", + "audagnostic.go", + "audiences.go", "interfaces.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/authentication/authenticator", @@ -28,6 +29,13 @@ filegroup( go_test( name = "go_default_test", - srcs = ["helpers_test.go"], + srcs = [ + "audagnostic_test.go", + "audiences_test.go", + ], embed = [":go_default_library"], + deps = [ + "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", + ], ) diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audagnostic.go b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audagnostic.go new file mode 100644 index 0000000000000..bcf7eb4bc9d07 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audagnostic.go @@ -0,0 +1,90 @@ +/* +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 authenticator + +import ( + "context" + "fmt" + "net/http" +) + +func authenticate(ctx context.Context, implicitAuds Audiences, authenticate func() (*Response, bool, error)) (*Response, bool, error) { + targetAuds, ok := AudiencesFrom(ctx) + // We can remove this once api audiences is never empty. That will probably + // be N releases after TokenRequest is GA. + if !ok { + return authenticate() + } + auds := implicitAuds.Intersect(targetAuds) + if len(auds) == 0 { + return nil, false, nil + } + resp, ok, err := authenticate() + if err != nil || !ok { + return nil, false, err + } + if len(resp.Audiences) > 0 { + // maybe the authenticator was audience aware after all. + return nil, false, fmt.Errorf("audience agnostic authenticator wrapped an authenticator that returned audiences: %q", resp.Audiences) + } + resp.Audiences = auds + return resp, true, nil +} + +type audAgnosticRequestAuthenticator struct { + implicit Audiences + delegate Request +} + +var _ = Request(&audAgnosticRequestAuthenticator{}) + +func (a *audAgnosticRequestAuthenticator) AuthenticateRequest(req *http.Request) (*Response, bool, error) { + return authenticate(req.Context(), a.implicit, func() (*Response, bool, error) { + return a.delegate.AuthenticateRequest(req) + }) +} + +// WrapAudienceAgnosticRequest wraps an audience agnostic request authenticator +// to restrict its accepted audiences to a set of implicit audiences. +func WrapAudienceAgnosticRequest(implicit Audiences, delegate Request) Request { + return &audAgnosticRequestAuthenticator{ + implicit: implicit, + delegate: delegate, + } +} + +type audAgnosticTokenAuthenticator struct { + implicit Audiences + delegate Token +} + +var _ = Token(&audAgnosticTokenAuthenticator{}) + +func (a *audAgnosticTokenAuthenticator) AuthenticateToken(ctx context.Context, tok string) (*Response, bool, error) { + return authenticate(ctx, a.implicit, func() (*Response, bool, error) { + return a.delegate.AuthenticateToken(ctx, tok) + }) +} + +// WrapAudienceAgnosticToken wraps an audience agnostic token authenticator to +// restrict its accepted audiences to a set of implicit audiences. +func WrapAudienceAgnosticToken(implicit Audiences, delegate Token) Token { + return &audAgnosticTokenAuthenticator{ + implicit: implicit, + delegate: delegate, + } +} diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audagnostic_test.go b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audagnostic_test.go new file mode 100644 index 0000000000000..0152b9a6e389b --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audagnostic_test.go @@ -0,0 +1,229 @@ +/* +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 authenticator + +import ( + "context" + "errors" + "fmt" + "reflect" + "testing" + + "k8s.io/apimachinery/pkg/util/diff" + "k8s.io/apiserver/pkg/authentication/user" +) + +func TestAuthenticate(t *testing.T) { + type treq struct { + resp *Response + authenticated bool + err error + + wantResp *Response + wantAuthenticated bool + wantErr bool + } + type taudcfg struct { + auds Audiences + implicitAuds Audiences + } + cs := []struct { + name string + + taudcfgs []taudcfg + treqs []treq + }{ + { + name: "good audience", + + taudcfgs: []taudcfg{ + { + implicitAuds: Audiences{"api"}, + auds: Audiences{"api"}, + }, + { + implicitAuds: Audiences{"api", "other"}, + auds: Audiences{"api"}, + }, + { + implicitAuds: Audiences{"api"}, + auds: Audiences{"api", "other"}, + }, + { + implicitAuds: Audiences{"api", "other"}, + auds: Audiences{"api", "other_other"}, + }, + }, + + treqs: []treq{ + { + resp: &Response{ + User: &user.DefaultInfo{ + Name: "test_user", + }, + }, + authenticated: true, + + wantResp: &Response{ + User: &user.DefaultInfo{ + Name: "test_user", + }, + Audiences: Audiences{"api"}, + }, + wantAuthenticated: true, + }, + { + err: errors.New("uhoh"), + wantErr: true, + }, + { + authenticated: false, + wantAuthenticated: false, + }, + }, + }, + { + name: "multiple good audiences", + + taudcfgs: []taudcfg{ + { + implicitAuds: Audiences{"api", "other_api"}, + auds: Audiences{"api", "other_api"}, + }, + { + implicitAuds: Audiences{"api", "other_api", "other"}, + auds: Audiences{"api", "other_api"}, + }, + { + implicitAuds: Audiences{"api", "other_api"}, + auds: Audiences{"api", "other_api", "other"}, + }, + { + implicitAuds: Audiences{"api", "other_api", "other"}, + auds: Audiences{"api", "other_api", "other_other"}, + }, + }, + + treqs: []treq{ + { + resp: &Response{ + User: &user.DefaultInfo{ + Name: "test_user", + }, + }, + authenticated: true, + + wantResp: &Response{ + User: &user.DefaultInfo{ + Name: "test_user", + }, + Audiences: Audiences{"api", "other_api"}, + }, + wantAuthenticated: true, + }, + { + err: errors.New("uhoh"), + + wantErr: true, + }, + { + authenticated: false, + + wantAuthenticated: false, + }, + }, + }, + { + name: "bad audience(s)", + + taudcfgs: []taudcfg{ + { + implicitAuds: Audiences{"api"}, + auds: Audiences{"other_api"}, + }, + { + implicitAuds: Audiences{}, + auds: Audiences{"other_api"}, + }, + { + implicitAuds: Audiences{"api"}, + auds: Audiences{}, + }, + { + implicitAuds: Audiences{"api", "other"}, + auds: Audiences{}, + }, + { + implicitAuds: Audiences{}, + auds: Audiences{"api", "other"}, + }, + }, + + treqs: []treq{ + { + resp: &Response{ + User: &user.DefaultInfo{ + Name: "test_user", + }, + }, + authenticated: true, + + wantAuthenticated: false, + }, + { + err: errors.New("uhoh"), + + wantAuthenticated: false, + }, + { + authenticated: false, + + wantAuthenticated: false, + }, + }, + }, + } + + for _, c := range cs { + t.Run(c.name, func(t *testing.T) { + for _, taudcfg := range c.taudcfgs { + for _, treq := range c.treqs { + t.Run(fmt.Sprintf("auds=%q,implicit=%q", taudcfg.auds, taudcfg.implicitAuds), func(t *testing.T) { + ctx := context.Background() + ctx = WithAudiences(ctx, taudcfg.auds) + resp, ok, err := authenticate(ctx, taudcfg.implicitAuds, func() (*Response, bool, error) { + if treq.resp != nil { + resp := *treq.resp + return &resp, treq.authenticated, treq.err + } + return nil, treq.authenticated, treq.err + }) + if got, want := (err != nil), treq.wantErr; got != want { + t.Errorf("Unexpected error. got=%v, want=%v, err=%v", got, want, err) + } + if got, want := ok, treq.wantAuthenticated; got != want { + t.Errorf("Unexpected authentication. got=%v, want=%v", got, want) + } + if got, want := resp, treq.wantResp; !reflect.DeepEqual(got, want) { + t.Errorf("Unexpected response. diff:\n%v", diff.ObjectGoPrintDiff(got, want)) + } + }) + } + } + }) + } +} diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/helpers.go b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audiences.go similarity index 65% rename from staging/src/k8s.io/apiserver/pkg/authentication/authenticator/helpers.go rename to staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audiences.go index f2aa9b0d7ee07..2a3a918896d9b 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/helpers.go +++ b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audiences.go @@ -16,9 +16,30 @@ limitations under the License. package authenticator +import "context" + // Audiences is a container for the Audiences of a token. type Audiences []string +// The key type is unexported to prevent collisions +type key int + +const ( + // audiencesKey is the context key for request audiences. + audiencesKey key = iota +) + +// WithAudiences returns a context that stores a request's expected audiences. +func WithAudiences(ctx context.Context, auds Audiences) context.Context { + return context.WithValue(ctx, audiencesKey, auds) +} + +// AudiencesFrom returns a request's expected audiences stored in the request context. +func AudiencesFrom(ctx context.Context) (Audiences, bool) { + auds, ok := ctx.Value(audiencesKey).(Audiences) + return auds, ok +} + // Has checks if Audiences contains a specific audiences. func (a Audiences) Has(taud string) bool { for _, aud := range a { diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/helpers_test.go b/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audiences_test.go similarity index 100% rename from staging/src/k8s.io/apiserver/pkg/authentication/authenticator/helpers_test.go rename to staging/src/k8s.io/apiserver/pkg/authentication/authenticator/audiences_test.go diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/BUILD b/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/BUILD index 750e8b4eae4c6..1da12201175f8 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/BUILD @@ -23,6 +23,7 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/authentication/request/union:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/request/websocket:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/request/x509:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/authentication/token/cache:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/token/tokenfile:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/delegating.go b/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/delegating.go index d8e18345545eb..74e583a2af435 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/delegating.go +++ b/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/delegating.go @@ -31,6 +31,7 @@ import ( unionauth "k8s.io/apiserver/pkg/authentication/request/union" "k8s.io/apiserver/pkg/authentication/request/websocket" "k8s.io/apiserver/pkg/authentication/request/x509" + "k8s.io/apiserver/pkg/authentication/token/cache" webhooktoken "k8s.io/apiserver/plugin/pkg/authenticator/token/webhook" authenticationclient "k8s.io/client-go/kubernetes/typed/authentication/v1beta1" "k8s.io/client-go/util/cert" @@ -85,11 +86,12 @@ func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.Secur } if c.TokenAccessReviewClient != nil { - tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient, c.CacheTTL) + tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient) if err != nil { return nil, nil, err } - authenticators = append(authenticators, bearertoken.New(tokenAuth), websocket.NewProtocolAuthenticator(tokenAuth)) + cachingTokenAuth := cache.New(tokenAuth, false, c.CacheTTL, c.CacheTTL) + authenticators = append(authenticators, bearertoken.New(cachingTokenAuth), websocket.NewProtocolAuthenticator(cachingTokenAuth)) securityDefinitions["BearerToken"] = &spec.SecurityScheme{ SecuritySchemeProps: spec.SecuritySchemeProps{ diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/request/anonymous/anonymous.go b/staging/src/k8s.io/apiserver/pkg/authentication/request/anonymous/anonymous.go index 651832fd3f710..f9177d151379a 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/request/anonymous/anonymous.go +++ b/staging/src/k8s.io/apiserver/pkg/authentication/request/anonymous/anonymous.go @@ -31,11 +31,13 @@ const ( func NewAuthenticator() authenticator.Request { return authenticator.RequestFunc(func(req *http.Request) (*authenticator.Response, bool, error) { + auds, _ := authenticator.AudiencesFrom(req.Context()) return &authenticator.Response{ User: &user.DefaultInfo{ Name: anonymousUser, Groups: []string{unauthenticatedGroup}, }, + Audiences: auds, }, true, nil }) } diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/request/anonymous/anonymous_test.go b/staging/src/k8s.io/apiserver/pkg/authentication/request/anonymous/anonymous_test.go index 7b27ff20e1bca..494ab60974c77 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/request/anonymous/anonymous_test.go +++ b/staging/src/k8s.io/apiserver/pkg/authentication/request/anonymous/anonymous_test.go @@ -17,6 +17,7 @@ limitations under the License. package anonymous import ( + "net/http" "testing" "k8s.io/apimachinery/pkg/util/sets" @@ -26,7 +27,7 @@ import ( func TestAnonymous(t *testing.T) { var a authenticator.Request = NewAuthenticator() - r, ok, err := a.AuthenticateRequest(nil) + r, ok, err := a.AuthenticateRequest(&http.Request{}) if err != nil { t.Fatalf("Unexpected error %v", err) } diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/request/x509/OWNERS b/staging/src/k8s.io/apiserver/pkg/authentication/request/x509/OWNERS new file mode 100644 index 0000000000000..470b7a1c92d15 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/authentication/request/x509/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-certificates-approvers +reviewers: +- sig-auth-certificates-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/BUILD b/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/BUILD index 3c8ca28129ffc..66c09d448448e 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/BUILD @@ -17,7 +17,6 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", "//vendor/github.com/pborman/uuid:go_default_library", ], ) @@ -35,7 +34,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/cache:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go b/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go index ec5af39d8bcec..ea3853a38b417 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go +++ b/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go @@ -23,7 +23,6 @@ import ( utilclock "k8s.io/apimachinery/pkg/util/clock" "k8s.io/apiserver/pkg/authentication/authenticator" - "k8s.io/apiserver/pkg/endpoints/request" ) // cacheRecord holds the three return values of the authenticator.Token AuthenticateToken method @@ -36,6 +35,7 @@ type cacheRecord struct { type cachedTokenAuthenticator struct { authenticator authenticator.Token + cacheErrs bool successTTL time.Duration failureTTL time.Duration @@ -52,13 +52,14 @@ type cache interface { } // New returns a token authenticator that caches the results of the specified authenticator. A ttl of 0 bypasses the cache. -func New(authenticator authenticator.Token, successTTL, failureTTL time.Duration) authenticator.Token { - return newWithClock(authenticator, successTTL, failureTTL, utilclock.RealClock{}) +func New(authenticator authenticator.Token, cacheErrs bool, successTTL, failureTTL time.Duration) authenticator.Token { + return newWithClock(authenticator, cacheErrs, successTTL, failureTTL, utilclock.RealClock{}) } -func newWithClock(authenticator authenticator.Token, successTTL, failureTTL time.Duration, clock utilclock.Clock) authenticator.Token { +func newWithClock(authenticator authenticator.Token, cacheErrs bool, successTTL, failureTTL time.Duration, clock utilclock.Clock) authenticator.Token { return &cachedTokenAuthenticator{ authenticator: authenticator, + cacheErrs: cacheErrs, successTTL: successTTL, failureTTL: failureTTL, cache: newStripedCache(32, fnvHashFunc, func() cache { return newSimpleCache(128, clock) }), @@ -67,7 +68,7 @@ func newWithClock(authenticator authenticator.Token, successTTL, failureTTL time // AuthenticateToken implements authenticator.Token func (a *cachedTokenAuthenticator) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) { - auds, _ := request.AudiencesFrom(ctx) + auds, _ := authenticator.AudiencesFrom(ctx) key := keyFunc(auds, token) if record, ok := a.cache.get(key); ok { @@ -75,6 +76,9 @@ func (a *cachedTokenAuthenticator) AuthenticateToken(ctx context.Context, token } resp, ok, err := a.authenticator.AuthenticateToken(ctx, token) + if !a.cacheErrs && err != nil { + return resp, ok, err + } switch { case ok && a.successTTL > 0: diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator_test.go b/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator_test.go index e92e957a4d3ac..09901b40033b8 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator_test.go +++ b/staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator_test.go @@ -25,7 +25,6 @@ import ( utilclock "k8s.io/apimachinery/pkg/util/clock" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/user" - "k8s.io/apiserver/pkg/endpoints/request" ) func TestCachedTokenAuthenticator(t *testing.T) { @@ -42,7 +41,7 @@ func TestCachedTokenAuthenticator(t *testing.T) { }) fakeClock := utilclock.NewFakeClock(time.Now()) - a := newWithClock(fakeAuth, time.Minute, 0, fakeClock) + a := newWithClock(fakeAuth, true, time.Minute, 0, fakeClock) calledWithToken, resultUsers, resultOk, resultErr = []string{}, nil, false, nil a.AuthenticateToken(context.Background(), "bad1") @@ -109,20 +108,20 @@ func TestCachedTokenAuthenticator(t *testing.T) { func TestCachedTokenAuthenticatorWithAudiences(t *testing.T) { resultUsers := make(map[string]user.Info) fakeAuth := authenticator.TokenFunc(func(ctx context.Context, token string) (*authenticator.Response, bool, error) { - auds, _ := request.AudiencesFrom(ctx) + auds, _ := authenticator.AudiencesFrom(ctx) return &authenticator.Response{User: resultUsers[auds[0]+token]}, true, nil }) fakeClock := utilclock.NewFakeClock(time.Now()) - a := newWithClock(fakeAuth, time.Minute, 0, fakeClock) + a := newWithClock(fakeAuth, true, time.Minute, 0, fakeClock) resultUsers["audAusertoken1"] = &user.DefaultInfo{Name: "user1"} resultUsers["audBusertoken1"] = &user.DefaultInfo{Name: "user1-different"} - if u, ok, _ := a.AuthenticateToken(request.WithAudiences(context.Background(), []string{"audA"}), "usertoken1"); !ok || u.User.GetName() != "user1" { + if u, ok, _ := a.AuthenticateToken(authenticator.WithAudiences(context.Background(), []string{"audA"}), "usertoken1"); !ok || u.User.GetName() != "user1" { t.Errorf("Expected user1") } - if u, ok, _ := a.AuthenticateToken(request.WithAudiences(context.Background(), []string{"audB"}), "usertoken1"); !ok || u.User.GetName() != "user1-different" { + if u, ok, _ := a.AuthenticateToken(authenticator.WithAudiences(context.Background(), []string{"audB"}), "usertoken1"); !ok || u.User.GetName() != "user1-different" { t.Errorf("Expected user1-different") } } diff --git a/staging/src/k8s.io/apiserver/pkg/authorization/OWNERS b/staging/src/k8s.io/apiserver/pkg/authorization/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/authorization/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD b/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD index d1ab6e43b6f20..45f63ebeb5591 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD @@ -54,6 +54,8 @@ go_test( "//staging/src/k8s.io/apiserver/pkg/server/filters:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", + "//staging/src/k8s.io/client-go/dynamic:go_default_library", + "//staging/src/k8s.io/client-go/rest:go_default_library", "//vendor/github.com/emicklei/go-restful:go_default_library", "//vendor/golang.org/x/net/websocket:go_default_library", ], diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/audit_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/audit_test.go index 5301f95ea18dc..e0c2de2d4396d 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/audit_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/audit_test.go @@ -42,7 +42,10 @@ type fakeAuditSink struct { func (s *fakeAuditSink) ProcessEvents(evs ...*auditinternal.Event) { s.lock.Lock() defer s.lock.Unlock() - s.events = append(s.events, evs...) + for _, ev := range evs { + e := ev.DeepCopy() + s.events = append(s.events, e) + } } func (s *fakeAuditSink) Events() []*auditinternal.Event { @@ -90,6 +93,9 @@ func TestAudit(t *testing.T) { } requestBodyMatches := func(i int, pattern string) eventCheck { return func(events []*auditinternal.Event) error { + if events[i].RequestObject == nil { + return fmt.Errorf("expected non nil request object") + } if matched, _ := regexp.Match(pattern, events[i].RequestObject.Raw); !matched { return fmt.Errorf("expected RequestBody to match %q, but didn't: %q", pattern, string(events[i].RequestObject.Raw)) } @@ -106,6 +112,9 @@ func TestAudit(t *testing.T) { } responseBodyMatches := func(i int, pattern string) eventCheck { return func(events []*auditinternal.Event) error { + if events[i].ResponseObject == nil { + return fmt.Errorf("expected non nil response object") + } if matched, _ := regexp.Match(pattern, events[i].ResponseObject.Raw); !matched { return fmt.Errorf("expected ResponseBody to match %q, but didn't: %q", pattern, string(events[i].ResponseObject.Raw)) } @@ -122,6 +131,19 @@ func TestAudit(t *testing.T) { return nil } } + expectedStages := func(stages ...auditinternal.Stage) eventCheck { + return func(events []*auditinternal.Event) error { + if len(stages) != len(events) { + return fmt.Errorf("expected %d stages, but got %d events", len(stages), len(events)) + } + for i, stage := range stages { + if events[i].Stage != stage { + return fmt.Errorf("expected stage %q, got %q", stage, events[i].Stage) + } + } + return nil + } + } for _, test := range []struct { desc string @@ -140,8 +162,9 @@ func TestAudit(t *testing.T) { 200, 2, []eventCheck{ - noRequestBody(0), - responseBodyMatches(0, `{.*"name":"c".*}`), + noRequestBody(1), + responseBodyMatches(1, `{.*"name":"c".*}`), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -157,8 +180,9 @@ func TestAudit(t *testing.T) { 200, 2, []eventCheck{ - noRequestBody(0), - responseBodyMatches(0, `{.*"name":"a".*"name":"b".*}`), + noRequestBody(1), + responseBodyMatches(1, `{.*"name":"a".*"name":"b".*}`), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -170,8 +194,9 @@ func TestAudit(t *testing.T) { 201, 2, []eventCheck{ - requestBodyIs(0, string(simpleFooJSON)), - responseBodyMatches(0, `{.*"foo".*}`), + requestBodyIs(1, string(simpleFooJSON)), + responseBodyMatches(1, `{.*"foo".*}`), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -183,8 +208,9 @@ func TestAudit(t *testing.T) { 405, 2, []eventCheck{ - noRequestBody(0), // the 405 is thrown long before the create handler would be executed - noResponseBody(0), // the 405 is thrown long before the create handler would be executed + noRequestBody(1), // the 405 is thrown long before the create handler would be executed + noResponseBody(1), // the 405 is thrown long before the create handler would be executed + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -196,8 +222,9 @@ func TestAudit(t *testing.T) { 200, 2, []eventCheck{ - noRequestBody(0), - responseBodyMatches(0, `{.*"kind":"Status".*"status":"Success".*}`), + noRequestBody(1), + responseBodyMatches(1, `{.*"kind":"Status".*"status":"Success".*}`), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -209,8 +236,9 @@ func TestAudit(t *testing.T) { 200, 2, []eventCheck{ - requestBodyMatches(0, "DeleteOptions"), - responseBodyMatches(0, `{.*"kind":"Status".*"status":"Success".*}`), + requestBodyMatches(1, "DeleteOptions"), + responseBodyMatches(1, `{.*"kind":"Status".*"status":"Success".*}`), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -222,8 +250,9 @@ func TestAudit(t *testing.T) { 200, 2, []eventCheck{ - requestBodyIs(0, string(simpleCPrimeJSON)), - responseBodyMatches(0, `{.*"bla".*}`), + requestBodyIs(1, string(simpleCPrimeJSON)), + responseBodyMatches(1, `{.*"bla".*}`), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -235,8 +264,9 @@ func TestAudit(t *testing.T) { 400, 2, []eventCheck{ - requestBodyIs(0, string(simpleCPrimeJSON)), - responseBodyMatches(0, `"Status".*"status":"Failure".*"code":400}`), + requestBodyIs(1, string(simpleCPrimeJSON)), + responseBodyMatches(1, `"Status".*"status":"Failure".*"code":400}`), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -255,8 +285,9 @@ func TestAudit(t *testing.T) { 200, 2, []eventCheck{ - requestBodyIs(0, `{"labels":{"foo":"bar"}}`), - responseBodyMatches(0, `"name":"c".*"labels":{"foo":"bar"}`), + requestBodyIs(1, `{"labels":{"foo":"bar"}}`), + responseBodyMatches(1, `"name":"c".*"labels":{"foo":"bar"}`), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseComplete), }, }, { @@ -272,8 +303,9 @@ func TestAudit(t *testing.T) { 200, 3, []eventCheck{ - noRequestBody(0), - noResponseBody(0), + noRequestBody(2), + noResponseBody(2), + expectedStages(auditinternal.StageRequestReceived, auditinternal.StageResponseStarted, auditinternal.StageResponseComplete), }, }, } { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authentication.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authentication.go index b9c6f6e51a715..70c14e088a281 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authentication.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authentication.go @@ -57,7 +57,7 @@ func WithAuthentication(handler http.Handler, auth authenticator.Request, failed } return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { if len(apiAuds) > 0 { - req = req.WithContext(genericapirequest.WithAudiences(req.Context(), apiAuds)) + req = req.WithContext(authenticator.WithAudiences(req.Context(), apiAuds)) } resp, ok, err := auth.AuthenticateRequest(req) if err != nil || !ok { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go index 998c05bcf7326..4c9f140ca30df 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go @@ -73,7 +73,7 @@ func WithAuthorization(handler http.Handler, a authorizer.Authorizer, s runtime. glog.V(4).Infof("Forbidden: %#v, Reason: %q", req.RequestURI, reason) audit.LogAnnotation(ae, decisionAnnotationKey, decisionForbid) audit.LogAnnotation(ae, reasonAnnotationKey, reason) - responsewriters.Forbidden(ctx, attributes, w, req, "", s) + responsewriters.Forbidden(ctx, attributes, w, req, reason, s) }) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go index 38414a6afa75e..726cbe4d565f0 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go @@ -110,7 +110,7 @@ func WithImpersonation(handler http.Handler, a authorizer.Authorizer, s runtime. decision, reason, err := a.Authorize(actingAsAttributes) if err != nil || decision != authorizer.DecisionAllow { glog.V(4).Infof("Forbidden: %#v, Reason: %s, Error: %v", req.RequestURI, reason, err) - responsewriters.Forbidden(ctx, actingAsAttributes, w, req, "", s) + responsewriters.Forbidden(ctx, actingAsAttributes, w, req, reason, s) return } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go index e40e4288ac574..515d266359217 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go @@ -77,7 +77,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte scope.err(err, w, req) return } - decoder := scope.Serializer.DecoderToVersion(s.Serializer, schema.GroupVersion{Group: gv.Group, Version: runtime.APIVersionInternal}) + decoder := scope.Serializer.DecoderToVersion(s.Serializer, scope.HubGroupVersion) body, err := readBody(req) if err != nil { @@ -167,6 +167,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte status.Code = int32(code) } + scope.Trace = trace transformResponseObject(ctx, scope, req, w, code, result) } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go index ff35fa9dddd58..b8b4cdc2315ff 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go @@ -175,6 +175,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco } } + scope.Trace = trace transformResponseObject(ctx, scope, req, w, status, result) } } @@ -182,6 +183,9 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco // DeleteCollection returns a function that will handle a collection deletion func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestScope, admit admission.Interface) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { + trace := utiltrace.New("Delete " + req.URL.Path) + defer trace.LogIfLong(500 * time.Millisecond) + if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) { scope.err(errors.NewBadRequest("the dryRun alpha feature is disabled"), w, req) return @@ -310,6 +314,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco } } + scope.Trace = trace transformResponseObject(ctx, scope, req, w, http.StatusOK, result) } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go index b234bcca4a70f..8526f8066ec8b 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go @@ -74,7 +74,9 @@ func getResourceHandler(scope RequestScope, getter getterFunc) http.HandlerFunc } trace.Step("About to write a response") + scope.Trace = trace transformResponseObject(ctx, scope, req, w, http.StatusOK, result) + trace.Step("Transformed response object") } } @@ -279,6 +281,7 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch } } + scope.Trace = trace transformResponseObject(ctx, scope, req, w, http.StatusOK, result) trace.Step(fmt.Sprintf("Writing http response done (%d items)", numberOfItems)) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go index d73c3fd573ea4..df9c38d165f5a 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go @@ -118,9 +118,10 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface return } gv := scope.Kind.GroupVersion() + codec := runtime.NewCodec( scope.Serializer.EncoderForVersion(s.Serializer, gv), - scope.Serializer.DecoderToVersion(s.Serializer, schema.GroupVersion{Group: gv.Group, Version: runtime.APIVersionInternal}), + scope.Serializer.DecoderToVersion(s.Serializer, scope.HubGroupVersion), ) userInfo, _ := request.UserFrom(ctx) @@ -163,6 +164,8 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface kind: scope.Kind, resource: scope.Resource, + hubGroupVersion: scope.HubGroupVersion, + createValidation: rest.AdmissionToValidateObjectFunc(admit, staticAdmissionAttributes), updateValidation: rest.AdmissionToValidateObjectUpdateFunc(admit, staticAdmissionAttributes), admissionCheck: admissionCheck, @@ -198,6 +201,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface } trace.Step("Self-link added") + scope.Trace = trace transformResponseObject(ctx, scope, req, w, http.StatusOK, result) } } @@ -218,6 +222,8 @@ type patcher struct { resource schema.GroupVersionResource kind schema.GroupVersionKind + hubGroupVersion schema.GroupVersion + // Validation functions createValidation rest.ValidateObjectFunc updateValidation rest.ValidateObjectUpdateFunc @@ -242,11 +248,6 @@ type patcher struct { mechanism patchMechanism } -func (p *patcher) toUnversioned(versionedObj runtime.Object) (runtime.Object, error) { - gvk := p.kind.GroupKind().WithVersion(runtime.APIVersionInternal) - return p.unsafeConvertor.ConvertToVersion(versionedObj, gvk.GroupVersion()) -} - type patchMechanism interface { applyPatchToCurrentObject(currentObject runtime.Object) (runtime.Object, error) } @@ -320,13 +321,8 @@ func (p *smpPatcher) applyPatchToCurrentObject(currentObject runtime.Object) (ru if err := strategicPatchObject(p.defaulter, currentVersionedObject, p.patchJS, versionedObjToUpdate, p.schemaReferenceObj); err != nil { return nil, err } - // Convert the object back to unversioned (aka internal version). - unversionedObjToUpdate, err := p.toUnversioned(versionedObjToUpdate) - if err != nil { - return nil, err - } - - return unversionedObjToUpdate, nil + // Convert the object back to the hub version + return p.unsafeConvertor.ConvertToVersion(versionedObjToUpdate, p.hubGroupVersion) } // strategicPatchObject applies a strategic merge patch of to diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/response.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/response.go index 8cee470a51e42..e140c081746b6 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/response.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/response.go @@ -35,9 +35,11 @@ import ( // Will write the complete response object. func transformResponseObject(ctx context.Context, scope RequestScope, req *http.Request, w http.ResponseWriter, statusCode int, result runtime.Object) { // TODO: fetch the media type much earlier in request processing and pass it into this method. + trace := scope.Trace mediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) if err != nil { status := responsewriters.ErrorToAPIStatus(err) + trace.Step("Writing raw JSON response") responsewriters.WriteRawJSON(int(status.Code), status, w) return } @@ -68,6 +70,7 @@ func transformResponseObject(ctx context.Context, scope RequestScope, req *http. return } encoder := metainternalversion.Codecs.EncoderForVersion(info.Serializer, metav1beta1.SchemeGroupVersion) + trace.Step(fmt.Sprintf("Serializing response as type %s", info.MediaType)) responsewriters.SerializeObject(info.MediaType, encoder, w, req, statusCode, partial) return @@ -79,6 +82,7 @@ func transformResponseObject(ctx context.Context, scope RequestScope, req *http. return } list := &metav1beta1.PartialObjectMetadataList{} + trace.Step("Processing list items") err := meta.EachListItem(result, func(obj runtime.Object) error { m, err := meta.Accessor(obj) if err != nil { @@ -101,6 +105,7 @@ func transformResponseObject(ctx context.Context, scope RequestScope, req *http. return } encoder := metainternalversion.Codecs.EncoderForVersion(info.Serializer, metav1beta1.SchemeGroupVersion) + trace.Step(fmt.Sprintf("Serializing response as type %s", info.MediaType)) responsewriters.SerializeObject(info.MediaType, encoder, w, req, statusCode, list) return @@ -109,17 +114,20 @@ func transformResponseObject(ctx context.Context, scope RequestScope, req *http. // TODO: skip if this is a status response (delete without body)? opts := &metav1beta1.TableOptions{} + trace.Step("Decoding parameters") if err := metav1beta1.ParameterCodec.DecodeParameters(req.URL.Query(), metav1beta1.SchemeGroupVersion, opts); err != nil { scope.err(err, w, req) return } + trace.Step("Converting to table") table, err := scope.TableConvertor.ConvertToTable(ctx, result, opts) if err != nil { scope.err(err, w, req) return } + trace.Step("Processing rows") for i := range table.Rows { item := &table.Rows[i] switch opts.IncludeObject { @@ -156,6 +164,7 @@ func transformResponseObject(ctx context.Context, scope RequestScope, req *http. return } encoder := metainternalversion.Codecs.EncoderForVersion(info.Serializer, metav1beta1.SchemeGroupVersion) + trace.Step(fmt.Sprintf("Serializing response as type %s", info.MediaType)) responsewriters.SerializeObject(info.MediaType, encoder, w, req, statusCode, table) return @@ -164,11 +173,13 @@ func transformResponseObject(ctx context.Context, scope RequestScope, req *http. accepted, _ := negotiation.MediaTypesForSerializer(metainternalversion.Codecs) err := negotiation.NewNotAcceptableError(accepted) status := responsewriters.ErrorToAPIStatus(err) + trace.Step("Writing raw JSON response") responsewriters.WriteRawJSON(int(status.Code), status, w) return } } + trace.Step("Writing response") responsewriters.WriteObject(statusCode, scope.Kind.GroupVersion(), scope.Serializer, result, w, req) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go index 8b3ca9d62bc16..b3504df3f2372 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go @@ -40,6 +40,7 @@ import ( "k8s.io/apiserver/pkg/endpoints/metrics" "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" + utiltrace "k8s.io/apiserver/pkg/util/trace" openapiproto "k8s.io/kube-openapi/pkg/util/proto" ) @@ -56,6 +57,7 @@ type RequestScope struct { Typer runtime.ObjectTyper UnsafeConvertor runtime.ObjectConvertor Authorizer authorizer.Authorizer + Trace *utiltrace.Trace TableConvertor rest.TableConvertor OpenAPISchema openapiproto.Schema @@ -65,6 +67,9 @@ type RequestScope struct { Subresource string MetaGroupVersion schema.GroupVersion + + // HubGroupVersion indicates what version objects read from etcd or incoming requests should be converted to for in-memory handling. + HubGroupVersion schema.GroupVersion } func (scope *RequestScope) err(err error, w http.ResponseWriter, req *http.Request) { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go index b190f8d299bcf..66d9e9c2cf891 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go @@ -367,6 +367,7 @@ func (tc *patchTestCase) Run(t *testing.T) { kind := examplev1.SchemeGroupVersion.WithKind("Pod") resource := examplev1.SchemeGroupVersion.WithResource("pods") schemaReferenceObj := &examplev1.Pod{} + hubVersion := example.SchemeGroupVersion for _, patchType := range []types.PatchType{types.JSONPatchType, types.MergePatchType, types.StrategicMergePatchType} { // This needs to be reset on each iteration. @@ -439,6 +440,8 @@ func (tc *patchTestCase) Run(t *testing.T) { kind: kind, resource: resource, + hubGroupVersion: hubVersion, + createValidation: rest.ValidateAllObjectFunc, updateValidation: admissionValidation, admissionCheck: admissionMutation, diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go index 19d23e1f2eba0..1bcde7f28b4e8 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go @@ -89,8 +89,9 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac } defaultGVK := scope.Kind original := r.New() + trace.Step("About to convert to expected version") - decoder := scope.Serializer.DecoderToVersion(s.Serializer, schema.GroupVersion{Group: defaultGVK.Group, Version: runtime.APIVersionInternal}) + decoder := scope.Serializer.DecoderToVersion(s.Serializer, scope.HubGroupVersion) obj, gvk, err := decoder.Decode(body, &defaultGVK, original) if err != nil { err = transformDecodeError(scope.Typer, err, original, gvk, body) @@ -189,6 +190,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac status = http.StatusCreated } + scope.Trace = trace transformResponseObject(ctx, scope, req, w, status, result) } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go index 19bb5e55adf5b..0b18d992696b7 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go @@ -506,6 +506,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Subresource: subresource, Kind: fqKindToRegister, + HubGroupVersion: schema.GroupVersion{Group: fqKindToRegister.Group, Version: runtime.APIVersionInternal}, + MetaGroupVersion: metav1.SchemeGroupVersion, } if a.group.MetaGroupVersion != nil { @@ -736,6 +738,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Returns(http.StatusAccepted, "Accepted", versionedStatus) if isGracefulDeleter { route.Reads(versionedDeleterObject) + route.ParameterNamed("body").Required(false) if err := addObjectParams(ws, route, versionedDeleteOptions); err != nil { return nil, err } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/request/BUILD b/staging/src/k8s.io/apiserver/pkg/endpoints/request/BUILD index e56dc33f8bd57..5e84006a1cf28 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/request/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/request/BUILD @@ -35,7 +35,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//vendor/github.com/golang/glog:go_default_library", ], diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/request/context.go b/staging/src/k8s.io/apiserver/pkg/endpoints/request/context.go index eb1e8546093a1..fe3ae38edcd7d 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/request/context.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/request/context.go @@ -21,7 +21,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/apis/audit" - "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/user" ) @@ -95,14 +94,3 @@ func AuditEventFrom(ctx context.Context) *audit.Event { ev, _ := ctx.Value(auditKey).(*audit.Event) return ev } - -// WithAudiences returns a context that stores a request's expected audiences. -func WithAudiences(ctx context.Context, auds authenticator.Audiences) context.Context { - return context.WithValue(ctx, audiencesKey, auds) -} - -// AudiencesFrom returns a request's expected audiences stored in the request context. -func AudiencesFrom(ctx context.Context) (authenticator.Audiences, bool) { - auds, ok := ctx.Value(audiencesKey).(authenticator.Audiences) - return auds, ok -} diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/watch_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/watch_test.go index 802b55e732f81..81d141fa753d4 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/watch_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/watch_test.go @@ -25,13 +25,16 @@ import ( "net/http/httptest" "net/url" "reflect" + "strings" "sync" "testing" "time" "golang.org/x/net/websocket" apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" @@ -43,6 +46,8 @@ import ( "k8s.io/apiserver/pkg/endpoints/handlers" apitesting "k8s.io/apiserver/pkg/endpoints/testing" "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/client-go/dynamic" + restclient "k8s.io/client-go/rest" ) // watchJSON defines the expected JSON wire equivalent of watch.Event @@ -561,6 +566,128 @@ func (t *fakeTimeoutFactory) TimeoutCh() (<-chan time.Time, func() bool) { } } +func TestWatchHTTPErrors(t *testing.T) { + watcher := watch.NewFake() + timeoutCh := make(chan time.Time) + done := make(chan struct{}) + + info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON) + if !ok || info.StreamSerializer == nil { + t.Fatal(info) + } + serializer := info.StreamSerializer + + // Setup a new watchserver + watchServer := &handlers.WatchServer{ + Watching: watcher, + + MediaType: "testcase/json", + Framer: serializer.Framer, + Encoder: newCodec, + EmbeddedEncoder: newCodec, + + Fixup: func(obj runtime.Object) {}, + TimeoutFactory: &fakeTimeoutFactory{timeoutCh, done}, + } + + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + watchServer.ServeHTTP(w, req) + })) + defer s.Close() + + // Setup a client + dest, _ := url.Parse(s.URL) + dest.Path = "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple" + dest.RawQuery = "watch=true" + + req, _ := http.NewRequest("GET", dest.String(), nil) + client := http.Client{} + resp, err := client.Do(req) + errStatus := errors.NewInternalError(fmt.Errorf("we got an error")).Status() + watcher.Error(&errStatus) + watcher.Stop() + + // Make sure we can actually watch an endpoint + decoder := json.NewDecoder(resp.Body) + var got watchJSON + err = decoder.Decode(&got) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if got.Type != watch.Error { + t.Fatalf("unexpected watch type: %#v", got) + } + status := &metav1.Status{} + if err := json.Unmarshal(got.Object, status); err != nil { + t.Fatal(err) + } + if status.Kind != "Status" || status.APIVersion != "v1" || status.Code != 500 || status.Status != "Failure" || !strings.Contains(status.Message, "we got an error") { + t.Fatalf("error: %#v", status) + } +} + +func TestWatchHTTPDynamicClientErrors(t *testing.T) { + watcher := watch.NewFake() + timeoutCh := make(chan time.Time) + done := make(chan struct{}) + + info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON) + if !ok || info.StreamSerializer == nil { + t.Fatal(info) + } + serializer := info.StreamSerializer + + // Setup a new watchserver + watchServer := &handlers.WatchServer{ + Watching: watcher, + + MediaType: "testcase/json", + Framer: serializer.Framer, + Encoder: newCodec, + EmbeddedEncoder: newCodec, + + Fixup: func(obj runtime.Object) {}, + TimeoutFactory: &fakeTimeoutFactory{timeoutCh, done}, + } + + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + watchServer.ServeHTTP(w, req) + })) + defer s.Close() + + client := dynamic.NewForConfigOrDie(&restclient.Config{ + Host: s.URL, + APIPath: "/" + prefix, + }).Resource(newGroupVersion.WithResource("simple")) + + w, err := client.Watch(metav1.ListOptions{}) + if err != nil { + t.Fatal(err) + } + + errStatus := errors.NewInternalError(fmt.Errorf("we got an error")).Status() + watcher.Error(&errStatus) + watcher.Stop() + + got := <-w.ResultChan() + if got.Type != watch.Error { + t.Fatalf("unexpected watch type: %#v", got) + } + obj, ok := got.Object.(*unstructured.Unstructured) + if !ok { + t.Fatalf("not the correct object type: %#v", got) + } + + status := &metav1.Status{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), status); err != nil { + t.Fatal(err) + } + if status.Kind != "Status" || status.APIVersion != "v1" || status.Code != 500 || status.Status != "Failure" || !strings.Contains(status.Message, "we got an error") { + t.Fatalf("error: %#v", status) + } + t.Logf("status: %#v", status) +} + func TestWatchHTTPTimeout(t *testing.T) { watcher := watch.NewFake() timeoutCh := make(chan time.Time) diff --git a/staging/src/k8s.io/apiserver/pkg/server/deprecated_insecure_serving.go b/staging/src/k8s.io/apiserver/pkg/server/deprecated_insecure_serving.go index 43fff06ec0361..6cf6c1a64fcbb 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/deprecated_insecure_serving.go +++ b/staging/src/k8s.io/apiserver/pkg/server/deprecated_insecure_serving.go @@ -79,10 +79,12 @@ func (s *DeprecatedInsecureServingInfo) NewLoopbackClientConfig() (*rest.Config, type InsecureSuperuser struct{} func (InsecureSuperuser) AuthenticateRequest(req *http.Request) (*authenticator.Response, bool, error) { + auds, _ := authenticator.AudiencesFrom(req.Context()) return &authenticator.Response{ User: &user.DefaultInfo{ Name: "system:unsecured", Groups: []string{user.SystemPrivilegedGroup, user.AllAuthenticated}, }, + Audiences: auds, }, true, nil } diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/audit.go b/staging/src/k8s.io/apiserver/pkg/server/options/audit.go index 71476c229a080..1e9efe7fc3933 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/audit.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/audit.go @@ -137,9 +137,8 @@ func NewAuditOptions() *AuditOptions { Mode: ModeBatch, BatchConfig: defaultWebhookBatchConfig(), }, - TruncateOptions: NewAuditTruncateOptions(), - // TODO(audit): use v1 API in release 1.13 - GroupVersionString: "audit.k8s.io/v1beta1", + TruncateOptions: NewAuditTruncateOptions(), + GroupVersionString: "audit.k8s.io/v1", }, LogOptions: AuditLogOptions{ Format: pluginlog.FormatJson, @@ -147,9 +146,8 @@ func NewAuditOptions() *AuditOptions { Mode: ModeBlocking, BatchConfig: defaultLogBatchConfig(), }, - TruncateOptions: NewAuditTruncateOptions(), - // TODO(audit): use v1 API in release 1.13 - GroupVersionString: "audit.k8s.io/v1beta1", + TruncateOptions: NewAuditTruncateOptions(), + GroupVersionString: "audit.k8s.io/v1", }, } } diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/authorization.go b/staging/src/k8s.io/apiserver/pkg/server/options/authorization.go index 7c65dd3918486..6d8cfb8410b5f 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/authorization.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/authorization.go @@ -56,6 +56,9 @@ type DelegatingAuthorizationOptions struct { // AlwaysAllowPaths are HTTP paths which are excluded from authorization. They can be plain // paths or end in * in which case prefix-match is applied. A leading / is optional. AlwaysAllowPaths []string + + // AlwaysAllowGroups are groups which are allowed to take any actions. In kube, this is system:masters. + AlwaysAllowGroups []string } func NewDelegatingAuthorizationOptions() *DelegatingAuthorizationOptions { @@ -66,6 +69,12 @@ func NewDelegatingAuthorizationOptions() *DelegatingAuthorizationOptions { } } +// WithAlwaysAllowGroups appends the list of paths to AlwaysAllowGroups +func (s *DelegatingAuthorizationOptions) WithAlwaysAllowGroups(groups ...string) *DelegatingAuthorizationOptions { + s.AlwaysAllowGroups = append(s.AlwaysAllowGroups, groups...) + return s +} + func (s *DelegatingAuthorizationOptions) Validate() []error { allErrors := []error{} return allErrors @@ -115,6 +124,10 @@ func (s *DelegatingAuthorizationOptions) ApplyTo(c *server.AuthorizationInfo) er func (s *DelegatingAuthorizationOptions) toAuthorizer(client kubernetes.Interface) (authorizer.Authorizer, error) { var authorizers []authorizer.Authorizer + if len(s.AlwaysAllowGroups) > 0 { + authorizers = append(authorizers, authorizerfactory.NewPrivilegedGroups(s.AlwaysAllowGroups...)) + } + if len(s.AlwaysAllowPaths) > 0 { a, err := path.NewAuthorizer(s.AlwaysAllowPaths) if err != nil { diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/OWNERS b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/OWNERS new file mode 100644 index 0000000000000..498b470c9bfca --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-encryption-at-rest-approvers +reviewers: +- sig-auth-encryption-at-rest-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/serving.go b/staging/src/k8s.io/apiserver/pkg/server/options/serving.go index 3ecc7e02094c1..998c7ce358a68 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/serving.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/serving.go @@ -75,19 +75,25 @@ type CertKey struct { } type GeneratableKeyCert struct { + // CertKey allows setting an explicit cert/key file to use. CertKey CertKey - // CertDirectory is a directory that will contain the certificates. If the cert and key aren't specifically set - // this will be used to derive a match with the "pair-name" + // CertDirectory specifies a directory to write generated certificates to if CertFile/KeyFile aren't explicitly set. + // PairName is used to determine the filenames within CertDirectory. + // If CertDirectory and PairName are not set, an in-memory certificate will be generated. CertDirectory string + // PairName is the name which will be used with CertDirectory to make a cert and key filenames. + // It becomes CertDirectory/PairName.crt and CertDirectory/PairName.key + PairName string + + // GeneratedCert holds an in-memory generated certificate if CertFile/KeyFile aren't explicitly set, and CertDirectory/PairName are not set. + GeneratedCert *tls.Certificate + // FixtureDirectory is a directory that contains test fixture used to avoid regeneration of certs during tests. // The format is: // _-_-.crt // _-_-.key FixtureDirectory string - // PairName is the name which will be used with CertDirectory to make a cert and key names - // It becomes CertDirector/PairName.crt and CertDirector/PairName.key - PairName string } func NewSecureServingOptions() *SecureServingOptions { @@ -121,6 +127,10 @@ func (s *SecureServingOptions) Validate() []error { errors = append(errors, fmt.Errorf("--secure-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port", s.BindPort)) } + if (len(s.ServerCert.CertKey.CertFile) != 0 || len(s.ServerCert.CertKey.KeyFile) != 0) && s.ServerCert.GeneratedCert != nil { + errors = append(errors, fmt.Errorf("cert/key file and in-memory certificate cannot both be set")) + } + return errors } @@ -219,6 +229,8 @@ func (s *SecureServingOptions) ApplyTo(config **server.SecureServingInfo) error return fmt.Errorf("unable to load server certificate: %v", err) } c.Cert = &tlsCert + } else if s.ServerCert.GeneratedCert != nil { + c.Cert = s.ServerCert.GeneratedCert } if len(s.CipherSuites) != 0 { @@ -264,13 +276,20 @@ func (s *SecureServingOptions) MaybeDefaultWithSelfSignedCerts(publicAddress str return nil } - keyCert.CertFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".crt") - keyCert.KeyFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".key") - - canReadCertAndKey, err := certutil.CanReadCertAndKey(keyCert.CertFile, keyCert.KeyFile) - if err != nil { - return err + canReadCertAndKey := false + if len(s.ServerCert.CertDirectory) > 0 { + if len(s.ServerCert.PairName) == 0 { + return fmt.Errorf("PairName is required if CertDirectory is set") + } + keyCert.CertFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".crt") + keyCert.KeyFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".key") + if canRead, err := certutil.CanReadCertAndKey(keyCert.CertFile, keyCert.KeyFile); err != nil { + return err + } else { + canReadCertAndKey = canRead + } } + if !canReadCertAndKey { // add either the bind address or localhost to the valid alternates bindIP := s.BindAddress.String() @@ -282,15 +301,21 @@ func (s *SecureServingOptions) MaybeDefaultWithSelfSignedCerts(publicAddress str if cert, key, err := certutil.GenerateSelfSignedCertKeyWithFixtures(publicAddress, alternateIPs, alternateDNS, s.ServerCert.FixtureDirectory); err != nil { return fmt.Errorf("unable to generate self signed cert: %v", err) - } else { + } else if len(keyCert.CertFile) > 0 && len(keyCert.KeyFile) > 0 { if err := certutil.WriteCert(keyCert.CertFile, cert); err != nil { return err } - if err := certutil.WriteKey(keyCert.KeyFile, key); err != nil { return err } glog.Infof("Generated self-signed cert (%s, %s)", keyCert.CertFile, keyCert.KeyFile) + } else { + tlsCert, err := tls.X509KeyPair(cert, key) + if err != nil { + return fmt.Errorf("unable to generate self signed cert: %v", err) + } + s.ServerCert.GeneratedCert = &tlsCert + glog.Infof("Generated self-signed cert in-memory") } } diff --git a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/OWNERS b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/OWNERS new file mode 100644 index 0000000000000..498b470c9bfca --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-encryption-at-rest-approvers +reviewers: +- sig-auth-encryption-at-rest-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD b/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD index b9b2b2d9f3abc..d8b203700079a 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD @@ -13,17 +13,21 @@ go_library( "client.go", "error.go", "serviceresolver.go", + "validation.go", "webhook.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/util/webhook", importpath = "k8s.io/apiserver/pkg/util/webhook", deps = [ + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/client-go/rest:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/authentication.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/authentication.go index f6d79dea36231..1d1c0ad3bc9d9 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/authentication.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/authentication.go @@ -19,9 +19,11 @@ package webhook import ( "fmt" "io/ioutil" + "net/http" "strings" "time" + corev1 "k8s.io/api/core/v1" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" @@ -31,6 +33,37 @@ import ( // rest.Config generated by the resolver. type AuthenticationInfoResolverWrapper func(AuthenticationInfoResolver) AuthenticationInfoResolver +// NewDefaultAuthenticationInfoResolverWrapper builds a default authn resolver wrapper +func NewDefaultAuthenticationInfoResolverWrapper( + proxyTransport *http.Transport, + kubeapiserverClientConfig *rest.Config) AuthenticationInfoResolverWrapper { + + webhookAuthResolverWrapper := func(delegate AuthenticationInfoResolver) AuthenticationInfoResolver { + return &AuthenticationInfoResolverDelegator{ + ClientConfigForFunc: func(server string) (*rest.Config, error) { + if server == "kubernetes.default.svc" { + return kubeapiserverClientConfig, nil + } + return delegate.ClientConfigFor(server) + }, + ClientConfigForServiceFunc: func(serviceName, serviceNamespace string) (*rest.Config, error) { + if serviceName == "kubernetes" && serviceNamespace == corev1.NamespaceDefault { + return kubeapiserverClientConfig, nil + } + ret, err := delegate.ClientConfigForService(serviceName, serviceNamespace) + if err != nil { + return nil, err + } + if proxyTransport != nil && proxyTransport.DialContext != nil { + ret.Dial = proxyTransport.DialContext + } + return ret, err + }, + } + } + return webhookAuthResolverWrapper +} + // AuthenticationInfoResolver builds rest.Config base on the server or service // name and service namespace. type AuthenticationInfoResolver interface { diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/validation.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/validation.go new file mode 100644 index 0000000000000..2ddb2c09ab7a9 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/validation.go @@ -0,0 +1,101 @@ +/* +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 webhook + +import ( + "fmt" + "net/url" + "strings" + + "k8s.io/apimachinery/pkg/util/validation" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +// ValidateWebhookURL validates webhook's URL. +func ValidateWebhookURL(fldPath *field.Path, URL string, forceHttps bool) field.ErrorList { + var allErrors field.ErrorList + const form = "; desired format: https://host[/path]" + if u, err := url.Parse(URL); err != nil { + allErrors = append(allErrors, field.Required(fldPath, "url must be a valid URL: "+err.Error()+form)) + } else { + if forceHttps && u.Scheme != "https" { + allErrors = append(allErrors, field.Invalid(fldPath, u.Scheme, "'https' is the only allowed URL scheme"+form)) + } + if len(u.Host) == 0 { + allErrors = append(allErrors, field.Invalid(fldPath, u.Host, "host must be provided"+form)) + } + if u.User != nil { + allErrors = append(allErrors, field.Invalid(fldPath, u.User.String(), "user information is not permitted in the URL")) + } + if len(u.Fragment) != 0 { + allErrors = append(allErrors, field.Invalid(fldPath, u.Fragment, "fragments are not permitted in the URL")) + } + if len(u.RawQuery) != 0 { + allErrors = append(allErrors, field.Invalid(fldPath, u.RawQuery, "query parameters are not permitted in the URL")) + } + } + return allErrors +} + +func ValidateWebhookService(fldPath *field.Path, namespace, name string, path *string) field.ErrorList { + var allErrors field.ErrorList + + if len(name) == 0 { + allErrors = append(allErrors, field.Required(fldPath.Child("name"), "service name is required")) + } + + if len(namespace) == 0 { + allErrors = append(allErrors, field.Required(fldPath.Child("namespace"), "service namespace is required")) + } + + if path == nil { + return allErrors + } + + // TODO: replace below with url.Parse + verifying that host is empty? + + urlPath := *path + if urlPath == "/" || len(urlPath) == 0 { + return allErrors + } + if urlPath == "//" { + allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, "segment[0] may not be empty")) + return allErrors + } + + if !strings.HasPrefix(urlPath, "/") { + allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, "must start with a '/'")) + } + + urlPathToCheck := urlPath[1:] + if strings.HasSuffix(urlPathToCheck, "/") { + urlPathToCheck = urlPathToCheck[:len(urlPathToCheck)-1] + } + steps := strings.Split(urlPathToCheck, "/") + for i, step := range steps { + if len(step) == 0 { + allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, fmt.Sprintf("segment[%d] may not be empty", i))) + continue + } + failures := validation.IsDNS1123Subdomain(step) + for _, failure := range failures { + allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), urlPath, fmt.Sprintf("segment[%d]: %v", i, failure))) + } + } + + return allErrors +} diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/audit/OWNERS b/staging/src/k8s.io/apiserver/plugin/pkg/audit/OWNERS new file mode 100644 index 0000000000000..178ce84a5ce3e --- /dev/null +++ b/staging/src/k8s.io/apiserver/plugin/pkg/audit/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-audit-approvers +reviewers: +- sig-auth-audit-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/OWNERS b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/OWNERS new file mode 100644 index 0000000000000..c607d2aa8c5fe --- /dev/null +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers +reviewers: +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go index 12a46a57d895f..f53fc2ddd4c7c 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go @@ -89,7 +89,7 @@ type Options struct { UsernamePrefix string // GroupsClaim, if specified, causes the OIDCAuthenticator to try to populate the user's - // groups with an ID Token field. If the GrouppClaim field is present in an ID Token the value + // groups with an ID Token field. If the GroupsClaim field is present in an ID Token the value // must be a string or list of strings. GroupsClaim string diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/BUILD b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/BUILD index fd4af99aa5517..fc926d1f75c71 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/BUILD +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/BUILD @@ -16,6 +16,8 @@ go_test( deps = [ "//staging/src/k8s.io/api/authentication/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/authentication/token/cache:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library", ], @@ -30,7 +32,6 @@ go_library( "//staging/src/k8s.io/api/authentication/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/cache:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go index 90104df54943a..f462276f5bbb7 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go @@ -26,7 +26,6 @@ import ( authentication "k8s.io/api/authentication/v1beta1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/cache" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/util/webhook" @@ -45,28 +44,29 @@ var _ authenticator.Token = (*WebhookTokenAuthenticator)(nil) type WebhookTokenAuthenticator struct { tokenReview authenticationclient.TokenReviewInterface - responseCache *cache.LRUExpireCache - ttl time.Duration initialBackoff time.Duration } -// NewFromInterface creates a webhook authenticator using the given tokenReview client -func NewFromInterface(tokenReview authenticationclient.TokenReviewInterface, ttl time.Duration) (*WebhookTokenAuthenticator, error) { - return newWithBackoff(tokenReview, ttl, retryBackoff) +// NewFromInterface creates a webhook authenticator using the given tokenReview +// client. It is recommend to wrap this authenticator with the token cache +// authenticator implemented in +// k8s.io/apiserver/pkg/authentication/token/cache. +func NewFromInterface(tokenReview authenticationclient.TokenReviewInterface) (*WebhookTokenAuthenticator, error) { + return newWithBackoff(tokenReview, retryBackoff) } // New creates a new WebhookTokenAuthenticator from the provided kubeconfig file. -func New(kubeConfigFile string, ttl time.Duration) (*WebhookTokenAuthenticator, error) { +func New(kubeConfigFile string) (*WebhookTokenAuthenticator, error) { tokenReview, err := tokenReviewInterfaceFromKubeconfig(kubeConfigFile) if err != nil { return nil, err } - return newWithBackoff(tokenReview, ttl, retryBackoff) + return newWithBackoff(tokenReview, retryBackoff) } // newWithBackoff allows tests to skip the sleep. -func newWithBackoff(tokenReview authenticationclient.TokenReviewInterface, ttl, initialBackoff time.Duration) (*WebhookTokenAuthenticator, error) { - return &WebhookTokenAuthenticator{tokenReview, cache.NewLRUExpireCache(1024), ttl, initialBackoff}, nil +func newWithBackoff(tokenReview authenticationclient.TokenReviewInterface, initialBackoff time.Duration) (*WebhookTokenAuthenticator, error) { + return &WebhookTokenAuthenticator{tokenReview, initialBackoff}, nil } // AuthenticateToken implements the authenticator.Token interface. @@ -74,25 +74,20 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token r := &authentication.TokenReview{ Spec: authentication.TokenReviewSpec{Token: token}, } - if entry, ok := w.responseCache.Get(r.Spec); ok { - r.Status = entry.(authentication.TokenReviewStatus) - } else { - var ( - result *authentication.TokenReview - err error - ) - webhook.WithExponentialBackoff(w.initialBackoff, func() error { - result, err = w.tokenReview.Create(r) - return err - }) - if err != nil { - // An error here indicates bad configuration or an outage. Log for debugging. - glog.Errorf("Failed to make webhook authenticator request: %v", err) - return nil, false, err - } - r.Status = result.Status - w.responseCache.Add(r.Spec, result.Status, w.ttl) + var ( + result *authentication.TokenReview + err error + ) + webhook.WithExponentialBackoff(w.initialBackoff, func() error { + result, err = w.tokenReview.Create(r) + return err + }) + if err != nil { + // An error here indicates bad configuration or an outage. Log for debugging. + glog.Errorf("Failed to make webhook authenticator request: %v", err) + return nil, false, err } + r.Status = result.Status if !r.Status.Authenticated { return nil, false, nil } diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook_test.go index bd2d00bf72240..2544e2429d137 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook_test.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook_test.go @@ -33,6 +33,8 @@ import ( "k8s.io/api/authentication/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/authentication/authenticator" + "k8s.io/apiserver/pkg/authentication/token/cache" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/client-go/tools/clientcmd/api/v1" ) @@ -166,7 +168,7 @@ func (m *mockService) HTTPStatusCode() int { return m.statusCode } // newTokenAuthenticator creates a temporary kubeconfig file from the provided // arguments and attempts to load a new WebhookTokenAuthenticator from it. -func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, cacheTime time.Duration) (*WebhookTokenAuthenticator, error) { +func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, cacheTime time.Duration) (authenticator.Token, error) { tempfile, err := ioutil.TempFile("", "") if err != nil { return nil, err @@ -194,7 +196,12 @@ func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, c return nil, err } - return newWithBackoff(c, cacheTime, 0) + authn, err := newWithBackoff(c, 0) + if err != nil { + return nil, err + } + + return cache.New(authn, false, cacheTime, cacheTime), nil } func TestTLSConfig(t *testing.T) { @@ -549,15 +556,12 @@ func TestWebhookCacheAndRetry(t *testing.T) { _, ok, err := wh.AuthenticateToken(context.Background(), testcase.token) hasError := err != nil if hasError != testcase.expectError { - t.Log(testcase.description) t.Errorf("Webhook returned HTTP %d, expected error=%v, but got error %v", testcase.code, testcase.expectError, err) } if serv.called != testcase.expectCalls { - t.Log(testcase.description) t.Errorf("Expected %d calls, got %d", testcase.expectCalls, serv.called) } if ok != testcase.expectOk { - t.Log(testcase.description) t.Errorf("Expected ok=%v, got %v", testcase.expectOk, ok) } }) diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/OWNERS b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/cli-runtime/Godeps/Godeps.json b/staging/src/k8s.io/cli-runtime/Godeps/Godeps.json index 280521d273195..b39e00a6a135b 100644 --- a/staging/src/k8s.io/cli-runtime/Godeps/Godeps.json +++ b/staging/src/k8s.io/cli-runtime/Godeps/Godeps.json @@ -124,23 +124,23 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", diff --git a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder.go b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder.go index 6a0d954f80b93..42f660a4e53f5 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder.go +++ b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder.go @@ -1089,9 +1089,10 @@ func (b *Builder) Do() *Result { if b.requireObject { helpers = append(helpers, RetrieveLazy) } - r.visitor = NewDecoratedVisitor(r.visitor, helpers...) if b.continueOnError { - r.visitor = ContinueOnErrorVisitor{r.visitor} + r.visitor = NewDecoratedVisitor(ContinueOnErrorVisitor{r.visitor}, helpers...) + } else { + r.visitor = NewDecoratedVisitor(r.visitor, helpers...) } return r } diff --git a/staging/src/k8s.io/client-go/Godeps/Godeps.json b/staging/src/k8s.io/client-go/Godeps/Godeps.json index a3221a7213db4..156d5972c651f 100644 --- a/staging/src/k8s.io/client-go/Godeps/Godeps.json +++ b/staging/src/k8s.io/client-go/Godeps/Godeps.json @@ -16,27 +16,27 @@ }, { "ImportPath": "github.com/Azure/go-autorest/autorest", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/autorest/adal", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/autorest/azure", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/autorest/date", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/logger", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/Azure/go-autorest/version", - "Rev": "a88c19ef2016e095f0b6c3b451074b4663f53bed" + "Rev": "ea233b6412b0421a65dc6160e16c893364664a95" }, { "ImportPath": "github.com/davecgh/go-spew/spew", @@ -200,27 +200,27 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/context/ctxhttp", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -616,7 +616,7 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" } ] } diff --git a/staging/src/k8s.io/client-go/examples/create-update-delete-deployment/README.md b/staging/src/k8s.io/client-go/examples/create-update-delete-deployment/README.md index 47d8dd1ee5448..72cfc5d91dbe5 100644 --- a/staging/src/k8s.io/client-go/examples/create-update-delete-deployment/README.md +++ b/staging/src/k8s.io/client-go/examples/create-update-delete-deployment/README.md @@ -49,7 +49,7 @@ Running this command will execute the following operations on your cluster: Each step is separated by an interactive prompt. You must hit the Return key to proceed to the next step. You can use these prompts as -a break to take time to run `kubectl` and inspect the result of the operations +a break to take time to run `kubectl` and inspect the result of the operations executed. You should see an output like the following: diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/BUILD index 17bd3fad4d77d..dd54b316b6149 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/BUILD @@ -17,6 +17,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//staging/src/k8s.io/api/apps/v1:go_default_library", + "//staging/src/k8s.io/api/autoscaling/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/deployment.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/deployment.go index 73d46f8bb6cb3..503eb4b73304b 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/deployment.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/deployment.go @@ -20,6 +20,7 @@ package v1 import ( v1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" @@ -44,6 +45,9 @@ type DeploymentInterface interface { List(opts metav1.ListOptions) (*v1.DeploymentList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Deployment, err error) + GetScale(deploymentName string, options metav1.GetOptions) (*autoscalingv1.Scale, error) + UpdateScale(deploymentName string, scale *autoscalingv1.Scale) (*autoscalingv1.Scale, error) + DeploymentExpansion } @@ -172,3 +176,31 @@ func (c *deployments) Patch(name string, pt types.PatchType, data []byte, subres Into(result) return } + +// GetScale takes name of the deployment, and returns the corresponding autoscalingv1.Scale object, and an error if there is any. +func (c *deployments) GetScale(deploymentName string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { + result = &autoscalingv1.Scale{} + err = c.client.Get(). + Namespace(c.ns). + Resource("deployments"). + Name(deploymentName). + SubResource("scale"). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// UpdateScale takes the top resource name and the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. +func (c *deployments) UpdateScale(deploymentName string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) { + result = &autoscalingv1.Scale{} + err = c.client.Put(). + Namespace(c.ns). + Resource("deployments"). + Name(deploymentName). + SubResource("scale"). + Body(scale). + Do(). + Into(result) + return +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/BUILD index 6202fc55ddfc3..d01abefea0cda 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/BUILD @@ -16,6 +16,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//staging/src/k8s.io/api/apps/v1:go_default_library", + "//staging/src/k8s.io/api/autoscaling/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_deployment.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_deployment.go index a5786fd5ebde0..6a8cb379da81b 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_deployment.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_deployment.go @@ -20,6 +20,7 @@ package fake import ( appsv1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -138,3 +139,25 @@ func (c *FakeDeployments) Patch(name string, pt types.PatchType, data []byte, su } return obj.(*appsv1.Deployment), err } + +// GetScale takes name of the deployment, and returns the corresponding scale object, and an error if there is any. +func (c *FakeDeployments) GetScale(deploymentName string, options v1.GetOptions) (result *autoscalingv1.Scale, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetSubresourceAction(deploymentsResource, c.ns, "scale", deploymentName), &autoscalingv1.Scale{}) + + if obj == nil { + return nil, err + } + return obj.(*autoscalingv1.Scale), err +} + +// UpdateScale takes the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. +func (c *FakeDeployments) UpdateScale(deploymentName string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(deploymentsResource, "scale", c.ns, scale), &autoscalingv1.Scale{}) + + if obj == nil { + return nil, err + } + return obj.(*autoscalingv1.Scale), err +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_replicaset.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_replicaset.go index d6a7c059fc2fd..e871f82f76614 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_replicaset.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_replicaset.go @@ -20,6 +20,7 @@ package fake import ( appsv1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -138,3 +139,25 @@ func (c *FakeReplicaSets) Patch(name string, pt types.PatchType, data []byte, su } return obj.(*appsv1.ReplicaSet), err } + +// GetScale takes name of the replicaSet, and returns the corresponding scale object, and an error if there is any. +func (c *FakeReplicaSets) GetScale(replicaSetName string, options v1.GetOptions) (result *autoscalingv1.Scale, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetSubresourceAction(replicasetsResource, c.ns, "scale", replicaSetName), &autoscalingv1.Scale{}) + + if obj == nil { + return nil, err + } + return obj.(*autoscalingv1.Scale), err +} + +// UpdateScale takes the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. +func (c *FakeReplicaSets) UpdateScale(replicaSetName string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(replicasetsResource, "scale", c.ns, scale), &autoscalingv1.Scale{}) + + if obj == nil { + return nil, err + } + return obj.(*autoscalingv1.Scale), err +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_statefulset.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_statefulset.go index 0682a9990ea94..83e80bff4973c 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_statefulset.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_statefulset.go @@ -20,6 +20,7 @@ package fake import ( appsv1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -138,3 +139,25 @@ func (c *FakeStatefulSets) Patch(name string, pt types.PatchType, data []byte, s } return obj.(*appsv1.StatefulSet), err } + +// GetScale takes name of the statefulSet, and returns the corresponding scale object, and an error if there is any. +func (c *FakeStatefulSets) GetScale(statefulSetName string, options v1.GetOptions) (result *autoscalingv1.Scale, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetSubresourceAction(statefulsetsResource, c.ns, "scale", statefulSetName), &autoscalingv1.Scale{}) + + if obj == nil { + return nil, err + } + return obj.(*autoscalingv1.Scale), err +} + +// UpdateScale takes the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. +func (c *FakeStatefulSets) UpdateScale(statefulSetName string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(statefulsetsResource, "scale", c.ns, scale), &autoscalingv1.Scale{}) + + if obj == nil { + return nil, err + } + return obj.(*autoscalingv1.Scale), err +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/replicaset.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/replicaset.go index 077941162d022..ea6efb6861782 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/replicaset.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/replicaset.go @@ -20,6 +20,7 @@ package v1 import ( v1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" @@ -44,6 +45,9 @@ type ReplicaSetInterface interface { List(opts metav1.ListOptions) (*v1.ReplicaSetList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.ReplicaSet, err error) + GetScale(replicaSetName string, options metav1.GetOptions) (*autoscalingv1.Scale, error) + UpdateScale(replicaSetName string, scale *autoscalingv1.Scale) (*autoscalingv1.Scale, error) + ReplicaSetExpansion } @@ -172,3 +176,31 @@ func (c *replicaSets) Patch(name string, pt types.PatchType, data []byte, subres Into(result) return } + +// GetScale takes name of the replicaSet, and returns the corresponding autoscalingv1.Scale object, and an error if there is any. +func (c *replicaSets) GetScale(replicaSetName string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { + result = &autoscalingv1.Scale{} + err = c.client.Get(). + Namespace(c.ns). + Resource("replicasets"). + Name(replicaSetName). + SubResource("scale"). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// UpdateScale takes the top resource name and the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. +func (c *replicaSets) UpdateScale(replicaSetName string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) { + result = &autoscalingv1.Scale{} + err = c.client.Put(). + Namespace(c.ns). + Resource("replicasets"). + Name(replicaSetName). + SubResource("scale"). + Body(scale). + Do(). + Into(result) + return +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/statefulset.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/statefulset.go index 54322d97d31b1..66e522ba124a4 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/statefulset.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1/statefulset.go @@ -20,6 +20,7 @@ package v1 import ( v1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" @@ -44,6 +45,9 @@ type StatefulSetInterface interface { List(opts metav1.ListOptions) (*v1.StatefulSetList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.StatefulSet, err error) + GetScale(statefulSetName string, options metav1.GetOptions) (*autoscalingv1.Scale, error) + UpdateScale(statefulSetName string, scale *autoscalingv1.Scale) (*autoscalingv1.Scale, error) + StatefulSetExpansion } @@ -172,3 +176,31 @@ func (c *statefulSets) Patch(name string, pt types.PatchType, data []byte, subre Into(result) return } + +// GetScale takes name of the statefulSet, and returns the corresponding autoscalingv1.Scale object, and an error if there is any. +func (c *statefulSets) GetScale(statefulSetName string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { + result = &autoscalingv1.Scale{} + err = c.client.Get(). + Namespace(c.ns). + Resource("statefulsets"). + Name(statefulSetName). + SubResource("scale"). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// UpdateScale takes the top resource name and the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. +func (c *statefulSets) UpdateScale(statefulSetName string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) { + result = &autoscalingv1.Scale{} + err = c.client.Put(). + Namespace(c.ns). + Resource("statefulsets"). + Name(statefulSetName). + SubResource("scale"). + Body(scale). + Do(). + Into(result) + return +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/BUILD index 34a2f829d1d9b..f9fe3d400b317 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/BUILD @@ -13,7 +13,6 @@ go_library( "deployment.go", "doc.go", "generated_expansion.go", - "scale.go", "statefulset.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/apps_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/apps_client.go index 4d882e26e7d74..2c9db886b1e28 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/apps_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/apps_client.go @@ -29,7 +29,6 @@ type AppsV1beta1Interface interface { RESTClient() rest.Interface ControllerRevisionsGetter DeploymentsGetter - ScalesGetter StatefulSetsGetter } @@ -46,10 +45,6 @@ func (c *AppsV1beta1Client) Deployments(namespace string) DeploymentInterface { return newDeployments(c, namespace) } -func (c *AppsV1beta1Client) Scales(namespace string) ScaleInterface { - return newScales(c, namespace) -} - func (c *AppsV1beta1Client) StatefulSets(namespace string) StatefulSetInterface { return newStatefulSets(c, namespace) } diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/BUILD index d4460b98b6ce9..c3bc1b48cd42a 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/BUILD @@ -12,7 +12,6 @@ go_library( "fake_apps_client.go", "fake_controllerrevision.go", "fake_deployment.go", - "fake_scale.go", "fake_statefulset.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_apps_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_apps_client.go index 2ff602be9b6fe..8e65d78d29ae6 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_apps_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_apps_client.go @@ -36,10 +36,6 @@ func (c *FakeAppsV1beta1) Deployments(namespace string) v1beta1.DeploymentInterf return &FakeDeployments{c, namespace} } -func (c *FakeAppsV1beta1) Scales(namespace string) v1beta1.ScaleInterface { - return &FakeScales{c, namespace} -} - func (c *FakeAppsV1beta1) StatefulSets(namespace string) v1beta1.StatefulSetInterface { return &FakeStatefulSets{c, namespace} } diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/generated_expansion.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/generated_expansion.go index b2bfd73a77bd1..113455df24c59 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/generated_expansion.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/generated_expansion.go @@ -22,6 +22,4 @@ type ControllerRevisionExpansion interface{} type DeploymentExpansion interface{} -type ScaleExpansion interface{} - type StatefulSetExpansion interface{} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/scale.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/scale.go deleted file mode 100644 index cef27bd1457cd..0000000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta1/scale.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1beta1 - -import ( - rest "k8s.io/client-go/rest" -) - -// ScalesGetter has a method to return a ScaleInterface. -// A group's client should implement this interface. -type ScalesGetter interface { - Scales(namespace string) ScaleInterface -} - -// ScaleInterface has methods to work with Scale resources. -type ScaleInterface interface { - ScaleExpansion -} - -// scales implements ScaleInterface -type scales struct { - client rest.Interface - ns string -} - -// newScales returns a Scales -func newScales(c *AppsV1beta1Client, namespace string) *scales { - return &scales{ - client: c.RESTClient(), - ns: namespace, - } -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/BUILD index 246b4327fd72d..9edb752483863 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/BUILD @@ -15,7 +15,6 @@ go_library( "doc.go", "generated_expansion.go", "replicaset.go", - "scale.go", "statefulset.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/apps_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/apps_client.go index 27549499fb68d..99d677f405029 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/apps_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/apps_client.go @@ -31,7 +31,6 @@ type AppsV1beta2Interface interface { DaemonSetsGetter DeploymentsGetter ReplicaSetsGetter - ScalesGetter StatefulSetsGetter } @@ -56,10 +55,6 @@ func (c *AppsV1beta2Client) ReplicaSets(namespace string) ReplicaSetInterface { return newReplicaSets(c, namespace) } -func (c *AppsV1beta2Client) Scales(namespace string) ScaleInterface { - return newScales(c, namespace) -} - func (c *AppsV1beta2Client) StatefulSets(namespace string) StatefulSetInterface { return newStatefulSets(c, namespace) } diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/BUILD index 37b34afd975ac..642f08c79c55c 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/BUILD @@ -14,7 +14,6 @@ go_library( "fake_daemonset.go", "fake_deployment.go", "fake_replicaset.go", - "fake_scale.go", "fake_statefulset.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_apps_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_apps_client.go index f7d79d3522588..0ec34a2cdbc3d 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_apps_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_apps_client.go @@ -44,10 +44,6 @@ func (c *FakeAppsV1beta2) ReplicaSets(namespace string) v1beta2.ReplicaSetInterf return &FakeReplicaSets{c, namespace} } -func (c *FakeAppsV1beta2) Scales(namespace string) v1beta2.ScaleInterface { - return &FakeScales{c, namespace} -} - func (c *FakeAppsV1beta2) StatefulSets(namespace string) v1beta2.StatefulSetInterface { return &FakeStatefulSets{c, namespace} } diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_scale.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_scale.go deleted file mode 100644 index b06b7e8e303e8..0000000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_scale.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -// FakeScales implements ScaleInterface -type FakeScales struct { - Fake *FakeAppsV1beta2 - ns string -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/generated_expansion.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/generated_expansion.go index bceae5986233e..6a21749687d22 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/generated_expansion.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/generated_expansion.go @@ -26,6 +26,4 @@ type DeploymentExpansion interface{} type ReplicaSetExpansion interface{} -type ScaleExpansion interface{} - type StatefulSetExpansion interface{} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/scale.go b/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/scale.go deleted file mode 100644 index f8d6a7fb0f800..0000000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/apps/v1beta2/scale.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1beta2 - -import ( - rest "k8s.io/client-go/rest" -) - -// ScalesGetter has a method to return a ScaleInterface. -// A group's client should implement this interface. -type ScalesGetter interface { - Scales(namespace string) ScaleInterface -} - -// ScaleInterface has methods to work with Scale resources. -type ScaleInterface interface { - ScaleExpansion -} - -// scales implements ScaleInterface -type scales struct { - client rest.Interface - ns string -} - -// newScales returns a Scales -func newScales(c *AppsV1beta2Client, namespace string) *scales { - return &scales{ - client: c.RESTClient(), - ns: namespace, - } -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/authentication/OWNERS b/staging/src/k8s.io/client-go/kubernetes/typed/authentication/OWNERS new file mode 100644 index 0000000000000..c607d2aa8c5fe --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/authentication/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers +reviewers: +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/authorization/OWNERS b/staging/src/k8s.io/client-go/kubernetes/typed/authorization/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/authorization/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/BUILD index 76f16bfa13e18..1377227a6096e 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/BUILD @@ -38,8 +38,8 @@ go_library( importpath = "k8s.io/client-go/kubernetes/typed/core/v1", deps = [ "//staging/src/k8s.io/api/authentication/v1:go_default_library", + "//staging/src/k8s.io/api/autoscaling/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", - "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/api/policy/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/fake/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/fake/BUILD index 32c81b04af76a..022c147acd59b 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/fake/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/fake/BUILD @@ -37,8 +37,8 @@ go_library( importpath = "k8s.io/client-go/kubernetes/typed/core/v1/fake", deps = [ "//staging/src/k8s.io/api/authentication/v1:go_default_library", + "//staging/src/k8s.io/api/autoscaling/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", - "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/api/policy/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_replicationcontroller.go b/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_replicationcontroller.go index f830d7da7fd03..6de94c14829b9 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_replicationcontroller.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_replicationcontroller.go @@ -19,8 +19,8 @@ limitations under the License. package fake import ( + autoscalingv1 "k8s.io/api/autoscaling/v1" corev1 "k8s.io/api/core/v1" - v1beta1 "k8s.io/api/extensions/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -141,23 +141,23 @@ func (c *FakeReplicationControllers) Patch(name string, pt types.PatchType, data } // GetScale takes name of the replicationController, and returns the corresponding scale object, and an error if there is any. -func (c *FakeReplicationControllers) GetScale(replicationControllerName string, options v1.GetOptions) (result *v1beta1.Scale, err error) { +func (c *FakeReplicationControllers) GetScale(replicationControllerName string, options v1.GetOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. - Invokes(testing.NewGetSubresourceAction(replicationcontrollersResource, c.ns, "scale", replicationControllerName), &v1beta1.Scale{}) + Invokes(testing.NewGetSubresourceAction(replicationcontrollersResource, c.ns, "scale", replicationControllerName), &autoscalingv1.Scale{}) if obj == nil { return nil, err } - return obj.(*v1beta1.Scale), err + return obj.(*autoscalingv1.Scale), err } // UpdateScale takes the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. -func (c *FakeReplicationControllers) UpdateScale(replicationControllerName string, scale *v1beta1.Scale) (result *v1beta1.Scale, err error) { +func (c *FakeReplicationControllers) UpdateScale(replicationControllerName string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(replicationcontrollersResource, "scale", c.ns, scale), &v1beta1.Scale{}) + Invokes(testing.NewUpdateSubresourceAction(replicationcontrollersResource, "scale", c.ns, scale), &autoscalingv1.Scale{}) if obj == nil { return nil, err } - return obj.(*v1beta1.Scale), err + return obj.(*autoscalingv1.Scale), err } diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/replicationcontroller.go b/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/replicationcontroller.go index 17622f1c26096..f3e41612433d4 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/replicationcontroller.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/core/v1/replicationcontroller.go @@ -19,8 +19,8 @@ limitations under the License. package v1 import ( + autoscalingv1 "k8s.io/api/autoscaling/v1" v1 "k8s.io/api/core/v1" - v1beta1 "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" @@ -45,8 +45,8 @@ type ReplicationControllerInterface interface { List(opts metav1.ListOptions) (*v1.ReplicationControllerList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.ReplicationController, err error) - GetScale(replicationControllerName string, options metav1.GetOptions) (*v1beta1.Scale, error) - UpdateScale(replicationControllerName string, scale *v1beta1.Scale) (*v1beta1.Scale, error) + GetScale(replicationControllerName string, options metav1.GetOptions) (*autoscalingv1.Scale, error) + UpdateScale(replicationControllerName string, scale *autoscalingv1.Scale) (*autoscalingv1.Scale, error) ReplicationControllerExpansion } @@ -177,9 +177,9 @@ func (c *replicationControllers) Patch(name string, pt types.PatchType, data []b return } -// GetScale takes name of the replicationController, and returns the corresponding v1beta1.Scale object, and an error if there is any. -func (c *replicationControllers) GetScale(replicationControllerName string, options metav1.GetOptions) (result *v1beta1.Scale, err error) { - result = &v1beta1.Scale{} +// GetScale takes name of the replicationController, and returns the corresponding autoscalingv1.Scale object, and an error if there is any. +func (c *replicationControllers) GetScale(replicationControllerName string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { + result = &autoscalingv1.Scale{} err = c.client.Get(). Namespace(c.ns). Resource("replicationcontrollers"). @@ -192,8 +192,8 @@ func (c *replicationControllers) GetScale(replicationControllerName string, opti } // UpdateScale takes the top resource name and the representation of a scale and updates it. Returns the server's representation of the scale, and an error, if there is any. -func (c *replicationControllers) UpdateScale(replicationControllerName string, scale *v1beta1.Scale) (result *v1beta1.Scale, err error) { - result = &v1beta1.Scale{} +func (c *replicationControllers) UpdateScale(replicationControllerName string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) { + result = &autoscalingv1.Scale{} err = c.client.Put(). Namespace(c.ns). Resource("replicationcontrollers"). diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/BUILD index 062da6216a16d..6690d96b0bb7d 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/BUILD @@ -17,16 +17,12 @@ go_library( "ingress.go", "podsecuritypolicy.go", "replicaset.go", - "scale.go", - "scale_expansion.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1", importpath = "k8s.io/client-go/kubernetes/typed/extensions/v1beta1", deps = [ "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/meta: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", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go index 1961ffc7cda0a..0e9edf5cce60f 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go @@ -32,7 +32,6 @@ type ExtensionsV1beta1Interface interface { IngressesGetter PodSecurityPoliciesGetter ReplicaSetsGetter - ScalesGetter } // ExtensionsV1beta1Client is used to interact with features provided by the extensions group. @@ -60,10 +59,6 @@ func (c *ExtensionsV1beta1Client) ReplicaSets(namespace string) ReplicaSetInterf return newReplicaSets(c, namespace) } -func (c *ExtensionsV1beta1Client) Scales(namespace string) ScaleInterface { - return newScales(c, namespace) -} - // NewForConfig creates a new ExtensionsV1beta1Client for the given config. func NewForConfig(c *rest.Config) (*ExtensionsV1beta1Client, error) { config := *c diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/BUILD b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/BUILD index d0a83e23efa0b..5de2b7dfebff5 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/BUILD +++ b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/BUILD @@ -16,8 +16,6 @@ go_library( "fake_ingress.go", "fake_podsecuritypolicy.go", "fake_replicaset.go", - "fake_scale.go", - "fake_scale_expansion.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake", importpath = "k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake", diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_extensions_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_extensions_client.go index 1aba34f9dcb80..0282c0b49908b 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_extensions_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_extensions_client.go @@ -48,10 +48,6 @@ func (c *FakeExtensionsV1beta1) ReplicaSets(namespace string) v1beta1.ReplicaSet return &FakeReplicaSets{c, namespace} } -func (c *FakeExtensionsV1beta1) Scales(namespace string) v1beta1.ScaleInterface { - return &FakeScales{c, namespace} -} - // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeExtensionsV1beta1) RESTClient() rest.Interface { diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_scale.go b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_scale.go deleted file mode 100644 index 02c4d0bab73ff..0000000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_scale.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -// FakeScales implements ScaleInterface -type FakeScales struct { - Fake *FakeExtensionsV1beta1 - ns string -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_scale_expansion.go b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_scale_expansion.go deleted file mode 100644 index 1f1d49ba1a9ff..0000000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_scale_expansion.go +++ /dev/null @@ -1,47 +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 fake - -import ( - "k8s.io/api/extensions/v1beta1" - "k8s.io/apimachinery/pkg/runtime/schema" - core "k8s.io/client-go/testing" -) - -func (c *FakeScales) Get(kind string, name string) (result *v1beta1.Scale, err error) { - action := core.GetActionImpl{} - action.Verb = "get" - action.Namespace = c.ns - action.Resource = schema.GroupVersionResource{Resource: kind} - action.Subresource = "scale" - action.Name = name - obj, err := c.Fake.Invokes(action, &v1beta1.Scale{}) - result = obj.(*v1beta1.Scale) - return -} - -func (c *FakeScales) Update(kind string, scale *v1beta1.Scale) (result *v1beta1.Scale, err error) { - action := core.UpdateActionImpl{} - action.Verb = "update" - action.Namespace = c.ns - action.Resource = schema.GroupVersionResource{Resource: kind} - action.Subresource = "scale" - action.Object = scale - obj, err := c.Fake.Invokes(action, scale) - result = obj.(*v1beta1.Scale) - return -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/scale.go b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/scale.go deleted file mode 100644 index 6ee677acd290d..0000000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/scale.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1beta1 - -import ( - rest "k8s.io/client-go/rest" -) - -// ScalesGetter has a method to return a ScaleInterface. -// A group's client should implement this interface. -type ScalesGetter interface { - Scales(namespace string) ScaleInterface -} - -// ScaleInterface has methods to work with Scale resources. -type ScaleInterface interface { - ScaleExpansion -} - -// scales implements ScaleInterface -type scales struct { - client rest.Interface - ns string -} - -// newScales returns a Scales -func newScales(c *ExtensionsV1beta1Client, namespace string) *scales { - return &scales{ - client: c.RESTClient(), - ns: namespace, - } -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/scale_expansion.go b/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/scale_expansion.go deleted file mode 100644 index c9733cb28d2e7..0000000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/scale_expansion.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2016 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 v1beta1 - -import ( - "k8s.io/api/extensions/v1beta1" - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -// The ScaleExpansion interface allows manually adding extra methods to the ScaleInterface. -type ScaleExpansion interface { - Get(kind string, name string) (*v1beta1.Scale, error) - Update(kind string, scale *v1beta1.Scale) (*v1beta1.Scale, error) -} - -// Get takes the reference to scale subresource and returns the subresource or error, if one occurs. -func (c *scales) Get(kind string, name string) (result *v1beta1.Scale, err error) { - result = &v1beta1.Scale{} - - // TODO this method needs to take a proper unambiguous kind - fullyQualifiedKind := schema.GroupVersionKind{Kind: kind} - resource, _ := meta.UnsafeGuessKindToResource(fullyQualifiedKind) - - err = c.client.Get(). - Namespace(c.ns). - Resource(resource.Resource). - Name(name). - SubResource("scale"). - Do(). - Into(result) - return -} - -func (c *scales) Update(kind string, scale *v1beta1.Scale) (result *v1beta1.Scale, err error) { - result = &v1beta1.Scale{} - - // TODO this method needs to take a proper unambiguous kind - fullyQualifiedKind := schema.GroupVersionKind{Kind: kind} - resource, _ := meta.UnsafeGuessKindToResource(fullyQualifiedKind) - - err = c.client.Put(). - Namespace(scale.Namespace). - Resource(resource.Resource). - Name(scale.Name). - SubResource("scale"). - Body(scale). - Do(). - Into(result) - return -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/rbac/OWNERS b/staging/src/k8s.io/client-go/kubernetes/typed/rbac/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/rbac/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/listers/apps/v1beta1/BUILD b/staging/src/k8s.io/client-go/listers/apps/v1beta1/BUILD index 640f659934342..9d50008600d25 100644 --- a/staging/src/k8s.io/client-go/listers/apps/v1beta1/BUILD +++ b/staging/src/k8s.io/client-go/listers/apps/v1beta1/BUILD @@ -11,7 +11,6 @@ go_library( "controllerrevision.go", "deployment.go", "expansion_generated.go", - "scale.go", "statefulset.go", "statefulset_expansion.go", ], diff --git a/staging/src/k8s.io/client-go/listers/apps/v1beta1/expansion_generated.go b/staging/src/k8s.io/client-go/listers/apps/v1beta1/expansion_generated.go index 8f8d08434d8e2..c73cf98c7a591 100644 --- a/staging/src/k8s.io/client-go/listers/apps/v1beta1/expansion_generated.go +++ b/staging/src/k8s.io/client-go/listers/apps/v1beta1/expansion_generated.go @@ -33,11 +33,3 @@ type DeploymentListerExpansion interface{} // DeploymentNamespaceListerExpansion allows custom methods to be added to // DeploymentNamespaceLister. type DeploymentNamespaceListerExpansion interface{} - -// ScaleListerExpansion allows custom methods to be added to -// ScaleLister. -type ScaleListerExpansion interface{} - -// ScaleNamespaceListerExpansion allows custom methods to be added to -// ScaleNamespaceLister. -type ScaleNamespaceListerExpansion interface{} diff --git a/staging/src/k8s.io/client-go/listers/apps/v1beta1/scale.go b/staging/src/k8s.io/client-go/listers/apps/v1beta1/scale.go deleted file mode 100644 index ef8a2630ec31c..0000000000000 --- a/staging/src/k8s.io/client-go/listers/apps/v1beta1/scale.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/apps/v1beta1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// ScaleLister helps list Scales. -type ScaleLister interface { - // List lists all Scales in the indexer. - List(selector labels.Selector) (ret []*v1beta1.Scale, err error) - // Scales returns an object that can list and get Scales. - Scales(namespace string) ScaleNamespaceLister - ScaleListerExpansion -} - -// scaleLister implements the ScaleLister interface. -type scaleLister struct { - indexer cache.Indexer -} - -// NewScaleLister returns a new ScaleLister. -func NewScaleLister(indexer cache.Indexer) ScaleLister { - return &scaleLister{indexer: indexer} -} - -// List lists all Scales in the indexer. -func (s *scaleLister) List(selector labels.Selector) (ret []*v1beta1.Scale, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1beta1.Scale)) - }) - return ret, err -} - -// Scales returns an object that can list and get Scales. -func (s *scaleLister) Scales(namespace string) ScaleNamespaceLister { - return scaleNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ScaleNamespaceLister helps list and get Scales. -type ScaleNamespaceLister interface { - // List lists all Scales in the indexer for a given namespace. - List(selector labels.Selector) (ret []*v1beta1.Scale, err error) - // Get retrieves the Scale from the indexer for a given namespace and name. - Get(name string) (*v1beta1.Scale, error) - ScaleNamespaceListerExpansion -} - -// scaleNamespaceLister implements the ScaleNamespaceLister -// interface. -type scaleNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Scales in the indexer for a given namespace. -func (s scaleNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Scale, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1beta1.Scale)) - }) - return ret, err -} - -// Get retrieves the Scale from the indexer for a given namespace and name. -func (s scaleNamespaceLister) Get(name string) (*v1beta1.Scale, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1beta1.Resource("scale"), name) - } - return obj.(*v1beta1.Scale), nil -} diff --git a/staging/src/k8s.io/client-go/listers/apps/v1beta2/BUILD b/staging/src/k8s.io/client-go/listers/apps/v1beta2/BUILD index 20e24652c46ce..cbef24da637bf 100644 --- a/staging/src/k8s.io/client-go/listers/apps/v1beta2/BUILD +++ b/staging/src/k8s.io/client-go/listers/apps/v1beta2/BUILD @@ -16,7 +16,6 @@ go_library( "expansion_generated.go", "replicaset.go", "replicaset_expansion.go", - "scale.go", "statefulset.go", "statefulset_expansion.go", ], diff --git a/staging/src/k8s.io/client-go/listers/apps/v1beta2/expansion_generated.go b/staging/src/k8s.io/client-go/listers/apps/v1beta2/expansion_generated.go index d468f38e7c6d5..bac6ccb9a7a37 100644 --- a/staging/src/k8s.io/client-go/listers/apps/v1beta2/expansion_generated.go +++ b/staging/src/k8s.io/client-go/listers/apps/v1beta2/expansion_generated.go @@ -25,11 +25,3 @@ type ControllerRevisionListerExpansion interface{} // ControllerRevisionNamespaceListerExpansion allows custom methods to be added to // ControllerRevisionNamespaceLister. type ControllerRevisionNamespaceListerExpansion interface{} - -// ScaleListerExpansion allows custom methods to be added to -// ScaleLister. -type ScaleListerExpansion interface{} - -// ScaleNamespaceListerExpansion allows custom methods to be added to -// ScaleNamespaceLister. -type ScaleNamespaceListerExpansion interface{} diff --git a/staging/src/k8s.io/client-go/listers/apps/v1beta2/scale.go b/staging/src/k8s.io/client-go/listers/apps/v1beta2/scale.go deleted file mode 100644 index d89329864ae74..0000000000000 --- a/staging/src/k8s.io/client-go/listers/apps/v1beta2/scale.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v1beta2 - -import ( - v1beta2 "k8s.io/api/apps/v1beta2" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// ScaleLister helps list Scales. -type ScaleLister interface { - // List lists all Scales in the indexer. - List(selector labels.Selector) (ret []*v1beta2.Scale, err error) - // Scales returns an object that can list and get Scales. - Scales(namespace string) ScaleNamespaceLister - ScaleListerExpansion -} - -// scaleLister implements the ScaleLister interface. -type scaleLister struct { - indexer cache.Indexer -} - -// NewScaleLister returns a new ScaleLister. -func NewScaleLister(indexer cache.Indexer) ScaleLister { - return &scaleLister{indexer: indexer} -} - -// List lists all Scales in the indexer. -func (s *scaleLister) List(selector labels.Selector) (ret []*v1beta2.Scale, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1beta2.Scale)) - }) - return ret, err -} - -// Scales returns an object that can list and get Scales. -func (s *scaleLister) Scales(namespace string) ScaleNamespaceLister { - return scaleNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ScaleNamespaceLister helps list and get Scales. -type ScaleNamespaceLister interface { - // List lists all Scales in the indexer for a given namespace. - List(selector labels.Selector) (ret []*v1beta2.Scale, err error) - // Get retrieves the Scale from the indexer for a given namespace and name. - Get(name string) (*v1beta2.Scale, error) - ScaleNamespaceListerExpansion -} - -// scaleNamespaceLister implements the ScaleNamespaceLister -// interface. -type scaleNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Scales in the indexer for a given namespace. -func (s scaleNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.Scale, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1beta2.Scale)) - }) - return ret, err -} - -// Get retrieves the Scale from the indexer for a given namespace and name. -func (s scaleNamespaceLister) Get(name string) (*v1beta2.Scale, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1beta2.Resource("scale"), name) - } - return obj.(*v1beta2.Scale), nil -} diff --git a/staging/src/k8s.io/client-go/listers/authentication/OWNERS b/staging/src/k8s.io/client-go/listers/authentication/OWNERS new file mode 100644 index 0000000000000..c607d2aa8c5fe --- /dev/null +++ b/staging/src/k8s.io/client-go/listers/authentication/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers +reviewers: +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/listers/authorization/OWNERS b/staging/src/k8s.io/client-go/listers/authorization/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/staging/src/k8s.io/client-go/listers/authorization/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/BUILD b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/BUILD index 786a63311b52b..62d18fefa1e4d 100644 --- a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/BUILD +++ b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/BUILD @@ -18,7 +18,6 @@ go_library( "podsecuritypolicy.go", "replicaset.go", "replicaset_expansion.go", - "scale.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/listers/extensions/v1beta1", importpath = "k8s.io/client-go/listers/extensions/v1beta1", diff --git a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go index b5ee8a49230f9..d5c2a7a7d2213 100644 --- a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go +++ b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go @@ -29,11 +29,3 @@ type IngressNamespaceListerExpansion interface{} // PodSecurityPolicyListerExpansion allows custom methods to be added to // PodSecurityPolicyLister. type PodSecurityPolicyListerExpansion interface{} - -// ScaleListerExpansion allows custom methods to be added to -// ScaleLister. -type ScaleListerExpansion interface{} - -// ScaleNamespaceListerExpansion allows custom methods to be added to -// ScaleNamespaceLister. -type ScaleNamespaceListerExpansion interface{} diff --git a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/scale.go b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/scale.go deleted file mode 100644 index 527d4be424689..0000000000000 --- a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/scale.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// ScaleLister helps list Scales. -type ScaleLister interface { - // List lists all Scales in the indexer. - List(selector labels.Selector) (ret []*v1beta1.Scale, err error) - // Scales returns an object that can list and get Scales. - Scales(namespace string) ScaleNamespaceLister - ScaleListerExpansion -} - -// scaleLister implements the ScaleLister interface. -type scaleLister struct { - indexer cache.Indexer -} - -// NewScaleLister returns a new ScaleLister. -func NewScaleLister(indexer cache.Indexer) ScaleLister { - return &scaleLister{indexer: indexer} -} - -// List lists all Scales in the indexer. -func (s *scaleLister) List(selector labels.Selector) (ret []*v1beta1.Scale, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1beta1.Scale)) - }) - return ret, err -} - -// Scales returns an object that can list and get Scales. -func (s *scaleLister) Scales(namespace string) ScaleNamespaceLister { - return scaleNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ScaleNamespaceLister helps list and get Scales. -type ScaleNamespaceLister interface { - // List lists all Scales in the indexer for a given namespace. - List(selector labels.Selector) (ret []*v1beta1.Scale, err error) - // Get retrieves the Scale from the indexer for a given namespace and name. - Get(name string) (*v1beta1.Scale, error) - ScaleNamespaceListerExpansion -} - -// scaleNamespaceLister implements the ScaleNamespaceLister -// interface. -type scaleNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Scales in the indexer for a given namespace. -func (s scaleNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Scale, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1beta1.Scale)) - }) - return ret, err -} - -// Get retrieves the Scale from the indexer for a given namespace and name. -func (s scaleNamespaceLister) Get(name string) (*v1beta1.Scale, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1beta1.Resource("scale"), name) - } - return obj.(*v1beta1.Scale), nil -} diff --git a/staging/src/k8s.io/client-go/listers/rbac/OWNERS b/staging/src/k8s.io/client-go/listers/rbac/OWNERS new file mode 100644 index 0000000000000..cd0d70a0f8f02 --- /dev/null +++ b/staging/src/k8s.io/client-go/listers/rbac/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authorizers-approvers +reviewers: +- sig-auth-authorizers-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/pkg/apis/clientauthentication/OWNERS b/staging/src/k8s.io/client-go/pkg/apis/clientauthentication/OWNERS new file mode 100644 index 0000000000000..3b7ea1b131f25 --- /dev/null +++ b/staging/src/k8s.io/client-go/pkg/apis/clientauthentication/OWNERS @@ -0,0 +1,7 @@ +# approval on api packages bubbles to api-approvers +reviewers: +- sig-auth-authenticators-approvers +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/plugin/pkg/client/auth/OWNERS b/staging/src/k8s.io/client-go/plugin/pkg/client/auth/OWNERS new file mode 100644 index 0000000000000..c607d2aa8c5fe --- /dev/null +++ b/staging/src/k8s.io/client-go/plugin/pkg/client/auth/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers +reviewers: +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/plugin/pkg/client/auth/azure/azure.go b/staging/src/k8s.io/client-go/plugin/pkg/client/auth/azure/azure.go index 60304b0f392fa..9858963e38116 100644 --- a/staging/src/k8s.io/client-go/plugin/pkg/client/auth/azure/azure.go +++ b/staging/src/k8s.io/client-go/plugin/pkg/client/auth/azure/azure.go @@ -17,6 +17,7 @@ limitations under the License. package azure import ( + "encoding/json" "errors" "fmt" "net/http" @@ -243,9 +244,9 @@ func (ts *azureTokenSource) retrieveTokenFromCfg() (*azureToken, error) { token: adal.Token{ AccessToken: accessToken, RefreshToken: refreshToken, - ExpiresIn: expiresIn, - ExpiresOn: expiresOn, - NotBefore: expiresOn, + ExpiresIn: json.Number(expiresIn), + ExpiresOn: json.Number(expiresOn), + NotBefore: json.Number(expiresOn), Resource: fmt.Sprintf("spn:%s", apiserverID), Type: tokenType, }, @@ -262,8 +263,8 @@ func (ts *azureTokenSource) storeTokenInCfg(token *azureToken) error { newCfg[cfgClientID] = token.clientID newCfg[cfgTenantID] = token.tenantID newCfg[cfgApiserverID] = token.apiserverID - newCfg[cfgExpiresIn] = token.token.ExpiresIn - newCfg[cfgExpiresOn] = token.token.ExpiresOn + newCfg[cfgExpiresIn] = string(token.token.ExpiresIn) + newCfg[cfgExpiresOn] = string(token.token.ExpiresOn) err := ts.persister.Persist(newCfg) if err != nil { diff --git a/staging/src/k8s.io/client-go/plugin/pkg/client/auth/azure/azure_test.go b/staging/src/k8s.io/client-go/plugin/pkg/client/auth/azure/azure_test.go index b420712bc1229..810a097ded9fe 100644 --- a/staging/src/k8s.io/client-go/plugin/pkg/client/auth/azure/azure_test.go +++ b/staging/src/k8s.io/client-go/plugin/pkg/client/auth/azure/azure_test.go @@ -17,6 +17,7 @@ limitations under the License. package azure import ( + "encoding/json" "strconv" "strings" "sync" @@ -115,8 +116,8 @@ func token2Cfg(token *azureToken) map[string]string { cfg[cfgClientID] = token.clientID cfg[cfgTenantID] = token.tenantID cfg[cfgApiserverID] = token.apiserverID - cfg[cfgExpiresIn] = token.token.ExpiresIn - cfg[cfgExpiresOn] = token.token.ExpiresOn + cfg[cfgExpiresIn] = string(token.token.ExpiresIn) + cfg[cfgExpiresOn] = string(token.token.ExpiresOn) return cfg } @@ -125,8 +126,8 @@ func newFackeAzureToken(accessToken string, expiresOn string) adal.Token { AccessToken: accessToken, RefreshToken: "fake", ExpiresIn: "3600", - ExpiresOn: expiresOn, - NotBefore: expiresOn, + ExpiresOn: json.Number(expiresOn), + NotBefore: json.Number(expiresOn), Resource: "fake", Type: "fake", } diff --git a/staging/src/k8s.io/client-go/rest/config.go b/staging/src/k8s.io/client-go/rest/config.go index 87e87905523c2..d5ef84065ccd7 100644 --- a/staging/src/k8s.io/client-go/rest/config.go +++ b/staging/src/k8s.io/client-go/rest/config.go @@ -322,7 +322,7 @@ func InClusterConfig() (*Config, error) { return nil, ErrNotInCluster } - ts := newCachedPathTokenSource(tokenFile) + ts := NewCachedFileTokenSource(tokenFile) if _, err := ts.Token(); err != nil { return nil, err diff --git a/staging/src/k8s.io/client-go/rest/token_source.go b/staging/src/k8s.io/client-go/rest/token_source.go index 296b2a0481dfa..e0a6eb7d9f197 100644 --- a/staging/src/k8s.io/client-go/rest/token_source.go +++ b/staging/src/k8s.io/client-go/rest/token_source.go @@ -42,7 +42,9 @@ func TokenSourceWrapTransport(ts oauth2.TokenSource) func(http.RoundTripper) htt } } -func newCachedPathTokenSource(path string) oauth2.TokenSource { +// NewCachedFileTokenSource returns a oauth2.TokenSource reads a token from a +// file at a specified path and periodically reloads it. +func NewCachedFileTokenSource(path string) oauth2.TokenSource { return &cachingTokenSource{ now: time.Now, leeway: 1 * time.Minute, diff --git a/staging/src/k8s.io/client-go/tools/auth/OWNERS b/staging/src/k8s.io/client-go/tools/auth/OWNERS new file mode 100644 index 0000000000000..c607d2aa8c5fe --- /dev/null +++ b/staging/src/k8s.io/client-go/tools/auth/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-authenticators-approvers +reviewers: +- sig-auth-authenticators-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/tools/cache/expiration_cache.go b/staging/src/k8s.io/client-go/tools/cache/expiration_cache.go index fa88fc407e392..d284453ec4335 100644 --- a/staging/src/k8s.io/client-go/tools/cache/expiration_cache.go +++ b/staging/src/k8s.io/client-go/tools/cache/expiration_cache.go @@ -179,7 +179,7 @@ func (c *ExpirationCache) Delete(obj interface{}) error { func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) error { c.expirationLock.Lock() defer c.expirationLock.Unlock() - items := map[string]interface{}{} + items := make(map[string]interface{}, len(list)) ts := c.clock.Now() for _, item := range list { key, err := c.keyFunc(item) diff --git a/staging/src/k8s.io/client-go/tools/cache/fifo.go b/staging/src/k8s.io/client-go/tools/cache/fifo.go index e05c01ee2960d..508c5530c36fb 100644 --- a/staging/src/k8s.io/client-go/tools/cache/fifo.go +++ b/staging/src/k8s.io/client-go/tools/cache/fifo.go @@ -297,7 +297,7 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) { // after calling this function. f's queue is reset, too; upon return, it // will contain the items in the map, in no particular order. func (f *FIFO) Replace(list []interface{}, resourceVersion string) error { - items := map[string]interface{}{} + items := make(map[string]interface{}, len(list)) for _, item := range list { key, err := f.keyFunc(item) if err != nil { diff --git a/staging/src/k8s.io/client-go/tools/cache/store.go b/staging/src/k8s.io/client-go/tools/cache/store.go index 4958987f0e73e..fc844efe64d61 100755 --- a/staging/src/k8s.io/client-go/tools/cache/store.go +++ b/staging/src/k8s.io/client-go/tools/cache/store.go @@ -210,7 +210,7 @@ func (c *cache) GetByKey(key string) (item interface{}, exists bool, err error) // 'c' takes ownership of the list, you should not reference the list again // after calling this function. func (c *cache) Replace(list []interface{}, resourceVersion string) error { - items := map[string]interface{}{} + items := make(map[string]interface{}, len(list)) for _, item := range list { key, err := c.keyFunc(item) if err != nil { diff --git a/staging/src/k8s.io/client-go/tools/clientcmd/client_config.go b/staging/src/k8s.io/client-go/tools/clientcmd/client_config.go index b8927f71087e5..e5dc921ff9a8e 100644 --- a/staging/src/k8s.io/client-go/tools/clientcmd/client_config.go +++ b/staging/src/k8s.io/client-go/tools/clientcmd/client_config.go @@ -229,11 +229,11 @@ func (config *DirectClientConfig) getUserIdentificationPartialConfig(configAuthI if len(configAuthInfo.Token) > 0 { mergedConfig.BearerToken = configAuthInfo.Token } else if len(configAuthInfo.TokenFile) > 0 { - tokenBytes, err := ioutil.ReadFile(configAuthInfo.TokenFile) - if err != nil { + ts := restclient.NewCachedFileTokenSource(configAuthInfo.TokenFile) + if _, err := ts.Token(); err != nil { return nil, err } - mergedConfig.BearerToken = string(tokenBytes) + mergedConfig.WrapTransport = restclient.TokenSourceWrapTransport(ts) } if len(configAuthInfo.Impersonate) > 0 { mergedConfig.Impersonate = restclient.ImpersonationConfig{ diff --git a/staging/src/k8s.io/client-go/tools/clientcmd/client_config_test.go b/staging/src/k8s.io/client-go/tools/clientcmd/client_config_test.go index 798aa3dd89d11..6da850ed40535 100644 --- a/staging/src/k8s.io/client-go/tools/clientcmd/client_config_test.go +++ b/staging/src/k8s.io/client-go/tools/clientcmd/client_config_test.go @@ -18,12 +18,14 @@ package clientcmd import ( "io/ioutil" + "net/http" "os" "reflect" "strings" "testing" "github.com/imdario/mergo" + restclient "k8s.io/client-go/rest" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) @@ -332,7 +334,19 @@ func TestBasicTokenFile(t *testing.T) { t.Fatalf("Unexpected error: %v", err) } - matchStringArg(token, clientConfig.BearerToken, t) + var out *http.Request + clientConfig.WrapTransport(fakeTransport(func(req *http.Request) (*http.Response, error) { + out = req + return &http.Response{}, nil + })).RoundTrip(&http.Request{}) + + matchStringArg(token, strings.TrimPrefix(out.Header.Get("Authorization"), "Bearer "), t) +} + +type fakeTransport func(*http.Request) (*http.Response, error) + +func (ft fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) { + return ft(req) } func TestPrecedenceTokenFile(t *testing.T) { diff --git a/staging/src/k8s.io/client-go/tools/leaderelection/leaderelection.go b/staging/src/k8s.io/client-go/tools/leaderelection/leaderelection.go index 9a357b2ac1f83..be52e85a048eb 100644 --- a/staging/src/k8s.io/client-go/tools/leaderelection/leaderelection.go +++ b/staging/src/k8s.io/client-go/tools/leaderelection/leaderelection.go @@ -224,7 +224,7 @@ func (le *LeaderElector) renew(ctx context.Context) { le.maybeReportTransition() desc := le.config.Lock.Describe() if err == nil { - glog.V(4).Infof("successfully renewed lease %v", desc) + glog.V(5).Infof("successfully renewed lease %v", desc) return } le.config.Lock.RecordEvent("stopped leading") diff --git a/staging/src/k8s.io/client-go/util/cert/OWNERS b/staging/src/k8s.io/client-go/util/cert/OWNERS new file mode 100644 index 0000000000000..470b7a1c92d15 --- /dev/null +++ b/staging/src/k8s.io/client-go/util/cert/OWNERS @@ -0,0 +1,7 @@ +approvers: +- sig-auth-certificates-approvers +reviewers: +- sig-auth-certificates-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/util/certificate/OWNERS b/staging/src/k8s.io/client-go/util/certificate/OWNERS index 2dce803b34dd9..470b7a1c92d15 100644 --- a/staging/src/k8s.io/client-go/util/certificate/OWNERS +++ b/staging/src/k8s.io/client-go/util/certificate/OWNERS @@ -1,8 +1,7 @@ -reviewers: -- mikedanese -- liggit -- smarterclayton approvers: -- mikedanese -- liggit -- smarterclayton +- sig-auth-certificates-approvers +reviewers: +- sig-auth-certificates-reviewers +labels: +- sig/auth + diff --git a/staging/src/k8s.io/client-go/util/certificate/certificate_manager.go b/staging/src/k8s.io/client-go/util/certificate/certificate_manager.go index 7b07b26a3ef02..fbdf4ec7f36ee 100644 --- a/staging/src/k8s.io/client-go/util/certificate/certificate_manager.go +++ b/staging/src/k8s.io/client-go/util/certificate/certificate_manager.go @@ -274,7 +274,7 @@ func (m *manager) Start() { if m.dynamicTemplate { go wait.Forever(func() { // check if the current template matches what we last requested - if !reflect.DeepEqual(m.getLastRequest(), m.getTemplate()) { + if !m.certSatisfiesTemplate() && !reflect.DeepEqual(m.getLastRequest(), m.getTemplate()) { // if the template is different, queue up an interrupt of the rotation deadline loop. // if we've requested a CSR that matches the new template by the time the interrupt is handled, the interrupt is disregarded. templateChanged <- struct{}{} @@ -389,35 +389,30 @@ func (m *manager) rotateCerts() (bool, error) { return true, nil } -// nextRotationDeadline returns a value for the threshold at which the -// current certificate should be rotated, 80%+/-10% of the expiration of the -// certificate. -func (m *manager) nextRotationDeadline() time.Time { - // forceRotation is not protected by locks - if m.forceRotation { - m.forceRotation = false - return time.Now() - } - - m.certAccessLock.RLock() - defer m.certAccessLock.RUnlock() +// Check that the current certificate on disk satisfies the requests from the +// current template. +// +// Note that extra items in the certificate's SAN or orgs that don't exist in +// the template will not trigger a renewal. +// +// Requires certAccessLock to be locked. +func (m *manager) certSatisfiesTemplateLocked() bool { if m.cert == nil { - return time.Now() + return false } - // Ensure the currently held certificate satisfies the requested subject CN and SANs if template := m.getTemplate(); template != nil { if template.Subject.CommonName != m.cert.Leaf.Subject.CommonName { - glog.V(2).Infof("Current certificate CN (%s) does not match requested CN (%s), rotating now", m.cert.Leaf.Subject.CommonName, template.Subject.CommonName) - return time.Now() + glog.V(2).Infof("Current certificate CN (%s) does not match requested CN (%s)", m.cert.Leaf.Subject.CommonName, template.Subject.CommonName) + return false } currentDNSNames := sets.NewString(m.cert.Leaf.DNSNames...) desiredDNSNames := sets.NewString(template.DNSNames...) missingDNSNames := desiredDNSNames.Difference(currentDNSNames) if len(missingDNSNames) > 0 { - glog.V(2).Infof("Current certificate is missing requested DNS names %v, rotating now", missingDNSNames.List()) - return time.Now() + glog.V(2).Infof("Current certificate is missing requested DNS names %v", missingDNSNames.List()) + return false } currentIPs := sets.NewString() @@ -430,9 +425,43 @@ func (m *manager) nextRotationDeadline() time.Time { } missingIPs := desiredIPs.Difference(currentIPs) if len(missingIPs) > 0 { - glog.V(2).Infof("Current certificate is missing requested IP addresses %v, rotating now", missingIPs.List()) - return time.Now() + glog.V(2).Infof("Current certificate is missing requested IP addresses %v", missingIPs.List()) + return false } + + currentOrgs := sets.NewString(m.cert.Leaf.Subject.Organization...) + desiredOrgs := sets.NewString(template.Subject.Organization...) + missingOrgs := desiredOrgs.Difference(currentOrgs) + if len(missingOrgs) > 0 { + glog.V(2).Infof("Current certificate is missing requested orgs %v", missingOrgs.List()) + return false + } + } + + return true +} + +func (m *manager) certSatisfiesTemplate() bool { + m.certAccessLock.RLock() + defer m.certAccessLock.RUnlock() + return m.certSatisfiesTemplateLocked() +} + +// nextRotationDeadline returns a value for the threshold at which the +// current certificate should be rotated, 80%+/-10% of the expiration of the +// certificate. +func (m *manager) nextRotationDeadline() time.Time { + // forceRotation is not protected by locks + if m.forceRotation { + m.forceRotation = false + return time.Now() + } + + m.certAccessLock.RLock() + defer m.certAccessLock.RUnlock() + + if !m.certSatisfiesTemplateLocked() { + return time.Now() } notAfter := m.cert.Leaf.NotAfter diff --git a/staging/src/k8s.io/client-go/util/certificate/certificate_manager_test.go b/staging/src/k8s.io/client-go/util/certificate/certificate_manager_test.go index 299a1d5305e49..545097ea453aa 100644 --- a/staging/src/k8s.io/client-go/util/certificate/certificate_manager_test.go +++ b/staging/src/k8s.io/client-go/util/certificate/certificate_manager_test.go @@ -22,6 +22,7 @@ import ( "crypto/x509" "crypto/x509/pkix" "fmt" + "net" "strings" "testing" "time" @@ -212,6 +213,170 @@ func TestSetRotationDeadline(t *testing.T) { } } +func TestCertSatisfiesTemplate(t *testing.T) { + testCases := []struct { + name string + cert *x509.Certificate + template *x509.CertificateRequest + shouldSatisfy bool + }{ + { + name: "No certificate, no template", + cert: nil, + template: nil, + shouldSatisfy: false, + }, + { + name: "No certificate", + cert: nil, + template: &x509.CertificateRequest{}, + shouldSatisfy: false, + }, + { + name: "No template", + cert: &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "system:node:fake-node-name", + }, + }, + template: nil, + shouldSatisfy: true, + }, + { + name: "Mismatched common name", + cert: &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "system:node:fake-node-name-2", + }, + }, + template: &x509.CertificateRequest{ + Subject: pkix.Name{ + CommonName: "system:node:fake-node-name", + }, + }, + shouldSatisfy: false, + }, + { + name: "Missing orgs in certificate", + cert: &x509.Certificate{ + Subject: pkix.Name{ + Organization: []string{"system:nodes"}, + }, + }, + template: &x509.CertificateRequest{ + Subject: pkix.Name{ + Organization: []string{"system:nodes", "foobar"}, + }, + }, + shouldSatisfy: false, + }, + { + name: "Extra orgs in certificate", + cert: &x509.Certificate{ + Subject: pkix.Name{ + Organization: []string{"system:nodes", "foobar"}, + }, + }, + template: &x509.CertificateRequest{ + Subject: pkix.Name{ + Organization: []string{"system:nodes"}, + }, + }, + shouldSatisfy: true, + }, + { + name: "Missing DNS names in certificate", + cert: &x509.Certificate{ + Subject: pkix.Name{}, + DNSNames: []string{"foo.example.com"}, + }, + template: &x509.CertificateRequest{ + Subject: pkix.Name{}, + DNSNames: []string{"foo.example.com", "bar.example.com"}, + }, + shouldSatisfy: false, + }, + { + name: "Extra DNS names in certificate", + cert: &x509.Certificate{ + Subject: pkix.Name{}, + DNSNames: []string{"foo.example.com", "bar.example.com"}, + }, + template: &x509.CertificateRequest{ + Subject: pkix.Name{}, + DNSNames: []string{"foo.example.com"}, + }, + shouldSatisfy: true, + }, + { + name: "Missing IP addresses in certificate", + cert: &x509.Certificate{ + Subject: pkix.Name{}, + IPAddresses: []net.IP{net.ParseIP("192.168.1.1")}, + }, + template: &x509.CertificateRequest{ + Subject: pkix.Name{}, + IPAddresses: []net.IP{net.ParseIP("192.168.1.1"), net.ParseIP("192.168.1.2")}, + }, + shouldSatisfy: false, + }, + { + name: "Extra IP addresses in certificate", + cert: &x509.Certificate{ + Subject: pkix.Name{}, + IPAddresses: []net.IP{net.ParseIP("192.168.1.1"), net.ParseIP("192.168.1.2")}, + }, + template: &x509.CertificateRequest{ + Subject: pkix.Name{}, + IPAddresses: []net.IP{net.ParseIP("192.168.1.1")}, + }, + shouldSatisfy: true, + }, + { + name: "Matching certificate", + cert: &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "system:node:fake-node-name", + Organization: []string{"system:nodes"}, + }, + DNSNames: []string{"foo.example.com"}, + IPAddresses: []net.IP{net.ParseIP("192.168.1.1")}, + }, + template: &x509.CertificateRequest{ + Subject: pkix.Name{ + CommonName: "system:node:fake-node-name", + Organization: []string{"system:nodes"}, + }, + DNSNames: []string{"foo.example.com"}, + IPAddresses: []net.IP{net.ParseIP("192.168.1.1")}, + }, + shouldSatisfy: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var tlsCert *tls.Certificate + + if tc.cert != nil { + tlsCert = &tls.Certificate{ + Leaf: tc.cert, + } + } + + m := manager{ + cert: tlsCert, + getTemplate: func() *x509.CertificateRequest { return tc.template }, + } + + result := m.certSatisfiesTemplate() + if result != tc.shouldSatisfy { + t.Errorf("cert: %+v, template: %+v, certSatisfiesTemplate returned %v, want %v", m.cert, tc.template, result, tc.shouldSatisfy) + } + }) + } +} + func TestRotateCertCreateCSRError(t *testing.T) { now := time.Now() m := manager{ diff --git a/staging/src/k8s.io/cloud-provider/Godeps/Godeps.json b/staging/src/k8s.io/cloud-provider/Godeps/Godeps.json index f1f23b353174e..b24b0eeb34ef3 100644 --- a/staging/src/k8s.io/cloud-provider/Godeps/Godeps.json +++ b/staging/src/k8s.io/cloud-provider/Godeps/Godeps.json @@ -104,23 +104,23 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", diff --git a/staging/src/k8s.io/cluster-bootstrap/Godeps/Godeps.json b/staging/src/k8s.io/cluster-bootstrap/Godeps/Godeps.json index fc536250ef983..440b974e48272 100644 --- a/staging/src/k8s.io/cluster-bootstrap/Godeps/Godeps.json +++ b/staging/src/k8s.io/cluster-bootstrap/Godeps/Godeps.json @@ -24,19 +24,19 @@ }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/text/secure/bidirule", diff --git a/staging/src/k8s.io/code-generator/Godeps/Godeps.json b/staging/src/k8s.io/code-generator/Godeps/Godeps.json index bdbb440ae2f28..6e2ec41e89a1e 100644 --- a/staging/src/k8s.io/code-generator/Godeps/Godeps.json +++ b/staging/src/k8s.io/code-generator/Godeps/Godeps.json @@ -24,19 +24,19 @@ }, { "ImportPath": "github.com/go-openapi/jsonpointer", - "Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98" + "Rev": "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004" }, { "ImportPath": "github.com/go-openapi/jsonreference", - "Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272" + "Rev": "8483a886a90412cd6858df4ea3483dce9c8e35a3" }, { "ImportPath": "github.com/go-openapi/spec", - "Rev": "1de3e0542de65ad8d75452a595886fdd0befb363" + "Rev": "5bae59e25b21498baea7f9d46e9c147ec106a42e" }, { "ImportPath": "github.com/go-openapi/swag", - "Rev": "f3f9494671f93fcff853e3c6e9e948b3eb71e590" + "Rev": "5899d5c5e619fda5fa86e14795a835f473ca284c" }, { "ImportPath": "github.com/gogo/protobuf/gogoproto", @@ -160,7 +160,7 @@ }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/text/cases", @@ -260,23 +260,23 @@ }, { "ImportPath": "k8s.io/kube-openapi/cmd/openapi-gen/args", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/generators", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/generators/rules", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/sets", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" } ] } diff --git a/staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go b/staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go index 0e7a7d8ec351e..49e8297dbd045 100644 --- a/staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go +++ b/staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go @@ -724,6 +724,10 @@ func genComment(out io.Writer, lines []string, indent string) { lines = lines[:l-1] } for _, c := range lines { + if len(c) == 0 { + fmt.Fprintf(out, "%s//\n", indent) // avoid trailing whitespace + continue + } fmt.Fprintf(out, "%s// %s\n", indent, c) } } diff --git a/staging/src/k8s.io/code-generator/generate-groups.sh b/staging/src/k8s.io/code-generator/generate-groups.sh index d7ad5b2e07f8a..d8531a8d9d7cb 100755 --- a/staging/src/k8s.io/code-generator/generate-groups.sh +++ b/staging/src/k8s.io/code-generator/generate-groups.sh @@ -50,7 +50,7 @@ shift 4 # To support running this script from anywhere, we have to first cd into this directory # so we can install the tools. cd $(dirname "${0}") - go install ./cmd/{defaulter-gen,client-gen,lister-gen,informer-gen,deepcopy-gen} + go install ${GOFLAGS:-} ./cmd/{defaulter-gen,client-gen,lister-gen,informer-gen,deepcopy-gen} ) function codegen::join() { local IFS="$1"; shift; echo "$*"; } @@ -72,8 +72,8 @@ if [ "${GENS}" = "all" ] || grep -qw "deepcopy" <<<"${GENS}"; then fi if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then - echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/clientset" - ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_VERSIONED:-versioned} --input-base "" --input $(codegen::join , "${FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/clientset "$@" + echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}" + ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_VERSIONED:-versioned} --input-base "" --input $(codegen::join , "${FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset} "$@" fi if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then @@ -85,7 +85,7 @@ if [ "${GENS}" = "all" ] || grep -qw "informer" <<<"${GENS}"; then echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers" ${GOPATH}/bin/informer-gen \ --input-dirs $(codegen::join , "${FQ_APIS[@]}") \ - --versioned-clientset-package ${OUTPUT_PKG}/clientset/${CLIENTSET_NAME_VERSIONED:-versioned} \ + --versioned-clientset-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}/${CLIENTSET_NAME_VERSIONED:-versioned} \ --listers-package ${OUTPUT_PKG}/listers \ --output-package ${OUTPUT_PKG}/informers \ "$@" diff --git a/staging/src/k8s.io/code-generator/generate-internal-groups.sh b/staging/src/k8s.io/code-generator/generate-internal-groups.sh index 1220e77c587d4..6849ed94373c7 100755 --- a/staging/src/k8s.io/code-generator/generate-internal-groups.sh +++ b/staging/src/k8s.io/code-generator/generate-internal-groups.sh @@ -47,7 +47,7 @@ EXT_APIS_PKG="$4" GROUPS_WITH_VERSIONS="$5" shift 5 -go install ./$(dirname "${0}")/cmd/{defaulter-gen,conversion-gen,client-gen,lister-gen,informer-gen,deepcopy-gen} +go install ${GOFLAGS:-} ./$(dirname "${0}")/cmd/{defaulter-gen,conversion-gen,client-gen,lister-gen,informer-gen,deepcopy-gen} function codegen::join() { local IFS="$1"; shift; echo "$*"; } # enumerate group versions @@ -85,11 +85,11 @@ if [ "${GENS}" = "all" ] || grep -qw "conversion" <<<"${GENS}"; then fi if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then - echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/clientset" + echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}" if [ -n "${INT_APIS_PKG}" ]; then - ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_INTERNAL:-internalversion} --input-base "" --input $(codegen::join , $(printf '%s/ ' "${INT_FQ_APIS[@]}")) --output-package ${OUTPUT_PKG}/clientset "$@" + ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_INTERNAL:-internalversion} --input-base "" --input $(codegen::join , $(printf '%s/ ' "${INT_FQ_APIS[@]}")) --output-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset} "$@" fi - ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_VERSIONED:-versioned} --input-base "" --input $(codegen::join , "${EXT_FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/clientset "$@" + ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_VERSIONED:-versioned} --input-base "" --input $(codegen::join , "${EXT_FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset} "$@" fi if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then @@ -101,8 +101,8 @@ if [ "${GENS}" = "all" ] || grep -qw "informer" <<<"${GENS}"; then echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers" ${GOPATH}/bin/informer-gen \ --input-dirs $(codegen::join , "${ALL_FQ_APIS[@]}") \ - --versioned-clientset-package ${OUTPUT_PKG}/clientset/${CLIENTSET_NAME_VERSIONED:-versioned} \ - --internal-clientset-package ${OUTPUT_PKG}/clientset/${CLIENTSET_NAME_INTERNAL:-internalversion} \ + --versioned-clientset-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}/${CLIENTSET_NAME_VERSIONED:-versioned} \ + --internal-clientset-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}/${CLIENTSET_NAME_INTERNAL:-internalversion} \ --listers-package ${OUTPUT_PKG}/listers \ --output-package ${OUTPUT_PKG}/informers \ "$@" diff --git a/staging/src/k8s.io/csi-api/Godeps/Godeps.json b/staging/src/k8s.io/csi-api/Godeps/Godeps.json index e99aa4d810574..c689fb7aba5d5 100644 --- a/staging/src/k8s.io/csi-api/Godeps/Godeps.json +++ b/staging/src/k8s.io/csi-api/Godeps/Godeps.json @@ -108,23 +108,23 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -298,18 +298,6 @@ "ImportPath": "k8s.io/api/storage/v1beta1", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, - { - "ImportPath": "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, - { - "ImportPath": "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/api/errors", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -568,7 +556,7 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" } ] } diff --git a/staging/src/k8s.io/csi-api/pkg/apis/OWNERS b/staging/src/k8s.io/csi-api/pkg/apis/OWNERS new file mode 100644 index 0000000000000..1cfcd56de878e --- /dev/null +++ b/staging/src/k8s.io/csi-api/pkg/apis/OWNERS @@ -0,0 +1,10 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +- sig-storage-reviewers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/csi-api/pkg/crd/BUILD b/staging/src/k8s.io/csi-api/pkg/crd/BUILD index 3a9a64a5c88bf..71a403cd5732f 100644 --- a/staging/src/k8s.io/csi-api/pkg/crd/BUILD +++ b/staging/src/k8s.io/csi-api/pkg/crd/BUILD @@ -6,25 +6,17 @@ go_library( importmap = "k8s.io/kubernetes/vendor/k8s.io/csi-api/pkg/crd", importpath = "k8s.io/csi-api/pkg/crd", visibility = ["//visibility:public"], - deps = [ - "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", - ], ) go_test( name = "go_default_test", srcs = ["crd_test.go"], - data = glob(["testdata/**"]), - embed = [":go_default_library"], - deps = [ - "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", - "//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", - "//vendor/github.com/ghodss/yaml:go_default_library", + data = [ + "//cluster/addons:addon-srcs", + "//staging/src/k8s.io/csi-api/pkg/crd:manifests", ], + embed = [":go_default_library"], + deps = ["//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library"], ) filegroup( @@ -34,6 +26,14 @@ filegroup( visibility = ["//visibility:private"], ) +filegroup( + name = "csi-manifests", + srcs = [ + "//staging/src/k8s.io/csi-api/pkg/crd:manifests", + ], + visibility = ["//visibility:public"], +) + filegroup( name = "all-srcs", srcs = [":package-srcs"], diff --git a/staging/src/k8s.io/csi-api/pkg/crd/OWNERS b/staging/src/k8s.io/csi-api/pkg/crd/OWNERS new file mode 100644 index 0000000000000..1cfcd56de878e --- /dev/null +++ b/staging/src/k8s.io/csi-api/pkg/crd/OWNERS @@ -0,0 +1,10 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +- sig-storage-reviewers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/csi-api/pkg/crd/crd.go b/staging/src/k8s.io/csi-api/pkg/crd/crd.go index 4a7936e414037..02e5b152811b3 100644 --- a/staging/src/k8s.io/csi-api/pkg/crd/crd.go +++ b/staging/src/k8s.io/csi-api/pkg/crd/crd.go @@ -14,106 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package crd is only for running tests to verify the manifest files +// in this package and the addons are in sync. +// The manifest file is currently manually generated, in the future, we +// should invest in tooling that will automatically generate the CRD +// manifest from the CR schema. package crd - -import ( - apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - csiapiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1" - "reflect" -) - -// NOTE: the CRD functions here and the associated unit tests are non-ideal temporary measures in -// release 1.12 in order to aid manual CRD installation. This installation will be automated in -// subsequent releases and as a result this package will be removed. - -// CSIDriverCRD returns the CustomResourceDefinition for CSIDriver object. -func CSIDriverCRD() *apiextensionsv1beta1.CustomResourceDefinition { - return &apiextensionsv1beta1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: csiapiv1alpha1.CsiDriverResourcePlural + "." + csiapiv1alpha1.GroupName, - }, - Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ - Group: csiapiv1alpha1.GroupName, - Version: csiapiv1alpha1.SchemeGroupVersion.Version, - Scope: apiextensionsv1beta1.ClusterScoped, - Validation: &apiextensionsv1beta1.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{ - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "spec": { - Description: "Specification of the CSI Driver.", - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "attachRequired": { - Description: "Indicates this CSI volume driver requires an attach operation," + - " and that Kubernetes should call attach and wait for any attach operation to" + - " complete before proceeding to mount.", - Type: "boolean", - }, - "podInfoOnMountVersion": { - Description: "Indicates this CSI volume driver requires additional pod" + - " information (like podName, podUID, etc.) during mount operations.", - Type: "string", - }, - }, - }, - }, - }, - }, - Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ - Plural: csiapiv1alpha1.CsiDriverResourcePlural, - Kind: reflect.TypeOf(csiapiv1alpha1.CSIDriver{}).Name(), - }, - }, - } -} - -// CSINodeInfoCRD returns the CustomResourceDefinition for CSINodeInfo object. -func CSINodeInfoCRD() *apiextensionsv1beta1.CustomResourceDefinition { - return &apiextensionsv1beta1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: csiapiv1alpha1.CsiNodeInfoResourcePlural + "." + csiapiv1alpha1.GroupName, - }, - Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ - Group: csiapiv1alpha1.GroupName, - Version: csiapiv1alpha1.SchemeGroupVersion.Version, - Scope: apiextensionsv1beta1.ClusterScoped, - Validation: &apiextensionsv1beta1.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{ - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "csiDrivers": { - Description: "List of CSI drivers running on the node and their properties.", - Type: "array", - Items: &apiextensionsv1beta1.JSONSchemaPropsOrArray{ - Schema: &apiextensionsv1beta1.JSONSchemaProps{ - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "driver": { - Description: "The CSI driver that this object refers to.", - Type: "string", - }, - "nodeID": { - Description: "The node from the driver point of view.", - Type: "string", - }, - "topologyKeys": { - Description: "List of keys supported by the driver.", - Type: "array", - Items: &apiextensionsv1beta1.JSONSchemaPropsOrArray{ - Schema: &apiextensionsv1beta1.JSONSchemaProps{ - Type: "string", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ - Plural: csiapiv1alpha1.CsiNodeInfoResourcePlural, - Kind: reflect.TypeOf(csiapiv1alpha1.CSINodeInfo{}).Name(), - }, - }, - } -} diff --git a/staging/src/k8s.io/csi-api/pkg/crd/crd_test.go b/staging/src/k8s.io/csi-api/pkg/crd/crd_test.go index 369a3b458b509..2bb155baffd77 100644 --- a/staging/src/k8s.io/csi-api/pkg/crd/crd_test.go +++ b/staging/src/k8s.io/csi-api/pkg/crd/crd_test.go @@ -14,56 +14,69 @@ See the License for the specific language governing permissions and limitations under the License. */ +// These tests verify the manifest files in this package and the +// addons directory are in sync. package crd_test import ( + "io/ioutil" + "os" "path/filepath" "testing" - "github.com/ghodss/yaml" - "io/ioutil" - apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - apiextensionsscheme "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" - "k8s.io/csi-api/pkg/crd" - "os" ) func TestBootstrapCRDs(t *testing.T) { - testObjects(t, crd.CSIDriverCRD(), "csidriver.yaml") - testObjects(t, crd.CSINodeInfoCRD(), "csinodeinfo.yaml") + verifyCopiesAreInSync( + t, + "csidriver.yaml", /* filename */ + "manifests", /* sourceOfTruthDir */ + []string{"../../../../../../cluster/addons/storage-crds"}, /* copyDirs */ + ) + verifyCopiesAreInSync( + t, + "csinodeinfo.yaml", /* filename */ + "manifests", /* sourceOfTruthDir */ + []string{"../../../../../../cluster/addons/storage-crds"}, /* copyDirs */ + ) } -func testObjects(t *testing.T, crd *apiextensionsv1beta1.CustomResourceDefinition, fixtureFilename string) { - filename := filepath.Join("testdata", fixtureFilename) - expectedYAML, err := ioutil.ReadFile(filename) - if err != nil { - t.Fatal(err) - } +// verifyCopiesAreInSync fails if any copies are different from source of truth. +func verifyCopiesAreInSync(t *testing.T, filename string, sourceOfTruthDir string, copyDirs []string) { + sourceOfTruthFilename := filepath.Join(sourceOfTruthDir, filename) - jsonData, err := runtime.Encode(apiextensionsscheme.Codecs.LegacyCodec(apiextensionsv1beta1.SchemeGroupVersion), crd) - if err != nil { - t.Fatal(err) + if len(copyDirs) <= 0 { + t.Fatalf("copyDirs is empty. There are no copies to validate.") } - yamlData, err := yaml.JSONToYAML(jsonData) + + expectedYAML, err := ioutil.ReadFile(sourceOfTruthFilename) if err != nil { t.Fatal(err) } - if string(yamlData) != string(expectedYAML) { - t.Errorf("Bootstrap CRD data does not match the test fixture in %s", filename) - const updateEnvVar = "UPDATE_CSI_CRD_FIXTURE_DATA" - if os.Getenv(updateEnvVar) == "true" { - if err := ioutil.WriteFile(filename, []byte(yamlData), os.FileMode(0755)); err == nil { - t.Logf("Updated data in %s", filename) - t.Logf("Verify the diff, commit changes, and rerun the tests") + for _, copyDir := range copyDirs { + copyFilename := filepath.Join(copyDir, filename) + actualYAML, err := ioutil.ReadFile(copyFilename) + if err != nil { + t.Fatal(err) + } + + if string(actualYAML) != string(expectedYAML) { + t.Errorf("Data in %q does not match source of truth in %q.", copyFilename, sourceOfTruthFilename) + + const updateEnvVar = "UPDATE_CSI_CRD_FIXTURE_DATA" + if os.Getenv(updateEnvVar) == "true" { + if err := ioutil.WriteFile(copyFilename, []byte(expectedYAML), os.FileMode(0755)); err == nil { + t.Logf("Updated data in %s", copyFilename) + t.Logf("Verify the diff, commit changes, and rerun the tests") + } else { + t.Logf("Could not update data in %s: %v", copyFilename, err) + } } else { - t.Logf("Could not update data in %s: %v", filename, err) + t.Logf("Diff between source of truth data and copy data in %s:\n-------------\n%s", copyFilename, diff.StringDiff(string(actualYAML), string(expectedYAML))) + t.Logf("If the change is expected, re-run with %s=true to update the copy data", updateEnvVar) } - } else { - t.Logf("Diff between data in code and fixture data in %s:\n-------------\n%s", filename, diff.StringDiff(string(yamlData), string(expectedYAML))) - t.Logf("If the change is expected, re-run with %s=true to update the fixtures", updateEnvVar) } } } diff --git a/staging/src/k8s.io/csi-api/pkg/crd/manifests/csidriver.yaml b/staging/src/k8s.io/csi-api/pkg/crd/manifests/csidriver.yaml new file mode 100644 index 0000000000000..54416b24f933d --- /dev/null +++ b/staging/src/k8s.io/csi-api/pkg/crd/manifests/csidriver.yaml @@ -0,0 +1,28 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: csidrivers.csi.storage.k8s.io + labels: + addonmanager.kubernetes.io/mode: Reconcile +spec: + group: csi.storage.k8s.io + names: + kind: CSIDriver + plural: csidrivers + scope: Cluster + validation: + openAPIV3Schema: + properties: + spec: + description: Specification of the CSI Driver. + properties: + attachRequired: + description: Indicates this CSI volume driver requires an attach operation, + and that Kubernetes should call attach and wait for any attach operation + to complete before proceeding to mount. + type: boolean + podInfoOnMountVersion: + description: Indicates this CSI volume driver requires additional pod + information (like podName, podUID, etc.) during mount operations. + type: string + version: v1alpha1 diff --git a/staging/src/k8s.io/csi-api/pkg/crd/manifests/csinodeinfo.yaml b/staging/src/k8s.io/csi-api/pkg/crd/manifests/csinodeinfo.yaml new file mode 100644 index 0000000000000..a9556fc1e824c --- /dev/null +++ b/staging/src/k8s.io/csi-api/pkg/crd/manifests/csinodeinfo.yaml @@ -0,0 +1,32 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: csinodeinfos.csi.storage.k8s.io + labels: + addonmanager.kubernetes.io/mode: Reconcile +spec: + group: csi.storage.k8s.io + names: + kind: CSINodeInfo + plural: csinodeinfos + scope: Cluster + validation: + openAPIV3Schema: + properties: + csiDrivers: + description: List of CSI drivers running on the node and their properties. + items: + properties: + driver: + description: The CSI driver that this object refers to. + type: string + nodeID: + description: The node from the driver point of view. + type: string + topologyKeys: + description: List of keys supported by the driver. + items: + type: string + type: array + type: array + version: v1alpha1 diff --git a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json index a4825b52a6e13..b81cd3143f3c7 100644 --- a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json @@ -36,39 +36,39 @@ }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/go-systemd/daemon", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/davecgh/go-spew/spew", @@ -116,19 +116,19 @@ }, { "ImportPath": "github.com/go-openapi/jsonpointer", - "Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98" + "Rev": "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004" }, { "ImportPath": "github.com/go-openapi/jsonreference", - "Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272" + "Rev": "8483a886a90412cd6858df4ea3483dce9c8e35a3" }, { "ImportPath": "github.com/go-openapi/spec", - "Rev": "1de3e0542de65ad8d75452a595886fdd0befb363" + "Rev": "5bae59e25b21498baea7f9d46e9c147ec106a42e" }, { "ImportPath": "github.com/go-openapi/swag", - "Rev": "f3f9494671f93fcff853e3c6e9e948b3eb71e590" + "Rev": "5899d5c5e619fda5fa86e14795a835f473ca284c" }, { "ImportPath": "github.com/gogo/protobuf/gogoproto", @@ -312,43 +312,43 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/html", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/html/atom", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/internal/timeseries", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/trace", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/websocket", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -1006,6 +1006,10 @@ "ImportPath": "k8s.io/apiserver/pkg/authentication/serviceaccount", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/apiserver/pkg/authentication/token/cache", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/token/tokenfile", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -1772,27 +1776,27 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/aggregator", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" } ] } diff --git a/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh b/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh index 43a4d57156bbb..97388362d23eb 100755 --- a/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh +++ b/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh @@ -18,65 +18,22 @@ set -o errexit set -o nounset set -o pipefail -SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/.. -SCRIPT_BASE=${SCRIPT_ROOT}/../.. -CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo k8s.io/code-generator)} - -if LANG=C sed --help 2>&1 | grep -q GNU; then - SED="sed" -elif which gsed &>/dev/null; then - SED="gsed" -else - echo "Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed." >&2 - exit 1 -fi - -# Register function to be called on EXIT to remove generated binary. -function cleanup { - rm -f "${CLIENTGEN:-}" - rm -f "${listergen:-}" - rm -f "${informergen:-}" -} -trap cleanup EXIT - -echo "Building client-gen" -CLIENTGEN="${PWD}/client-gen" - -go build -o "${CLIENTGEN}" ${CODEGEN_PKG}/cmd/client-gen - -PREFIX=k8s.io/kube-aggregator/pkg/apis -INPUT_BASE="--input-base ${PREFIX}" -INPUT_APIS=( -apiregistration/ -apiregistration/v1beta1 -apiregistration/v1 -) -INPUT="--input ${INPUT_APIS[@]}" -CLIENTSET_PATH="--output-package k8s.io/kube-aggregator/pkg/client/clientset_generated" - -${CLIENTGEN} ${INPUT_BASE} ${INPUT} ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} -${CLIENTGEN} --clientset-name="clientset" ${INPUT_BASE} --input apiregistration/v1beta1,apiregistration/v1 ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt - - -echo "Building lister-gen" -listergen="${PWD}/lister-gen" -go build -o "${listergen}" ${CODEGEN_PKG}/cmd/lister-gen - -LISTER_INPUT="--input-dirs k8s.io/kube-aggregator/pkg/apis/apiregistration --input-dirs k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1,k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" -LISTER_PATH="--output-package k8s.io/kube-aggregator/pkg/client/listers" -${listergen} ${LISTER_INPUT} ${LISTER_PATH} --output-base ${SCRIPT_BASE} --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt - - -echo "Building informer-gen" -informergen="${PWD}/informer-gen" -go build -o "${informergen}" ${CODEGEN_PKG}/cmd/informer-gen +SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. +CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)} + +CLIENTSET_NAME_VERSIONED=clientset \ +CLIENTSET_PKG_NAME=clientset_generated \ +${CODEGEN_PKG}/generate-groups.sh deepcopy,client,lister,informer \ + k8s.io/kube-aggregator/pkg/client k8s.io/kube-aggregator/pkg/apis \ + "apiregistration:v1beta1,v1" \ + --output-base "$(dirname ${BASH_SOURCE})/../../.." \ + --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt -${informergen} \ - --output-base ${SCRIPT_BASE} \ - --input-dirs k8s.io/kube-aggregator/pkg/apis/apiregistration --input-dirs k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1,k8s.io/kube-aggregator/pkg/apis/apiregistration/v1 \ - --versioned-clientset-package k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset \ - --internal-clientset-package k8s.io/kube-aggregator/pkg/client/clientset_generated/internalclientset \ - --listers-package k8s.io/kube-aggregator/pkg/client/listers \ - --output-package k8s.io/kube-aggregator/pkg/client/informers \ +CLIENTSET_NAME_VERSIONED=clientset \ +CLIENTSET_PKG_NAME=clientset_generated \ +CLIENTSET_NAME_INTERNAL=internalclientset \ +${CODEGEN_PKG}/generate-internal-groups.sh deepcopy,client,lister,informer,conversion \ + k8s.io/kube-aggregator/pkg/client k8s.io/kube-aggregator/pkg/apis k8s.io/kube-aggregator/pkg/apis \ + "apiregistration:v1beta1,v1" \ + --output-base "$(dirname ${BASH_SOURCE})/../../.." \ --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt - "$@" diff --git a/staging/src/k8s.io/kube-aggregator/pkg/apis/OWNERS b/staging/src/k8s.io/kube-aggregator/pkg/apis/OWNERS new file mode 100644 index 0000000000000..bae178f8175ea --- /dev/null +++ b/staging/src/k8s.io/kube-aggregator/pkg/apis/OWNERS @@ -0,0 +1,9 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/kube-controller-manager/Godeps/Godeps.json b/staging/src/k8s.io/kube-controller-manager/Godeps/Godeps.json index 0d07751e86fd5..63be4ce64d5db 100644 --- a/staging/src/k8s.io/kube-controller-manager/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-controller-manager/Godeps/Godeps.json @@ -24,19 +24,19 @@ }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/text/secure/bidirule", diff --git a/staging/src/k8s.io/kube-controller-manager/OWNERS b/staging/src/k8s.io/kube-controller-manager/OWNERS index e3149dc3c06ad..b9492dc62e08c 100644 --- a/staging/src/k8s.io/kube-controller-manager/OWNERS +++ b/staging/src/k8s.io/kube-controller-manager/OWNERS @@ -1,12 +1,10 @@ approvers: -- api-approvers - deads2k - luxas - mtaufen - sttts - stewart-yu reviewers: -- api-reviewers - deads2k - luxas - mtaufen diff --git a/staging/src/k8s.io/kube-controller-manager/config/OWNERS b/staging/src/k8s.io/kube-controller-manager/config/OWNERS new file mode 100644 index 0000000000000..b6f183359baa0 --- /dev/null +++ b/staging/src/k8s.io/kube-controller-manager/config/OWNERS @@ -0,0 +1,14 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +- deads2k +- luxas +- mtaufen +- sttts +- stewart-yu +labels: +- kind/api-change diff --git a/staging/src/k8s.io/kube-proxy/Godeps/Godeps.json b/staging/src/k8s.io/kube-proxy/Godeps/Godeps.json index ff3e44acfaf0d..f056c568f9e75 100644 --- a/staging/src/k8s.io/kube-proxy/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-proxy/Godeps/Godeps.json @@ -24,19 +24,19 @@ }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/text/secure/bidirule", diff --git a/staging/src/k8s.io/kube-proxy/OWNERS b/staging/src/k8s.io/kube-proxy/OWNERS index 69a52b9c86b94..f820d85fb1641 100644 --- a/staging/src/k8s.io/kube-proxy/OWNERS +++ b/staging/src/k8s.io/kube-proxy/OWNERS @@ -1,10 +1,8 @@ approvers: -- api-approvers - sig-network-approvers - sttts - luxas reviewers: -- api-reviewers - sig-network-reviewers - luxas - sttts diff --git a/staging/src/k8s.io/kube-proxy/config/OWNERS b/staging/src/k8s.io/kube-proxy/config/OWNERS new file mode 100644 index 0000000000000..7156a9b8b2741 --- /dev/null +++ b/staging/src/k8s.io/kube-proxy/config/OWNERS @@ -0,0 +1,10 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +- sig-network-reviewers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/kube-scheduler/Godeps/Godeps.json b/staging/src/k8s.io/kube-scheduler/Godeps/Godeps.json index ff61f39417fc9..7a1cd0f06706b 100644 --- a/staging/src/k8s.io/kube-scheduler/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-scheduler/Godeps/Godeps.json @@ -24,19 +24,19 @@ }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/text/secure/bidirule", diff --git a/staging/src/k8s.io/kube-scheduler/OWNERS b/staging/src/k8s.io/kube-scheduler/OWNERS index 1efb6b4a64c5c..13f210bae43d0 100755 --- a/staging/src/k8s.io/kube-scheduler/OWNERS +++ b/staging/src/k8s.io/kube-scheduler/OWNERS @@ -1,11 +1,9 @@ approvers: -- api-approvers - sig-scheduling-maintainers - sttts - luxas reviewers: - sig-scheduling -- api-reviewers - dixudx - luxas - sttts diff --git a/staging/src/k8s.io/kube-scheduler/config/OWNERS b/staging/src/k8s.io/kube-scheduler/config/OWNERS new file mode 100644 index 0000000000000..18a8557ccb9cc --- /dev/null +++ b/staging/src/k8s.io/kube-scheduler/config/OWNERS @@ -0,0 +1,10 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +- sig-scheduling +labels: +- kind/api-change diff --git a/staging/src/k8s.io/kubelet/Godeps/Godeps.json b/staging/src/k8s.io/kubelet/Godeps/Godeps.json index dbf0ed89d3d0b..bf338bcc92c6c 100644 --- a/staging/src/k8s.io/kubelet/Godeps/Godeps.json +++ b/staging/src/k8s.io/kubelet/Godeps/Godeps.json @@ -24,19 +24,19 @@ }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/text/secure/bidirule", diff --git a/staging/src/k8s.io/kubelet/OWNERS b/staging/src/k8s.io/kubelet/OWNERS index 3ac0a7a4077ed..fd46cbf2bb1a4 100644 --- a/staging/src/k8s.io/kubelet/OWNERS +++ b/staging/src/k8s.io/kubelet/OWNERS @@ -1,11 +1,9 @@ approvers: -- api-approvers - sig-node-approvers - sttts - luxas - mtaufen reviewers: -- api-reviewers - sig-node-reviewers - luxas - sttts diff --git a/staging/src/k8s.io/kubelet/config/OWNERS b/staging/src/k8s.io/kubelet/config/OWNERS new file mode 100644 index 0000000000000..930fcf08b7e5c --- /dev/null +++ b/staging/src/k8s.io/kubelet/config/OWNERS @@ -0,0 +1,10 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +- sig-node-reviewers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/metrics/Godeps/Godeps.json b/staging/src/k8s.io/metrics/Godeps/Godeps.json index 75f2f37b22eb3..5bafb5d3582c3 100644 --- a/staging/src/k8s.io/metrics/Godeps/Godeps.json +++ b/staging/src/k8s.io/metrics/Godeps/Godeps.json @@ -112,23 +112,23 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -528,7 +528,7 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" } ] } diff --git a/staging/src/k8s.io/metrics/IMPLEMENTATIONS.md b/staging/src/k8s.io/metrics/IMPLEMENTATIONS.md index 7548bb52c96c9..cde97de5bf1ef 100644 --- a/staging/src/k8s.io/metrics/IMPLEMENTATIONS.md +++ b/staging/src/k8s.io/metrics/IMPLEMENTATIONS.md @@ -24,3 +24,7 @@ They are listed here for convenience.*** - [Google Stackdriver (coming soon)](https://github.com/GoogleCloudPlatform/k8s-stackdriver) + +- [Datadog Cluster Agent](https://github.com/DataDog/datadog-agent/blob/c4f38af1897bac294d8fed6285098b14aafa6178/docs/cluster-agent/CUSTOM_METRICS_SERVER.md). + Implementation of the external metrics provider, using Datadog as a backend for the metrics. + Coming soon: Implementation of the custom metrics provider to support in-cluster metrics collected by the Datadog Agents. \ No newline at end of file diff --git a/staging/src/k8s.io/metrics/pkg/apis/OWNERS b/staging/src/k8s.io/metrics/pkg/apis/OWNERS new file mode 100644 index 0000000000000..083228551a48b --- /dev/null +++ b/staging/src/k8s.io/metrics/pkg/apis/OWNERS @@ -0,0 +1,10 @@ +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- api-reviewers +- sig-autoscaling-maintainers +labels: +- kind/api-change diff --git a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json index 51954a6bbceb9..45dc787be0742 100644 --- a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json @@ -36,39 +36,39 @@ }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Rev": "fca8add78a9d926166eb739b8e4a124434025ba3" + "Rev": "27fc7e2296f506182f58ce846e48f36b34fe6842" }, { "ImportPath": "github.com/coreos/go-systemd/daemon", - "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" + "Rev": "39ca1b05acc7ad1220e09f133283b8859a8b71ab" }, { "ImportPath": "github.com/davecgh/go-spew/spew", @@ -108,19 +108,19 @@ }, { "ImportPath": "github.com/go-openapi/jsonpointer", - "Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98" + "Rev": "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004" }, { "ImportPath": "github.com/go-openapi/jsonreference", - "Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272" + "Rev": "8483a886a90412cd6858df4ea3483dce9c8e35a3" }, { "ImportPath": "github.com/go-openapi/spec", - "Rev": "1de3e0542de65ad8d75452a595886fdd0befb363" + "Rev": "5bae59e25b21498baea7f9d46e9c147ec106a42e" }, { "ImportPath": "github.com/go-openapi/swag", - "Rev": "f3f9494671f93fcff853e3c6e9e948b3eb71e590" + "Rev": "5899d5c5e619fda5fa86e14795a835f473ca284c" }, { "ImportPath": "github.com/gogo/protobuf/gogoproto", @@ -292,35 +292,35 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/internal/timeseries", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/trace", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/websocket", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -970,6 +970,10 @@ "ImportPath": "k8s.io/apiserver/pkg/authentication/serviceaccount", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/apiserver/pkg/authentication/token/cache", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/token/tokenfile", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -1728,23 +1732,23 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" } ] } diff --git a/staging/src/k8s.io/sample-cli-plugin/Godeps/Godeps.json b/staging/src/k8s.io/sample-cli-plugin/Godeps/Godeps.json index abdb88836117c..fbb977f42d4d9 100644 --- a/staging/src/k8s.io/sample-cli-plugin/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-cli-plugin/Godeps/Godeps.json @@ -112,23 +112,23 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", diff --git a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json index 4dc33518aae90..3d979dd437673 100644 --- a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json @@ -120,23 +120,23 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/http2/hpack", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/idna", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/net/lex/httplex", - "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + "Rev": "0ed95abb35c445290478a5348a7b38bb154135fd" }, { "ImportPath": "golang.org/x/oauth2", @@ -1160,7 +1160,7 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + "Rev": "72693cb1fadd73ae2742f6fe29af77d1aecdd8cd" } ] } diff --git a/staging/src/k8s.io/sample-controller/controller.go b/staging/src/k8s.io/sample-controller/controller.go index 57541c71ab468..ab8468a0a28d8 100644 --- a/staging/src/k8s.io/sample-controller/controller.go +++ b/staging/src/k8s.io/sample-controller/controller.go @@ -219,7 +219,9 @@ func (c *Controller) processNextWorkItem() bool { // Run the syncHandler, passing it the namespace/name string of the // Foo resource to be synced. if err := c.syncHandler(key); err != nil { - return fmt.Errorf("error syncing '%s': %s", key, err.Error()) + // Put the item back on the workqueue to handle any transient errors. + c.workqueue.AddRateLimited(key) + return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error()) } // Finally, if no error occurs we Forget this item so it does not // get queued again until another change happens. diff --git a/test/OWNERS b/test/OWNERS index e7f0d66fd8303..ea5cffadabb29 100644 --- a/test/OWNERS +++ b/test/OWNERS @@ -26,6 +26,7 @@ reviewers: - timothysc - zmerlynn - vishh + - MaciekPytel # for test/e2e/common/autoscaling_utils.go approvers: - bowei # for test/e2e/{dns*,network}.go - cblecker @@ -56,5 +57,6 @@ approvers: - timothysc - zmerlynn - vishh + - MaciekPytel # for test/e2e/common/autoscaling_utils.go labels: - sig/testing diff --git a/test/cmd/apps.sh b/test/cmd/apps.sh index e8a7ef30183b6..7cabbabe24adc 100755 --- a/test/cmd/apps.sh +++ b/test/cmd/apps.sh @@ -299,7 +299,7 @@ run_deployment_tests() { sleep 1 kube::test::get_object_assert deployment "{{range.items}}{{$image_field0}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:" # Rollback to revision 1000000 - should be no-op - kubectl rollout undo deployment nginx --to-revision=1000000 "${kube_flags[@]}" + ! kubectl rollout undo deployment nginx --to-revision=1000000 "${kube_flags[@]}" kube::test::get_object_assert deployment "{{range.items}}{{$image_field0}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:" # Rollback to last revision kubectl rollout undo deployment nginx "${kube_flags[@]}" diff --git a/test/cmd/core.sh b/test/cmd/core.sh index 549703fa0eeb0..0300e3bb1c029 100755 --- a/test/cmd/core.sh +++ b/test/cmd/core.sh @@ -1094,6 +1094,34 @@ run_rc_tests() { # Clean-up kubectl delete deployment/nginx-deployment "${kube_flags[@]}" + ### Expose deployments by creating a service + # Uses deployment selectors for created service + output_message=$(kubectl expose -f test/fixtures/pkg/kubectl/cmd/expose/appsv1deployment.yaml --port 80 2>&1 "${kube_flags[@]}") + # Post-condition: service created for deployment. + kube::test::if_has_string "${output_message}" 'service/expose-test-deployment exposed' + # Clean-up + kubectl delete service/expose-test-deployment "${kube_flags[@]}" + # Uses deployment selectors for created service + output_message=$(kubectl expose -f test/fixtures/pkg/kubectl/cmd/expose/appsv1beta2deployment.yaml --port 80 2>&1 "${kube_flags[@]}") + # Post-condition: service created for deployment. + kube::test::if_has_string "${output_message}" 'service/expose-test-deployment exposed' + # Clean-up + kubectl delete service/expose-test-deployment "${kube_flags[@]}" + # Uses deployment selectors for created service + output_message=$(kubectl expose -f test/fixtures/pkg/kubectl/cmd/expose/appsv1beta1deployment.yaml --port 80 2>&1 "${kube_flags[@]}") + # Post-condition: service created for deployment. + kube::test::if_has_string "${output_message}" 'service/expose-test-deployment exposed' + # Clean-up + kubectl delete service/expose-test-deployment "${kube_flags[@]}" + # Contains no selectors, should fail. + output_message=$(! kubectl expose -f test/fixtures/pkg/kubectl/cmd/expose/appsv1deployment-no-selectors.yaml --port 80 2>&1 "${kube_flags[@]}") + # Post-condition: service created for deployment. + kube::test::if_has_string "${output_message}" 'invalid deployment: no selectors' + # Contains no selectors, should fail. + output_message=$(! kubectl expose -f test/fixtures/pkg/kubectl/cmd/expose/appsv1beta2deployment-no-selectors.yaml --port 80 2>&1 "${kube_flags[@]}") + # Post-condition: service created for deployment. + kube::test::if_has_string "${output_message}" 'invalid deployment: no selectors' + ### Expose a deployment as a service kubectl create -f test/fixtures/doc-yaml/user-guide/deployment.yaml "${kube_flags[@]}" # Pre-condition: 3 replicas diff --git a/test/cmd/diff.sh b/test/cmd/diff.sh index bc763473773ec..6d0d5a127525c 100755 --- a/test/cmd/diff.sh +++ b/test/cmd/diff.sh @@ -35,7 +35,7 @@ run_kubectl_diff_tests() { output_message=$(! kubectl diff -f hack/testdata/pod-changed.yaml) kube::test::if_has_string "${output_message}" 'k8s.gcr.io/pause:3.0' - kubectl delete -f hack/testdata/pod.yaml + kubectl delete -f hack/testdata/pod.yaml set +o nounset set +o errexit diff --git a/test/cmd/template-output.sh b/test/cmd/template-output.sh index 1b00843936221..18ad4df13cf6e 100755 --- a/test/cmd/template-output.sh +++ b/test/cmd/template-output.sh @@ -222,7 +222,7 @@ EOF kube::test::if_has_string "${output_message}" 'deploy:' # check that "rollout undo" supports --template output - output_message=$(kubectl "${kube_flags[@]}" rollout undo deploy/deploy --template="{{ .metadata.name }}:") + output_message=$(kubectl "${kube_flags[@]}" rollout undo deploy/deploy --to-revision=1 --template="{{ .metadata.name }}:") kube::test::if_has_string "${output_message}" 'deploy:' # check that "config view" command supports --template output diff --git a/test/conformance/OWNERS b/test/conformance/OWNERS index 81b67c92b7d54..8a14a1e9b9d23 100644 --- a/test/conformance/OWNERS +++ b/test/conformance/OWNERS @@ -2,6 +2,7 @@ reviewers: - mml - cheftako + - spiffxp approvers: - mml - cheftako diff --git a/test/conformance/cf_header.md b/test/conformance/cf_header.md index e4bef5c46e95f..ce24ac47fb094 100644 --- a/test/conformance/cf_header.md +++ b/test/conformance/cf_header.md @@ -2,7 +2,7 @@ ## **Summary** This document provides a summary of the tests included in the Kubernetes conformance test suite. -Each test lists a set of formal requirements that a platform that meets conformance requirements must adhere to. +Each test lists a set of formal requirements that a platform that meets conformance requirements must adhere to. The tests are a subset of the "e2e" tests that make up the Kubernetes testing infrastructure. Each test is identified by the presence of the `[Conformance]` keyword in the ginkgo descriptive function calls. diff --git a/test/conformance/testdata/conformance.txt b/test/conformance/testdata/conformance.txt index 886423bba473c..6962c09d29276 100755 --- a/test/conformance/testdata/conformance.txt +++ b/test/conformance/testdata/conformance.txt @@ -23,7 +23,10 @@ test/e2e/apps/deployment.go: "deployment should delete old replica sets" test/e2e/apps/deployment.go: "deployment should support rollover" test/e2e/apps/deployment.go: "deployment should support proportional scaling" test/e2e/apps/rc.go: "should serve a basic image on each replica with a public image" +test/e2e/apps/rc.go: "should adopt matching pods on creation" +test/e2e/apps/rc.go: "should release no longer matching pods" test/e2e/apps/replica_set.go: "should serve a basic image on each replica with a public image" +test/e2e/apps/replica_set.go: "should adopt matching pods on creation and release no longer matching pods" test/e2e/apps/statefulset.go: "should perform rolling updates and roll backs of template modifications" test/e2e/apps/statefulset.go: "should perform canary updates and phased rolling updates of template modifications" test/e2e/apps/statefulset.go: "Scaling should happen in predictable order and halt if any stateful pod is unhealthy" diff --git a/test/e2e/apimachinery/chunking.go b/test/e2e/apimachinery/chunking.go index d46406e070b68..07fa1f53ce7bd 100644 --- a/test/e2e/apimachinery/chunking.go +++ b/test/e2e/apimachinery/chunking.go @@ -80,7 +80,7 @@ var _ = SIGDescribe("Servers with support for API chunking", func() { for { opts.Limit = int64(rand.Int31n(numberOfTotalResources/10) + 1) list, err := client.List(opts) - Expect(err).ToNot(HaveOccurred()) + Expect(err).ToNot(HaveOccurred(), "failed to list pod templates in namespace: %s, given limit: %d", ns, opts.Limit) framework.Logf("Retrieved %d/%d results with rv %s and continue %s", len(list.Items), opts.Limit, list.ResourceVersion, list.Continue) Expect(len(list.Items)).To(BeNumerically("<=", opts.Limit)) @@ -101,8 +101,9 @@ var _ = SIGDescribe("Servers with support for API chunking", func() { } By("retrieving those results all at once") - list, err := client.List(metav1.ListOptions{Limit: numberOfTotalResources + 1}) - Expect(err).ToNot(HaveOccurred()) + opts := metav1.ListOptions{Limit: numberOfTotalResources + 1} + list, err := client.List(opts) + Expect(err).ToNot(HaveOccurred(), "failed to list pod templates in namespace: %s, given limit: %d", ns, opts.Limit) Expect(list.Items).To(HaveLen(numberOfTotalResources)) }) @@ -116,7 +117,7 @@ var _ = SIGDescribe("Servers with support for API chunking", func() { opts := metav1.ListOptions{} opts.Limit = oneTenth list, err := client.List(opts) - Expect(err).ToNot(HaveOccurred()) + Expect(err).ToNot(HaveOccurred(), "failed to list pod templates in namespace: %s, given limit: %d", ns, opts.Limit) firstToken := list.Continue firstRV := list.ResourceVersion framework.Logf("Retrieved %d/%d results with rv %s and continue %s", len(list.Items), opts.Limit, list.ResourceVersion, firstToken) @@ -149,7 +150,7 @@ var _ = SIGDescribe("Servers with support for API chunking", func() { By("retrieving the second page again with the token received with the error message") opts.Continue = inconsistentToken list, err = client.List(opts) - Expect(err).ToNot(HaveOccurred()) + Expect(err).ToNot(HaveOccurred(), "failed to list pod templates in namespace: %s, given inconsistent continue token %s and limit: %d", ns, opts.Continue, opts.Limit) Expect(list.ResourceVersion).ToNot(Equal(firstRV)) Expect(len(list.Items)).To(BeNumerically("==", opts.Limit)) found := oneTenth @@ -163,7 +164,7 @@ var _ = SIGDescribe("Servers with support for API chunking", func() { lastRV := list.ResourceVersion for { list, err := client.List(opts) - Expect(err).ToNot(HaveOccurred()) + Expect(err).ToNot(HaveOccurred(), "failed to list pod templates in namespace: %s, given limit: %d", ns, opts.Limit) framework.Logf("Retrieved %d/%d results with rv %s and continue %s", len(list.Items), opts.Limit, list.ResourceVersion, list.Continue) Expect(len(list.Items)).To(BeNumerically("<=", opts.Limit)) Expect(list.ResourceVersion).To(Equal(lastRV)) diff --git a/test/e2e/apimachinery/crd_watch.go b/test/e2e/apimachinery/crd_watch.go index 93339f5980c37..e3f04a33779ad 100644 --- a/test/e2e/apimachinery/crd_watch.go +++ b/test/e2e/apimachinery/crd_watch.go @@ -80,35 +80,35 @@ var _ = SIGDescribe("CustomResourceDefinition Watch", func() { noxuResourceClient := newNamespacedCustomResourceClient(ns, f.DynamicClient, noxuDefinition) watchA, err := watchCRWithName(noxuResourceClient, watchCRNameA) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to watch custom resource: %s", watchCRNameA) watchB, err := watchCRWithName(noxuResourceClient, watchCRNameB) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to watch custom resource: %s", watchCRNameB) testCrA := fixtures.NewNoxuInstance(ns, watchCRNameA) testCrB := fixtures.NewNoxuInstance(ns, watchCRNameB) By("Creating first CR ") testCrA, err = instantiateCustomResource(testCrA, noxuResourceClient, noxuDefinition) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to instantiate custom resource: %+v", testCrA) expectEvent(watchA, watch.Added, testCrA) expectNoEvent(watchB, watch.Added, testCrA) By("Creating second CR") testCrB, err = instantiateCustomResource(testCrB, noxuResourceClient, noxuDefinition) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to instantiate custom resource: %+v", testCrB) expectEvent(watchB, watch.Added, testCrB) expectNoEvent(watchA, watch.Added, testCrB) By("Deleting first CR") err = deleteCustomResource(noxuResourceClient, watchCRNameA) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete custom resource: %s", watchCRNameA) expectEvent(watchA, watch.Deleted, nil) expectNoEvent(watchB, watch.Deleted, nil) By("Deleting second CR") err = deleteCustomResource(noxuResourceClient, watchCRNameB) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete custom resource: %s", watchCRNameB) expectEvent(watchB, watch.Deleted, nil) expectNoEvent(watchA, watch.Deleted, nil) }) diff --git a/test/e2e/apimachinery/etcd_failure.go b/test/e2e/apimachinery/etcd_failure.go index 4f1d9c4c03f0c..d1e6da23faff8 100644 --- a/test/e2e/apimachinery/etcd_failure.go +++ b/test/e2e/apimachinery/etcd_failure.go @@ -94,8 +94,9 @@ func doEtcdFailure(failCommand, fixCommand string) { } func masterExec(cmd string) { - result, err := framework.SSH(cmd, framework.GetMasterHost()+":22", framework.TestContext.Provider) - Expect(err).NotTo(HaveOccurred()) + host := framework.GetMasterHost() + ":22" + result, err := framework.SSH(cmd, host, framework.TestContext.Provider) + Expect(err).NotTo(HaveOccurred(), "failed to SSH to host %s on provider %s and run command: %q", host, framework.TestContext.Provider, cmd) if result.Code != 0 { framework.LogSSHResult(result) framework.Failf("master exec command returned non-zero") @@ -120,7 +121,7 @@ func checkExistingRCRecovers(f *framework.Framework) { } for _, pod := range pods.Items { err = podClient.Delete(pod.Name, metav1.NewDeleteOptions(0)) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete pod %s in namespace: %s", pod.Name, f.Namespace.Name) } framework.Logf("apiserver has recovered") return true, nil @@ -130,7 +131,7 @@ func checkExistingRCRecovers(f *framework.Framework) { framework.ExpectNoError(wait.Poll(time.Millisecond*500, time.Second*60, func() (bool, error) { options := metav1.ListOptions{LabelSelector: rcSelector.String()} pods, err := podClient.List(options) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to list pods in namespace: %s, that match label selector: %s", f.Namespace.Name, rcSelector.String()) for _, pod := range pods.Items { if pod.DeletionTimestamp == nil && podutil.IsPodReady(&pod) { return true, nil diff --git a/test/e2e/apimachinery/garbage_collector.go b/test/e2e/apimachinery/garbage_collector.go index fa2f6f4e5f64e..875e390ae8bac 100644 --- a/test/e2e/apimachinery/garbage_collector.go +++ b/test/e2e/apimachinery/garbage_collector.go @@ -737,12 +737,12 @@ var _ = SIGDescribe("Garbage collector", func() { } By(fmt.Sprintf("set half of pods created by rc %s to have rc %s as owner as well", rc1Name, rc2Name)) pods, err := podClient.List(metav1.ListOptions{}) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to list pods in namespace: %s", f.Namespace.Name) patch := fmt.Sprintf(`{"metadata":{"ownerReferences":[{"apiVersion":"v1","kind":"ReplicationController","name":"%s","uid":"%s"}]}}`, rc2.ObjectMeta.Name, rc2.ObjectMeta.UID) for i := 0; i < halfReplicas; i++ { pod := pods.Items[i] _, err := podClient.Patch(pod.Name, types.StrategicMergePatchType, []byte(patch)) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to apply to pod %s in namespace %s, a strategic merge patch: %s", pod.Name, f.Namespace.Name, patch) } By(fmt.Sprintf("delete the rc %s", rc1Name)) @@ -816,33 +816,39 @@ var _ = SIGDescribe("Garbage collector", func() { framework.ConformanceIt("should not be blocked by dependency circle", func() { clientSet := f.ClientSet podClient := clientSet.CoreV1().Pods(f.Namespace.Name) - pod1 := newGCPod("pod1") + pod1Name := "pod1" + pod1 := newGCPod(pod1Name) pod1, err := podClient.Create(pod1) - Expect(err).NotTo(HaveOccurred()) - pod2 := newGCPod("pod2") + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", pod1Name, f.Namespace.Name) + pod2Name := "pod2" + pod2 := newGCPod(pod2Name) pod2, err = podClient.Create(pod2) - Expect(err).NotTo(HaveOccurred()) - pod3 := newGCPod("pod3") + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", pod2Name, f.Namespace.Name) + pod3Name := "pod3" + pod3 := newGCPod(pod3Name) pod3, err = podClient.Create(pod3) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", pod3Name, f.Namespace.Name) // create circular dependency addRefPatch := func(name string, uid types.UID) []byte { return []byte(fmt.Sprintf(`{"metadata":{"ownerReferences":[{"apiVersion":"v1","kind":"Pod","name":"%s","uid":"%s","controller":true,"blockOwnerDeletion":true}]}}`, name, uid)) } - pod1, err = podClient.Patch(pod1.Name, types.StrategicMergePatchType, addRefPatch(pod3.Name, pod3.UID)) - Expect(err).NotTo(HaveOccurred()) + patch1 := addRefPatch(pod3.Name, pod3.UID) + pod1, err = podClient.Patch(pod1.Name, types.StrategicMergePatchType, patch1) + Expect(err).NotTo(HaveOccurred(), "failed to apply to pod %s in namespace %s, a strategic merge patch: %s", pod1.Name, f.Namespace.Name, patch1) framework.Logf("pod1.ObjectMeta.OwnerReferences=%#v", pod1.ObjectMeta.OwnerReferences) - pod2, err = podClient.Patch(pod2.Name, types.StrategicMergePatchType, addRefPatch(pod1.Name, pod1.UID)) - Expect(err).NotTo(HaveOccurred()) + patch2 := addRefPatch(pod1.Name, pod1.UID) + pod2, err = podClient.Patch(pod2.Name, types.StrategicMergePatchType, patch2) + Expect(err).NotTo(HaveOccurred(), "failed to apply to pod %s in namespace %s, a strategic merge patch: %s", pod2.Name, f.Namespace.Name, patch2) framework.Logf("pod2.ObjectMeta.OwnerReferences=%#v", pod2.ObjectMeta.OwnerReferences) - pod3, err = podClient.Patch(pod3.Name, types.StrategicMergePatchType, addRefPatch(pod2.Name, pod2.UID)) - Expect(err).NotTo(HaveOccurred()) + patch3 := addRefPatch(pod2.Name, pod2.UID) + pod3, err = podClient.Patch(pod3.Name, types.StrategicMergePatchType, patch3) + Expect(err).NotTo(HaveOccurred(), "failed to apply to pod %s in namespace %s, a strategic merge patch: %s", pod3.Name, f.Namespace.Name, patch3) framework.Logf("pod3.ObjectMeta.OwnerReferences=%#v", pod3.ObjectMeta.OwnerReferences) // delete one pod, should result in the deletion of all pods deleteOptions := getForegroundOptions() deleteOptions.Preconditions = metav1.NewUIDPreconditions(string(pod1.UID)) err = podClient.Delete(pod1.ObjectMeta.Name, deleteOptions) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete pod %s in namespace: %s", pod1.Name, f.Namespace.Name) var pods *v1.PodList var err2 error // TODO: shorten the timeout when we make GC's periodic API rediscovery more efficient. @@ -1073,7 +1079,7 @@ var _ = SIGDescribe("Garbage collector", func() { By("Create the cronjob") cronJob := newCronJob("simple", "*/1 * * * ?") cronJob, err := f.ClientSet.BatchV1beta1().CronJobs(f.Namespace.Name).Create(cronJob) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create cronjob: %+v, in namespace: %s", cronJob, f.Namespace.Name) By("Wait for the CronJob to create new Job") err = wait.PollImmediate(500*time.Millisecond, 2*time.Minute, func() (bool, error) { diff --git a/test/e2e/apimachinery/initializers.go b/test/e2e/apimachinery/initializers.go index f0381721f1a3d..1adfd2d047199 100644 --- a/test/e2e/apimachinery/initializers.go +++ b/test/e2e/apimachinery/initializers.go @@ -52,8 +52,9 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { ch := make(chan struct{}) go func() { - _, err := c.CoreV1().Pods(ns).Create(newUninitializedPod(podName)) - Expect(err).NotTo(HaveOccurred()) + pod := newUninitializedPod(podName) + _, err := c.CoreV1().Pods(ns).Create(pod) + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", podName, ns) close(ch) }() @@ -72,34 +73,35 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { // verify that we can update an initializing pod pod, err := c.CoreV1().Pods(ns).Get(podName, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get pod %s in namespace: %s", podName, ns) pod.Annotations = map[string]string{"update-1": "test"} pod, err = c.CoreV1().Pods(ns).Update(pod) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update pod %s in namespace %s to: %+v", pod.Name, ns, pod) // verify the list call filters out uninitialized pods - pods, err := c.CoreV1().Pods(ns).List(metav1.ListOptions{IncludeUninitialized: true}) - Expect(err).NotTo(HaveOccurred()) + listOptions := metav1.ListOptions{IncludeUninitialized: true} + pods, err := c.CoreV1().Pods(ns).List(listOptions) + Expect(err).NotTo(HaveOccurred(), "failed to list pods in namespace: %s, given list options: %+v", ns, listOptions) Expect(pods.Items).To(HaveLen(1)) pods, err = c.CoreV1().Pods(ns).List(metav1.ListOptions{}) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to list pods in namespace: %s", ns) Expect(pods.Items).To(HaveLen(0)) // clear initializers pod.Initializers = nil pod, err = c.CoreV1().Pods(ns).Update(pod) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update pod %s in namespace %s to: %+v", pod.Name, ns, pod) // pod should now start running err = framework.WaitForPodRunningInNamespace(c, pod) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "error while waiting for pod %s to go to Running phase in namespace: %s", pod.Name, pod.Namespace) // ensure create call returns <-ch // verify that we cannot start the pod initializing again pod, err = c.CoreV1().Pods(ns).Get(podName, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get pod %s in namespace: %s", podName, ns) pod.Initializers = &metav1.Initializers{ Pending: []metav1.Initializer{{Name: "Other"}}, } @@ -119,7 +121,7 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { // create and register an initializer initializerName := "pod.test.e2e.kubernetes.io" initializerConfigName := "e2e-test-initializer" - _, err := c.AdmissionregistrationV1alpha1().InitializerConfigurations().Create(&v1alpha1.InitializerConfiguration{ + initializerConfig := &v1alpha1.InitializerConfiguration{ ObjectMeta: metav1.ObjectMeta{Name: initializerConfigName}, Initializers: []v1alpha1.Initializer{ { @@ -129,11 +131,12 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { }, }, }, - }) + } + _, err := c.AdmissionregistrationV1alpha1().InitializerConfigurations().Create(initializerConfig) if errors.IsNotFound(err) { framework.Skipf("dynamic configuration of initializers requires the alpha admissionregistration.k8s.io group to be enabled") } - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create and register initializer with config: %+v", initializerConfig) // we must remove the initializer when the test is complete and ensure no pods are pending for that initializer defer cleanupInitializer(c, initializerConfigName, initializerName) @@ -145,8 +148,9 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { ch := make(chan struct{}) go func() { defer close(ch) - _, err := c.CoreV1().Pods(ns).Create(newInitPod(podName)) - Expect(err).NotTo(HaveOccurred()) + pod := newInitPod(podName) + _, err := c.CoreV1().Pods(ns).Create(pod) + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", podName, ns) }() // wait until the pod shows up uninitialized @@ -162,7 +166,7 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { } return true, nil }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get pod %s from namespace: %s", podName, ns) Expect(pod.Initializers).NotTo(BeNil()) Expect(pod.Initializers.Pending).To(HaveLen(1)) Expect(pod.Initializers.Pending[0].Name).To(Equal(initializerName)) @@ -171,14 +175,14 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { By("Completing initialization") pod.Initializers = nil pod, err = c.CoreV1().Pods(ns).Update(pod) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update pod %s in namespace %s to: %+v", pod.Name, ns, pod) // ensure create call returns <-ch // pod should now start running err = framework.WaitForPodRunningInNamespace(c, pod) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "error while waiting for pod %s to go to Running phase in namespace: %s", pod.Name, pod.Namespace) // bypass initialization by explicitly passing an empty pending list By("Setting an empty initializer as an admin to bypass initialization") @@ -186,7 +190,7 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { pod = newUninitializedPod(podName) pod.Initializers.Pending = nil pod, err = c.CoreV1().Pods(ns).Create(pod) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", podName, ns) Expect(pod.Initializers).To(BeNil()) // bypass initialization for mirror pods @@ -198,7 +202,7 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { } pod.Spec.NodeName = "node-does-not-yet-exist" pod, err = c.CoreV1().Pods(ns).Create(pod) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", podName, ns) Expect(pod.Initializers).To(BeNil()) Expect(pod.Annotations[v1.MirrorPodAnnotationKey]).To(Equal("true")) }) @@ -213,7 +217,7 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { // create and register an initializer, without setting up a controller to handle it. initializerName := "pod.test.e2e.kubernetes.io" initializerConfigName := "e2e-test-initializer" - _, err := c.AdmissionregistrationV1alpha1().InitializerConfigurations().Create(&v1alpha1.InitializerConfiguration{ + initializerConfig := &v1alpha1.InitializerConfiguration{ ObjectMeta: metav1.ObjectMeta{Name: initializerConfigName}, Initializers: []v1alpha1.Initializer{ { @@ -223,11 +227,12 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { }, }, }, - }) + } + _, err := c.AdmissionregistrationV1alpha1().InitializerConfigurations().Create(initializerConfig) if errors.IsNotFound(err) { framework.Skipf("dynamic configuration of initializers requires the alpha admissionregistration.k8s.io group to be enabled") } - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create and register initializer with config: %+v", initializerConfig) // we must remove the initializer when the test is complete and ensure no pods are pending for that initializer defer cleanupInitializer(c, initializerConfigName, initializerName) @@ -236,31 +241,32 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { time.Sleep(3 * time.Second) // create a replicaset - persistedRS, err := c.ExtensionsV1beta1().ReplicaSets(ns).Create(newReplicaset()) - Expect(err).NotTo(HaveOccurred()) + rs := newReplicaset() + persistedRS, err := c.ExtensionsV1beta1().ReplicaSets(ns).Create(rs) + Expect(err).NotTo(HaveOccurred(), "failed to create replicaset %s in namespace: %s", persistedRS.Name, ns) // wait for replicaset controller to confirm that it has handled the creation err = waitForRSObservedGeneration(c, persistedRS.Namespace, persistedRS.Name, persistedRS.Generation) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "replicaset %s failed to observe generation: %d", persistedRS.Name, persistedRS.Generation) // update the replicaset spec to trigger a resync patch := []byte(`{"spec":{"minReadySeconds":5}}`) persistedRS, err = c.ExtensionsV1beta1().ReplicaSets(ns).Patch(persistedRS.Name, types.StrategicMergePatchType, patch) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to apply to replicaset %s in namespace %s a strategic merge patch: %s", persistedRS.Name, ns, patch) // wait for replicaset controller to confirm that it has handle the spec update err = waitForRSObservedGeneration(c, persistedRS.Namespace, persistedRS.Name, persistedRS.Generation) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "replicaset %s failed to observe generation: %d", persistedRS.Name, persistedRS.Generation) // verify that the replicaset controller doesn't create extra pod selector, err := metav1.LabelSelectorAsSelector(persistedRS.Spec.Selector) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to convert label selector %+v of LabelSelector api type into a struct that implements labels.Selector", persistedRS.Spec.Selector) listOptions := metav1.ListOptions{ LabelSelector: selector.String(), IncludeUninitialized: true, } pods, err := c.CoreV1().Pods(ns).List(listOptions) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to list pods in namespace: %s, given list options: %+v", ns, listOptions) Expect(len(pods.Items)).Should(Equal(1)) }) @@ -277,13 +283,13 @@ var _ = SIGDescribe("Initializers [Feature:Initializers]", func() { framework.Failf("expect err to be timeout error, got %v", err) } uninitializedPod, err := c.CoreV1().Pods(ns).Get(podName, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get pod %s in namespace: %s", podName, ns) Expect(uninitializedPod.Initializers).NotTo(BeNil()) Expect(len(uninitializedPod.Initializers.Pending)).Should(Equal(1)) patch := fmt.Sprintf(`{"metadata":{"initializers":{"pending":[{"$patch":"delete","name":"%s"}]}}}`, uninitializedPod.Initializers.Pending[0].Name) patchedPod, err := c.CoreV1().Pods(ns).Patch(uninitializedPod.Name, types.StrategicMergePatchType, []byte(patch)) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to apply to pod %s in namespace %s a strategic merge patch: %s", uninitializedPod.Name, ns, patch) Expect(patchedPod.Initializers).To(BeNil()) }) }) diff --git a/test/e2e/apimachinery/namespace.go b/test/e2e/apimachinery/namespace.go index 7f090baae699e..9c39ee4fab8c1 100644 --- a/test/e2e/apimachinery/namespace.go +++ b/test/e2e/apimachinery/namespace.go @@ -45,8 +45,9 @@ func extinguish(f *framework.Framework, totalNS int, maxAllowedAfterDel int, max go func(n int) { defer wg.Done() defer GinkgoRecover() - _, err = f.CreateNamespace(fmt.Sprintf("nslifetest-%v", n), nil) - Expect(err).NotTo(HaveOccurred()) + ns := fmt.Sprintf("nslifetest-%v", n) + _, err = f.CreateNamespace(ns, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create namespace: %s", ns) }(n) } wg.Wait() @@ -54,8 +55,9 @@ func extinguish(f *framework.Framework, totalNS int, maxAllowedAfterDel int, max //Wait 10 seconds, then SEND delete requests for all the namespaces. By("Waiting 10 seconds") time.Sleep(time.Duration(10 * time.Second)) - deleted, err := framework.DeleteNamespaces(f.ClientSet, []string{"nslifetest"}, nil /* skipFilter */) - Expect(err).NotTo(HaveOccurred()) + deleteFilter := []string{"nslifetest"} + deleted, err := framework.DeleteNamespaces(f.ClientSet, deleteFilter, nil /* skipFilter */) + Expect(err).NotTo(HaveOccurred(), "failed to delete namespace(s) containing: %s", deleteFilter) Expect(len(deleted)).To(Equal(totalNS)) By("Waiting for namespaces to vanish") @@ -93,23 +95,25 @@ func waitForPodInNamespace(c clientset.Interface, ns, podName string) *v1.Pod { } return true, nil }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get pod %s in namespace: %s", podName, ns) return pod } func ensurePodsAreRemovedWhenNamespaceIsDeleted(f *framework.Framework) { By("Creating a test namespace") - namespace, err := f.CreateNamespace("nsdeletetest", nil) - Expect(err).NotTo(HaveOccurred()) + namespaceName := "nsdeletetest" + namespace, err := f.CreateNamespace(namespaceName, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create namespace: %s", namespaceName) By("Waiting for a default service account to be provisioned in namespace") err = framework.WaitForDefaultServiceAccountInNamespace(f.ClientSet, namespace.Name) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failure while waiting for a default service account to be provisioned in namespace: %s", namespace.Name) By("Creating a pod in the namespace") + podName := "test-pod" pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ - Name: "test-pod", + Name: podName, }, Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -121,7 +125,7 @@ func ensurePodsAreRemovedWhenNamespaceIsDeleted(f *framework.Framework) { }, } pod, err = f.ClientSet.CoreV1().Pods(namespace.Name).Create(pod) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", podName, namespace.Name) By("Waiting for the pod to have running status") framework.ExpectNoError(framework.WaitForPodRunningInNamespace(f.ClientSet, pod)) @@ -150,7 +154,7 @@ func ensurePodsAreRemovedWhenNamespaceIsDeleted(f *framework.Framework) { By("Deleting the namespace") err = f.ClientSet.CoreV1().Namespaces().Delete(namespace.Name, nil) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete namespace: %s", namespace.Name) By("Waiting for the namespace to be removed.") maxWaitSeconds := int64(60) + *pod.Spec.TerminationGracePeriodSeconds @@ -164,26 +168,27 @@ func ensurePodsAreRemovedWhenNamespaceIsDeleted(f *framework.Framework) { })) By("Recreating the namespace") - namespace, err = f.CreateNamespace("nsdeletetest", nil) - Expect(err).NotTo(HaveOccurred()) + namespace, err = f.CreateNamespace(namespaceName, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create namespace: %s", namespaceName) By("Verifying there are no pods in the namespace") _, err = f.ClientSet.CoreV1().Pods(namespace.Name).Get(pod.Name, metav1.GetOptions{}) - Expect(err).To(HaveOccurred()) + Expect(err).To(HaveOccurred(), "failed to get pod %s in namespace: %s", pod.Name, namespace.Name) _, err = f.ClientSet.CoreV1().Pods(namespace.Name).Get(podB.Name, metav1.GetOptions{IncludeUninitialized: true}) - Expect(err).To(HaveOccurred()) + Expect(err).To(HaveOccurred(), "failed to get pod %s in namespace: %s", podB.Name, namespace.Name) } func ensureServicesAreRemovedWhenNamespaceIsDeleted(f *framework.Framework) { var err error By("Creating a test namespace") - namespace, err := f.CreateNamespace("nsdeletetest", nil) - Expect(err).NotTo(HaveOccurred()) + namespaceName := "nsdeletetest" + namespace, err := f.CreateNamespace(namespaceName, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create namespace: %s", namespaceName) By("Waiting for a default service account to be provisioned in namespace") err = framework.WaitForDefaultServiceAccountInNamespace(f.ClientSet, namespace.Name) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failure while waiting for a default service account to be provisioned in namespace: %s", namespace.Name) By("Creating a service in the namespace") serviceName := "test-service" @@ -204,11 +209,11 @@ func ensureServicesAreRemovedWhenNamespaceIsDeleted(f *framework.Framework) { }, } service, err = f.ClientSet.CoreV1().Services(namespace.Name).Create(service) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create service %s in namespace %s", serviceName, namespace.Name) By("Deleting the namespace") err = f.ClientSet.CoreV1().Namespaces().Delete(namespace.Name, nil) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete namespace: %s", namespace.Name) By("Waiting for the namespace to be removed.") maxWaitSeconds := int64(60) @@ -222,12 +227,12 @@ func ensureServicesAreRemovedWhenNamespaceIsDeleted(f *framework.Framework) { })) By("Recreating the namespace") - namespace, err = f.CreateNamespace("nsdeletetest", nil) - Expect(err).NotTo(HaveOccurred()) + namespace, err = f.CreateNamespace(namespaceName, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create namespace: %s", namespaceName) By("Verifying there is no service in the namespace") _, err = f.ClientSet.CoreV1().Services(namespace.Name).Get(service.Name, metav1.GetOptions{}) - Expect(err).To(HaveOccurred()) + Expect(err).To(HaveOccurred(), "failed to get service %s in namespace: %s", service.Name, namespace.Name) } // This test must run [Serial] due to the impact of running other parallel diff --git a/test/e2e/apimachinery/table_conversion.go b/test/e2e/apimachinery/table_conversion.go index 1356b4e79dd61..3d66bd88ab92d 100644 --- a/test/e2e/apimachinery/table_conversion.go +++ b/test/e2e/apimachinery/table_conversion.go @@ -55,11 +55,11 @@ var _ = SIGDescribe("Servers with support for Table transformation", func() { framework.Logf("Creating pod %s", podName) _, err := c.CoreV1().Pods(ns).Create(newTablePod(podName)) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", podName, ns) table := &metav1beta1.Table{} err = c.CoreV1().RESTClient().Get().Resource("pods").Namespace(ns).Name(podName).SetHeader("Accept", "application/json;as=Table;v=v1beta1;g=meta.k8s.io").Do().Into(table) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get pod %s in Table form in namespace: %s", podName, ns) framework.Logf("Table: %#v", table) Expect(len(table.ColumnDefinitions)).To(BeNumerically(">", 2)) @@ -107,7 +107,7 @@ var _ = SIGDescribe("Servers with support for Table transformation", func() { VersionedParams(&metav1.ListOptions{Limit: 2}, metav1.ParameterCodec). SetHeader("Accept", "application/json;as=Table;v=v1beta1;g=meta.k8s.io"). Do().Into(pagedTable) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get pod templates in Table form in namespace: %s", ns) Expect(len(pagedTable.Rows)).To(Equal(2)) Expect(pagedTable.ResourceVersion).ToNot(Equal("")) Expect(pagedTable.SelfLink).ToNot(Equal("")) @@ -119,7 +119,7 @@ var _ = SIGDescribe("Servers with support for Table transformation", func() { VersionedParams(&metav1.ListOptions{Continue: pagedTable.Continue}, metav1.ParameterCodec). SetHeader("Accept", "application/json;as=Table;v=v1beta1;g=meta.k8s.io"). Do().Into(pagedTable) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get pod templates in Table form in namespace: %s", ns) Expect(len(pagedTable.Rows)).To(BeNumerically(">", 0)) Expect(pagedTable.Rows[0].Cells[0]).To(Equal("template-0002")) }) @@ -129,7 +129,7 @@ var _ = SIGDescribe("Servers with support for Table transformation", func() { table := &metav1beta1.Table{} err := c.CoreV1().RESTClient().Get().Resource("nodes").SetHeader("Accept", "application/json;as=Table;v=v1beta1;g=meta.k8s.io").Do().Into(table) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to get nodes in Table form across all namespaces") framework.Logf("Table: %#v", table) Expect(len(table.ColumnDefinitions)).To(BeNumerically(">=", 2)) @@ -157,7 +157,7 @@ var _ = SIGDescribe("Servers with support for Table transformation", func() { }, } err := c.AuthorizationV1().RESTClient().Post().Resource("selfsubjectaccessreviews").SetHeader("Accept", "application/json;as=Table;v=v1beta1;g=meta.k8s.io").Body(sar).Do().Into(table) - Expect(err).To(HaveOccurred()) + Expect(err).To(HaveOccurred(), "failed to return error when posting self subject access review: %+v, to a backend that does not implement metadata", sar) Expect(err.(errors.APIStatus).Status().Code).To(Equal(int32(406))) }) }) @@ -166,7 +166,7 @@ func printTable(table *metav1beta1.Table) string { buf := &bytes.Buffer{} tw := tabwriter.NewWriter(buf, 5, 8, 1, ' ', 0) err := printers.PrintTable(table, tw, printers.PrintOptions{}) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to print table: %+v", table) tw.Flush() return buf.String() } diff --git a/test/e2e/apimachinery/watch.go b/test/e2e/apimachinery/watch.go index 4709f9c04181e..f26edbee0ffbd 100644 --- a/test/e2e/apimachinery/watch.go +++ b/test/e2e/apimachinery/watch.go @@ -57,15 +57,15 @@ var _ = SIGDescribe("Watchers", func() { By("creating a watch on configmaps with label A") watchA, err := watchConfigMaps(f, "", multipleWatchersLabelValueA) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create a watch on configmaps with label: %s", multipleWatchersLabelValueA) By("creating a watch on configmaps with label B") watchB, err := watchConfigMaps(f, "", multipleWatchersLabelValueB) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create a watch on configmaps with label: %s", multipleWatchersLabelValueB) By("creating a watch on configmaps with label A or B") watchAB, err := watchConfigMaps(f, "", multipleWatchersLabelValueA, multipleWatchersLabelValueB) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create a watch on configmaps with label %s or %s", multipleWatchersLabelValueA, multipleWatchersLabelValueB) testConfigMapA := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -86,7 +86,7 @@ var _ = SIGDescribe("Watchers", func() { By("creating a configmap with label A and ensuring the correct watchers observe the notification") testConfigMapA, err = c.CoreV1().ConfigMaps(ns).Create(testConfigMapA) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create a configmap with label %s in namespace: %s", multipleWatchersLabelValueA, ns) expectEvent(watchA, watch.Added, testConfigMapA) expectEvent(watchAB, watch.Added, testConfigMapA) expectNoEvent(watchB, watch.Added, testConfigMapA) @@ -95,7 +95,7 @@ var _ = SIGDescribe("Watchers", func() { testConfigMapA, err = updateConfigMap(c, ns, testConfigMapA.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "1") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace: %s", testConfigMapA.GetName(), ns) expectEvent(watchA, watch.Modified, testConfigMapA) expectEvent(watchAB, watch.Modified, testConfigMapA) expectNoEvent(watchB, watch.Modified, testConfigMapA) @@ -104,28 +104,28 @@ var _ = SIGDescribe("Watchers", func() { testConfigMapA, err = updateConfigMap(c, ns, testConfigMapA.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "2") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace: %s", testConfigMapA.GetName(), ns) expectEvent(watchA, watch.Modified, testConfigMapA) expectEvent(watchAB, watch.Modified, testConfigMapA) expectNoEvent(watchB, watch.Modified, testConfigMapA) By("deleting configmap A and ensuring the correct watchers observe the notification") err = c.CoreV1().ConfigMaps(ns).Delete(testConfigMapA.GetName(), nil) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete configmap %s in namespace: %s", testConfigMapA.GetName(), ns) expectEvent(watchA, watch.Deleted, nil) expectEvent(watchAB, watch.Deleted, nil) expectNoEvent(watchB, watch.Deleted, nil) By("creating a configmap with label B and ensuring the correct watchers observe the notification") testConfigMapB, err = c.CoreV1().ConfigMaps(ns).Create(testConfigMapB) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create configmap %s in namespace: %s", testConfigMapB, ns) expectEvent(watchB, watch.Added, testConfigMapB) expectEvent(watchAB, watch.Added, testConfigMapB) expectNoEvent(watchA, watch.Added, testConfigMapB) By("deleting configmap B and ensuring the correct watchers observe the notification") err = c.CoreV1().ConfigMaps(ns).Delete(testConfigMapB.GetName(), nil) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete configmap %s in namespace: %s", testConfigMapB.GetName(), ns) expectEvent(watchB, watch.Deleted, nil) expectEvent(watchAB, watch.Deleted, nil) expectNoEvent(watchA, watch.Deleted, nil) @@ -151,27 +151,27 @@ var _ = SIGDescribe("Watchers", func() { By("creating a new configmap") testConfigMap, err := c.CoreV1().ConfigMaps(ns).Create(testConfigMap) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create configmap %s in namespace: %s", testConfigMap.GetName(), ns) By("modifying the configmap once") testConfigMapFirstUpdate, err := updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "1") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace: %s", testConfigMap.GetName(), ns) By("modifying the configmap a second time") testConfigMapSecondUpdate, err := updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "2") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace %s a second time", testConfigMap.GetName(), ns) By("deleting the configmap") err = c.CoreV1().ConfigMaps(ns).Delete(testConfigMap.GetName(), nil) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete configmap %s in namespace: %s", testConfigMap.GetName(), ns) By("creating a watch on configmaps from the resource version returned by the first update") testWatch, err := watchConfigMaps(f, testConfigMapFirstUpdate.ObjectMeta.ResourceVersion, fromResourceVersionLabelValue) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create a watch on configmaps from the resource version %s returned by the first update", testConfigMapFirstUpdate.ObjectMeta.ResourceVersion) By("Expecting to observe notifications for all changes to the configmap after the first update") expectEvent(testWatch, watch.Modified, testConfigMapSecondUpdate) @@ -188,9 +188,10 @@ var _ = SIGDescribe("Watchers", func() { c := f.ClientSet ns := f.Namespace.Name + configMapName := "e2e-watch-test-watch-closed" testConfigMap := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: "e2e-watch-test-watch-closed", + Name: configMapName, Labels: map[string]string{ watchConfigMapLabelKey: watchRestartedLabelValue, }, @@ -199,17 +200,17 @@ var _ = SIGDescribe("Watchers", func() { By("creating a watch on configmaps") testWatchBroken, err := watchConfigMaps(f, "", watchRestartedLabelValue) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create a watch on configmap with label: %s", watchRestartedLabelValue) By("creating a new configmap") testConfigMap, err = c.CoreV1().ConfigMaps(ns).Create(testConfigMap) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create configmap %s in namespace: %s", configMapName, ns) By("modifying the configmap once") _, err = updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "1") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace: %s", configMapName, ns) By("closing the watch once it receives two notifications") expectEvent(testWatchBroken, watch.Added, testConfigMap) @@ -223,7 +224,7 @@ var _ = SIGDescribe("Watchers", func() { testConfigMapSecondUpdate, err := updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "2") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace %s a second time", configMapName, ns) By("creating a new watch on configmaps from the last resource version observed by the first watch") lastEventConfigMap, ok := lastEvent.Object.(*v1.ConfigMap) @@ -231,11 +232,11 @@ var _ = SIGDescribe("Watchers", func() { framework.Failf("Expected last notfication to refer to a configmap but got: %v", lastEvent) } testWatchRestarted, err := watchConfigMaps(f, lastEventConfigMap.ObjectMeta.ResourceVersion, watchRestartedLabelValue) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create a new watch on configmaps from the last resource version %s observed by the first watch", lastEventConfigMap.ObjectMeta.ResourceVersion) By("deleting the configmap") err = c.CoreV1().ConfigMaps(ns).Delete(testConfigMap.GetName(), nil) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete configmap %s in namespace: %s", configMapName, ns) By("Expecting to observe notifications for all changes to the configmap since the first watch closed") expectEvent(testWatchRestarted, watch.Modified, testConfigMapSecondUpdate) @@ -252,9 +253,10 @@ var _ = SIGDescribe("Watchers", func() { c := f.ClientSet ns := f.Namespace.Name + configMapName := "e2e-watch-test-label-changed" testConfigMap := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: "e2e-watch-test-label-changed", + Name: configMapName, Labels: map[string]string{ watchConfigMapLabelKey: toBeChangedLabelValue, }, @@ -263,23 +265,23 @@ var _ = SIGDescribe("Watchers", func() { By("creating a watch on configmaps with a certain label") testWatch, err := watchConfigMaps(f, "", toBeChangedLabelValue) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create a watch on configmap with label: %s", toBeChangedLabelValue) By("creating a new configmap") testConfigMap, err = c.CoreV1().ConfigMaps(ns).Create(testConfigMap) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create configmap %s in namespace: %s", configMapName, ns) By("modifying the configmap once") testConfigMapFirstUpdate, err := updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "1") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace: %s", configMapName, ns) By("changing the label value of the configmap") _, err = updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { cm.ObjectMeta.Labels[watchConfigMapLabelKey] = "wrong-value" }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace %s by changing label value", configMapName, ns) By("Expecting to observe a delete notification for the watched object") expectEvent(testWatch, watch.Added, testConfigMap) @@ -290,7 +292,7 @@ var _ = SIGDescribe("Watchers", func() { testConfigMapSecondUpdate, err := updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "2") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace %s a second time", configMapName, ns) By("Expecting not to observe a notification because the object no longer meets the selector's requirements") expectNoEvent(testWatch, watch.Modified, testConfigMapSecondUpdate) @@ -299,17 +301,17 @@ var _ = SIGDescribe("Watchers", func() { testConfigMapLabelRestored, err := updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { cm.ObjectMeta.Labels[watchConfigMapLabelKey] = toBeChangedLabelValue }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace %s by changing label value back", configMapName, ns) By("modifying the configmap a third time") testConfigMapThirdUpdate, err := updateConfigMap(c, ns, testConfigMap.GetName(), func(cm *v1.ConfigMap) { setConfigMapData(cm, "mutation", "3") }) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to update configmap %s in namespace %s a third time", configMapName, ns) By("deleting the configmap") err = c.CoreV1().ConfigMaps(ns).Delete(testConfigMap.GetName(), nil) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to delete configmap %s in namespace: %s", configMapName, ns) By("Expecting to observe an add notification for the watched object when the label value was restored") expectEvent(testWatch, watch.Added, testConfigMapLabelRestored) diff --git a/test/e2e/apimachinery/webhook.go b/test/e2e/apimachinery/webhook.go index b71b174dfb8c4..72c5ea67c09a1 100644 --- a/test/e2e/apimachinery/webhook.go +++ b/test/e2e/apimachinery/webhook.go @@ -620,7 +620,7 @@ func testWebhook(f *framework.Framework) { // Creating the pod, the request should be rejected pod := nonCompliantPod(f) _, err := client.CoreV1().Pods(f.Namespace.Name).Create(pod) - Expect(err).NotTo(BeNil()) + Expect(err).To(HaveOccurred(), "create pod %s in namespace %s should have been denied by webhook", pod.Name, f.Namespace.Name) expectedErrMsg1 := "the pod contains unwanted container name" if !strings.Contains(err.Error(), expectedErrMsg1) { framework.Failf("expect error contains %q, got %q", expectedErrMsg1, err.Error()) @@ -635,7 +635,7 @@ func testWebhook(f *framework.Framework) { // Creating the pod, the request should be rejected pod = hangingPod(f) _, err = client.CoreV1().Pods(f.Namespace.Name).Create(pod) - Expect(err).NotTo(BeNil()) + Expect(err).To(HaveOccurred(), "create pod %s in namespace %s should have caused webhook to hang", pod.Name, f.Namespace.Name) expectedTimeoutErr := "request did not complete within" if !strings.Contains(err.Error(), expectedTimeoutErr) { framework.Failf("expect timeout error %q, got %q", expectedTimeoutErr, err.Error()) @@ -645,7 +645,7 @@ func testWebhook(f *framework.Framework) { // Creating the configmap, the request should be rejected configmap := nonCompliantConfigMap(f) _, err = client.CoreV1().ConfigMaps(f.Namespace.Name).Create(configmap) - Expect(err).NotTo(BeNil()) + Expect(err).To(HaveOccurred(), "create configmap %s in namespace %s should have been denied by the webhook", configmap.Name, f.Namespace.Name) expectedErrMsg := "the configmap contains unwanted key and value" if !strings.Contains(err.Error(), expectedErrMsg) { framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error()) @@ -662,7 +662,7 @@ func testWebhook(f *framework.Framework) { }, } _, err = client.CoreV1().ConfigMaps(f.Namespace.Name).Create(configmap) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "failed to create configmap %s in namespace: %s", configmap.Name, f.Namespace.Name) By("update (PUT) the admitted configmap to a non-compliant one should be rejected by the webhook") toNonCompliantFn := func(cm *v1.ConfigMap) { @@ -672,7 +672,7 @@ func testWebhook(f *framework.Framework) { cm.Data["webhook-e2e-test"] = "webhook-disallow" } _, err = updateConfigMap(client, f.Namespace.Name, allowedConfigMapName, toNonCompliantFn) - Expect(err).NotTo(BeNil()) + Expect(err).To(HaveOccurred(), "update (PUT) admitted configmap %s in namespace %s to a non-compliant one should be rejected by webhook", allowedConfigMapName, f.Namespace.Name) if !strings.Contains(err.Error(), expectedErrMsg) { framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error()) } @@ -680,7 +680,7 @@ func testWebhook(f *framework.Framework) { By("update (PATCH) the admitted configmap to a non-compliant one should be rejected by the webhook") patch := nonCompliantConfigMapPatch() _, err = client.CoreV1().ConfigMaps(f.Namespace.Name).Patch(allowedConfigMapName, types.StrategicMergePatchType, []byte(patch)) - Expect(err).NotTo(BeNil()) + Expect(err).To(HaveOccurred(), "update admitted configmap %s in namespace %s by strategic merge patch to a non-compliant one should be rejected by webhook. Patch: %+v", allowedConfigMapName, f.Namespace.Name, patch) if !strings.Contains(err.Error(), expectedErrMsg) { framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error()) } @@ -699,7 +699,7 @@ func testWebhook(f *framework.Framework) { By("create a configmap that violates the webhook policy but is in a whitelisted namespace") configmap = nonCompliantConfigMap(f) _, err = client.CoreV1().ConfigMaps(skippedNamespaceName).Create(configmap) - Expect(err).To(BeNil()) + Expect(err).NotTo(HaveOccurred(), "failed to create configmap %s in namespace: %s", configmap.Name, skippedNamespaceName) } func testAttachingPodWebhook(f *framework.Framework) { @@ -707,15 +707,15 @@ func testAttachingPodWebhook(f *framework.Framework) { client := f.ClientSet pod := toBeAttachedPod(f) _, err := client.CoreV1().Pods(f.Namespace.Name).Create(pod) - Expect(err).To(BeNil()) + Expect(err).NotTo(HaveOccurred(), "failed to create pod %s in namespace: %s", pod.Name, f.Namespace.Name) err = framework.WaitForPodNameRunningInNamespace(client, pod.Name, f.Namespace.Name) - Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred(), "error while waiting for pod %s to go to Running phase in namespace: %s", pod.Name, f.Namespace.Name) By("'kubectl attach' the pod, should be denied by the webhook") timer := time.NewTimer(30 * time.Second) defer timer.Stop() _, err = framework.NewKubectlCommand("attach", fmt.Sprintf("--namespace=%v", f.Namespace.Name), pod.Name, "-i", "-c=container1").WithTimeout(timer.C).Exec() - Expect(err).NotTo(BeNil()) + Expect(err).To(HaveOccurred(), "'kubectl attach' the pod, should be denied by the webhook") if e, a := "attaching to pod 'to-be-attached-pod' is not allowed", err.Error(); !strings.Contains(a, e) { framework.Failf("unexpected 'kubectl attach' error message. expected to contain %q, got %q", e, a) } @@ -804,7 +804,7 @@ func testFailClosedWebhook(f *framework.Framework) { }, } _, err = client.CoreV1().ConfigMaps(failNamespaceName).Create(configmap) - Expect(err).To(HaveOccurred()) + Expect(err).To(HaveOccurred(), "create configmap in namespace: %s should be unconditionally rejected by the webhook", failNamespaceName) if !errors.IsInternalError(err) { framework.Failf("expect an internal error, got %#v", err) } @@ -1242,12 +1242,13 @@ func registerMutatingWebhookForCustomResource(f *framework.Framework, context *c func testCustomResourceWebhook(f *framework.Framework, crd *apiextensionsv1beta1.CustomResourceDefinition, customResourceClient dynamic.ResourceInterface) { By("Creating a custom resource that should be denied by the webhook") + crInstanceName := "cr-instance-1" crInstance := &unstructured.Unstructured{ Object: map[string]interface{}{ "kind": crd.Spec.Names.Kind, "apiVersion": crd.Spec.Group + "/" + crd.Spec.Version, "metadata": map[string]interface{}{ - "name": "cr-instance-1", + "name": crInstanceName, "namespace": f.Namespace.Name, }, "data": map[string]interface{}{ @@ -1256,7 +1257,7 @@ func testCustomResourceWebhook(f *framework.Framework, crd *apiextensionsv1beta1 }, } _, err := customResourceClient.Create(crInstance, metav1.CreateOptions{}) - Expect(err).NotTo(BeNil()) + Expect(err).To(HaveOccurred(), "create custom resource %s in namespace %s should be denied by webhook", crInstanceName, f.Namespace.Name) expectedErrMsg := "the custom resource contains unwanted data" if !strings.Contains(err.Error(), expectedErrMsg) { framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error()) @@ -1265,12 +1266,13 @@ func testCustomResourceWebhook(f *framework.Framework, crd *apiextensionsv1beta1 func testMutatingCustomResourceWebhook(f *framework.Framework, crd *apiextensionsv1beta1.CustomResourceDefinition, customResourceClient dynamic.ResourceInterface) { By("Creating a custom resource that should be mutated by the webhook") + crName := "cr-instance-1" cr := &unstructured.Unstructured{ Object: map[string]interface{}{ "kind": crd.Spec.Names.Kind, "apiVersion": crd.Spec.Group + "/" + crd.Spec.Version, "metadata": map[string]interface{}{ - "name": "cr-instance-1", + "name": crName, "namespace": f.Namespace.Name, }, "data": map[string]interface{}{ @@ -1279,7 +1281,7 @@ func testMutatingCustomResourceWebhook(f *framework.Framework, crd *apiextension }, } mutatedCR, err := customResourceClient.Create(cr, metav1.CreateOptions{}) - Expect(err).To(BeNil()) + Expect(err).NotTo(HaveOccurred(), "failed to create custom resource %s in namespace: %s", crName, f.Namespace.Name) expectedCRData := map[string]interface{}{ "mutation-start": "yes", "mutation-stage-1": "yes", @@ -1382,7 +1384,7 @@ func testCRDDenyWebhook(f *framework.Framework) { // create CRD _, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd) - Expect(err).NotTo(BeNil()) + Expect(err).To(HaveOccurred(), "create custom resource definition %s should be denied by webhook", testcrd.GetMetaName()) expectedErrMsg := "the crd contains unwanted label" if !strings.Contains(err.Error(), expectedErrMsg) { framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error()) diff --git a/test/e2e/apps/cronjob.go b/test/e2e/apps/cronjob.go index 31c541711fea4..ec2b10a146f55 100644 --- a/test/e2e/apps/cronjob.go +++ b/test/e2e/apps/cronjob.go @@ -214,8 +214,8 @@ var _ = SIGDescribe("CronJob", func() { Expect(err).To(HaveOccurred()) Expect(errors.IsNotFound(err)).To(BeTrue()) - By("Ensuring there are no active jobs in the cronjob") - err = waitForNoJobs(f.ClientSet, f.Namespace.Name, cronJob.Name, true) + By("Ensuring the job is not in the cronjob active list") + err = waitForJobNotActive(f.ClientSet, f.Namespace.Name, cronJob.Name, job.Name) Expect(err).NotTo(HaveOccurred()) By("Ensuring MissingJob event has occurred") @@ -336,7 +336,7 @@ func deleteCronJob(c clientset.Interface, ns, name string) error { // Wait for at least given amount of active jobs. func waitForActiveJobs(c clientset.Interface, ns, cronJobName string, active int) error { return wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) { - curr, err := c.BatchV1beta1().CronJobs(ns).Get(cronJobName, metav1.GetOptions{}) + curr, err := getCronJob(c, ns, cronJobName) if err != nil { return false, err } @@ -350,7 +350,7 @@ func waitForActiveJobs(c clientset.Interface, ns, cronJobName string, active int // empty after the timeout. func waitForNoJobs(c clientset.Interface, ns, jobName string, failIfNonEmpty bool) error { return wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) { - curr, err := c.BatchV1beta1().CronJobs(ns).Get(jobName, metav1.GetOptions{}) + curr, err := getCronJob(c, ns, jobName) if err != nil { return false, err } @@ -363,6 +363,23 @@ func waitForNoJobs(c clientset.Interface, ns, jobName string, failIfNonEmpty boo }) } +// Wait till a given job actually goes away from the Active list for a given cronjob +func waitForJobNotActive(c clientset.Interface, ns, cronJobName, jobName string) error { + return wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) { + curr, err := getCronJob(c, ns, cronJobName) + if err != nil { + return false, err + } + + for _, j := range curr.Status.Active { + if j.Name == jobName { + return false, nil + } + } + return true, nil + }) +} + // Wait for a job to not exist by listing jobs explicitly. func waitForJobNotExist(c clientset.Interface, ns string, targetJob *batchv1.Job) error { return wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) { @@ -429,7 +446,7 @@ func waitForAnyFinishedJob(c clientset.Interface, ns string) error { // waitForEventWithReason waits for events with a reason within a list has occurred func waitForEventWithReason(c clientset.Interface, ns, cronJobName string, reasons []string) error { return wait.Poll(framework.Poll, 30*time.Second, func() (bool, error) { - sj, err := c.BatchV1beta1().CronJobs(ns).Get(cronJobName, metav1.GetOptions{}) + sj, err := getCronJob(c, ns, cronJobName) if err != nil { return false, err } diff --git a/test/e2e/apps/network_partition.go b/test/e2e/apps/network_partition.go index 8fbebc96802d2..7d20149d3ec98 100644 --- a/test/e2e/apps/network_partition.go +++ b/test/e2e/apps/network_partition.go @@ -198,10 +198,12 @@ var _ = SIGDescribe("Network Partition [Disruptive] [Slow]", func() { By(fmt.Sprintf("Block traffic from node %s to the master", node.Name)) host, err := framework.GetNodeExternalIP(&node) framework.ExpectNoError(err) - master := framework.GetMasterAddress(c) + masterAddresses := framework.GetAllMasterAddresses(c) defer func() { By(fmt.Sprintf("Unblock traffic from node %s to the master", node.Name)) - framework.UnblockNetwork(host, master) + for _, masterAddress := range masterAddresses { + framework.UnblockNetwork(host, masterAddress) + } if CurrentGinkgoTestDescription().Failed { return @@ -214,7 +216,9 @@ var _ = SIGDescribe("Network Partition [Disruptive] [Slow]", func() { } }() - framework.BlockNetwork(host, master) + for _, masterAddress := range masterAddresses { + framework.BlockNetwork(host, masterAddress) + } By("Expect to observe node and pod status change from Ready to NotReady after network partition") expectNodeReadiness(false, newNode) @@ -576,10 +580,12 @@ var _ = SIGDescribe("Network Partition [Disruptive] [Slow]", func() { By(fmt.Sprintf("Block traffic from node %s to the master", node.Name)) host, err := framework.GetNodeExternalIP(&node) framework.ExpectNoError(err) - master := framework.GetMasterAddress(c) + masterAddresses := framework.GetAllMasterAddresses(c) defer func() { By(fmt.Sprintf("Unblock traffic from node %s to the master", node.Name)) - framework.UnblockNetwork(host, master) + for _, masterAddress := range masterAddresses { + framework.UnblockNetwork(host, masterAddress) + } if CurrentGinkgoTestDescription().Failed { return @@ -589,7 +595,9 @@ var _ = SIGDescribe("Network Partition [Disruptive] [Slow]", func() { expectNodeReadiness(true, newNode) }() - framework.BlockNetwork(host, master) + for _, masterAddress := range masterAddresses { + framework.BlockNetwork(host, masterAddress) + } By("Expect to observe node and pod status change from Ready to NotReady after network partition") expectNodeReadiness(false, newNode) diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index 406b380d9568b..8c127291f64d6 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -60,11 +60,21 @@ var _ = SIGDescribe("ReplicationController", func() { testReplicationControllerConditionCheck(f) }) - It("should adopt matching pods on creation", func() { + /* + 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 + */ + framework.ConformanceIt("should adopt matching pods on creation", func() { testRCAdoptMatchingOrphans(f) }) - It("should release no longer matching pods", func() { + /* + 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. + */ + framework.ConformanceIt("should release no longer matching pods", func() { testRCReleaseControlledNotMatching(f) }) }) diff --git a/test/e2e/apps/replica_set.go b/test/e2e/apps/replica_set.go index 354d2e94b7443..b41ea59513253 100644 --- a/test/e2e/apps/replica_set.go +++ b/test/e2e/apps/replica_set.go @@ -103,7 +103,12 @@ var _ = SIGDescribe("ReplicaSet", func() { testReplicaSetConditionCheck(f) }) - It("should adopt matching pods on creation and release no longer matching pods", func() { + /* + 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 + */ + framework.ConformanceIt("should adopt matching pods on creation and release no longer matching pods", func() { testRSAdoptMatchingAndReleaseNotMatching(f) }) }) diff --git a/test/e2e/apps/statefulset.go b/test/e2e/apps/statefulset.go index 626f465246277..a3428985611fa 100644 --- a/test/e2e/apps/statefulset.go +++ b/test/e2e/apps/statefulset.go @@ -983,7 +983,7 @@ func (m *mysqlGaleraTester) deploy(ns string) *apps.StatefulSet { func (m *mysqlGaleraTester) write(statefulPodIndex int, kv map[string]string) { name := fmt.Sprintf("%v-%d", m.ss.Name, statefulPodIndex) for k, v := range kv { - cmd := fmt.Sprintf("use statefulset; insert into foo (k, v) values (\"%v\", \"%v\");", k, v) + cmd := fmt.Sprintf("use statefulset; insert into foo (k, v) values (\"%v\", \"%v\");", k, v) framework.Logf(m.mysqlExec(cmd, m.ss.Namespace, name)) } } diff --git a/test/e2e/auth/BUILD b/test/e2e/auth/BUILD index f2345b047d350..c7f31b02098be 100644 --- a/test/e2e/auth/BUILD +++ b/test/e2e/auth/BUILD @@ -28,7 +28,6 @@ go_library( "//staging/src/k8s.io/api/batch/v1:go_default_library", "//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", - "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/api/policy/v1beta1:go_default_library", "//staging/src/k8s.io/api/rbac/v1beta1:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", diff --git a/test/e2e/auth/pod_security_policy.go b/test/e2e/auth/pod_security_policy.go index 971b85e0ab186..326fc33852709 100644 --- a/test/e2e/auth/pod_security_policy.go +++ b/test/e2e/auth/pod_security_policy.go @@ -20,7 +20,6 @@ import ( "fmt" "k8s.io/api/core/v1" - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" policy "k8s.io/api/policy/v1beta1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" apierrs "k8s.io/apimachinery/pkg/api/errors" @@ -79,27 +78,9 @@ var _ = SIGDescribe("PodSecurityPolicy", func() { expectForbidden(err) }) - // TODO: merge tests for extensions/policy API groups when PSP will be completely moved out of the extensions - - It("should enforce the restricted extensions.PodSecurityPolicy", func() { - By("Creating & Binding a restricted policy for the test service account") - _, cleanup := createAndBindPSP(f, restrictedPSP("restrictive")) - defer cleanup() - - By("Running a restricted pod") - pod, err := c.CoreV1().Pods(ns).Create(restrictedPod("allowed")) - framework.ExpectNoError(err) - framework.ExpectNoError(framework.WaitForPodNameRunningInNamespace(c, pod.Name, pod.Namespace)) - - testPrivilegedPods(func(pod *v1.Pod) { - _, err := c.CoreV1().Pods(ns).Create(pod) - expectForbidden(err) - }) - }) - It("should enforce the restricted policy.PodSecurityPolicy", func() { By("Creating & Binding a restricted policy for the test service account") - _, cleanup := createAndBindPSPInPolicy(f, restrictedPSPInPolicy("restrictive")) + _, cleanup := createAndBindPSP(f, restrictedPSP("restrictive")) defer cleanup() By("Running a restricted pod") @@ -113,34 +94,12 @@ var _ = SIGDescribe("PodSecurityPolicy", func() { }) }) - It("should allow pods under the privileged extensions.PodSecurityPolicy", func() { - By("Creating & Binding a privileged policy for the test service account") - // Ensure that the permissive policy is used even in the presence of the restricted policy. - _, cleanup := createAndBindPSP(f, restrictedPSP("restrictive")) - defer cleanup() - expectedPSP, cleanup := createAndBindPSP(f, framework.PrivilegedPSP("permissive")) - defer cleanup() - - testPrivilegedPods(func(pod *v1.Pod) { - p, err := c.CoreV1().Pods(ns).Create(pod) - framework.ExpectNoError(err) - framework.ExpectNoError(framework.WaitForPodNameRunningInNamespace(c, p.Name, p.Namespace)) - - // Verify expected PSP was used. - p, err = c.CoreV1().Pods(ns).Get(p.Name, metav1.GetOptions{}) - framework.ExpectNoError(err) - validated, found := p.Annotations[psputil.ValidatedPSPAnnotation] - Expect(found).To(BeTrue(), "PSP annotation not found") - Expect(validated).To(Equal(expectedPSP.Name), "Unexpected validated PSP") - }) - }) - It("should allow pods under the privileged policy.PodSecurityPolicy", func() { By("Creating & Binding a privileged policy for the test service account") // Ensure that the permissive policy is used even in the presence of the restricted policy. - _, cleanup := createAndBindPSPInPolicy(f, restrictedPSPInPolicy("restrictive")) + _, cleanup := createAndBindPSP(f, restrictedPSP("restrictive")) defer cleanup() - expectedPSP, cleanup := createAndBindPSPInPolicy(f, privilegedPSPInPolicy("permissive")) + expectedPSP, cleanup := createAndBindPSP(f, privilegedPSP("permissive")) defer cleanup() testPrivilegedPods(func(pod *v1.Pod) { @@ -229,49 +188,8 @@ func testPrivilegedPods(tester func(pod *v1.Pod)) { }) } -func createAndBindPSP(f *framework.Framework, pspTemplate *extensionsv1beta1.PodSecurityPolicy) (psp *extensionsv1beta1.PodSecurityPolicy, cleanup func()) { - // Create the PodSecurityPolicy object. - psp = pspTemplate.DeepCopy() - // Add the namespace to the name to ensure uniqueness and tie it to the namespace. - ns := f.Namespace.Name - name := fmt.Sprintf("%s-%s", ns, psp.Name) - psp.Name = name - psp, err := f.ClientSet.ExtensionsV1beta1().PodSecurityPolicies().Create(psp) - framework.ExpectNoError(err, "Failed to create PSP") - - // Create the Role to bind it to the namespace. - _, err = f.ClientSet.RbacV1beta1().Roles(ns).Create(&rbacv1beta1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Rules: []rbacv1beta1.PolicyRule{{ - APIGroups: []string{"extensions"}, - Resources: []string{"podsecuritypolicies"}, - ResourceNames: []string{name}, - Verbs: []string{"use"}, - }}, - }) - framework.ExpectNoError(err, "Failed to create PSP role") - - // Bind the role to the namespace. - framework.BindRoleInNamespace(f.ClientSet.RbacV1beta1(), name, ns, rbacv1beta1.Subject{ - Kind: rbacv1beta1.ServiceAccountKind, - Namespace: ns, - Name: "default", - }) - framework.ExpectNoError(framework.WaitForNamedAuthorizationUpdate(f.ClientSet.AuthorizationV1beta1(), - serviceaccount.MakeUsername(ns, "default"), ns, "use", name, - schema.GroupResource{Group: "extensions", Resource: "podsecuritypolicies"}, true)) - - return psp, func() { - // Cleanup non-namespaced PSP object. - f.ClientSet.ExtensionsV1beta1().PodSecurityPolicies().Delete(name, &metav1.DeleteOptions{}) - } -} - -// createAndBindPSPInPolicy creates a PSP in the policy API group (unlike createAndBindPSP()). -// TODO: merge these functions when PSP will be completely moved out of the extensions -func createAndBindPSPInPolicy(f *framework.Framework, pspTemplate *policy.PodSecurityPolicy) (psp *policy.PodSecurityPolicy, cleanup func()) { +// createAndBindPSP creates a PSP in the policy API group. +func createAndBindPSP(f *framework.Framework, pspTemplate *policy.PodSecurityPolicy) (psp *policy.PodSecurityPolicy, cleanup func()) { // Create the PodSecurityPolicy object. psp = pspTemplate.DeepCopy() // Add the namespace to the name to ensure uniqueness and tie it to the namespace. @@ -334,8 +252,7 @@ func restrictedPod(name string) *v1.Pod { } // privilegedPSPInPolicy creates a PodSecurityPolicy (in the "policy" API Group) that allows everything. -// TODO: replace by PrivilegedPSP when PSP will be completely moved out of the extensions -func privilegedPSPInPolicy(name string) *policy.PodSecurityPolicy { +func privilegedPSP(name string) *policy.PodSecurityPolicy { return &policy.PodSecurityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -368,8 +285,7 @@ func privilegedPSPInPolicy(name string) *policy.PodSecurityPolicy { } // restrictedPSPInPolicy creates a PodSecurityPolicy (in the "policy" API Group) that is most strict. -// TODO: replace by restrictedPSP when PSP will be completely moved out of the extensions -func restrictedPSPInPolicy(name string) *policy.PodSecurityPolicy { +func restrictedPSP(name string) *policy.PodSecurityPolicy { return &policy.PodSecurityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -423,61 +339,6 @@ func restrictedPSPInPolicy(name string) *policy.PodSecurityPolicy { } } -// restrictedPSP creates a PodSecurityPolicy that is most strict. -func restrictedPSP(name string) *extensionsv1beta1.PodSecurityPolicy { - return &extensionsv1beta1.PodSecurityPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Annotations: map[string]string{ - seccomp.AllowedProfilesAnnotationKey: v1.SeccompProfileRuntimeDefault, - seccomp.DefaultProfileAnnotationKey: v1.SeccompProfileRuntimeDefault, - apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault, - apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, - }, - }, - Spec: extensionsv1beta1.PodSecurityPolicySpec{ - Privileged: false, - AllowPrivilegeEscalation: utilpointer.BoolPtr(false), - RequiredDropCapabilities: []v1.Capability{ - "AUDIT_WRITE", - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "FSETID", - "KILL", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SYS_CHROOT", - }, - Volumes: []extensionsv1beta1.FSType{ - extensionsv1beta1.ConfigMap, - extensionsv1beta1.EmptyDir, - extensionsv1beta1.PersistentVolumeClaim, - "projected", - extensionsv1beta1.Secret, - }, - HostNetwork: false, - HostIPC: false, - HostPID: false, - RunAsUser: extensionsv1beta1.RunAsUserStrategyOptions{ - Rule: extensionsv1beta1.RunAsUserStrategyMustRunAsNonRoot, - }, - SELinux: extensionsv1beta1.SELinuxStrategyOptions{ - Rule: extensionsv1beta1.SELinuxStrategyRunAsAny, - }, - SupplementalGroups: extensionsv1beta1.SupplementalGroupsStrategyOptions{ - Rule: extensionsv1beta1.SupplementalGroupsStrategyRunAsAny, - }, - FSGroup: extensionsv1beta1.FSGroupStrategyOptions{ - Rule: extensionsv1beta1.FSGroupStrategyRunAsAny, - }, - ReadOnlyRootFilesystem: false, - }, - } -} - func boolPtr(b bool) *bool { return &b } diff --git a/test/e2e/autoscaling/custom_metrics_stackdriver_autoscaling.go b/test/e2e/autoscaling/custom_metrics_stackdriver_autoscaling.go index 5277cb9c5df0f..325c3bce4396b 100644 --- a/test/e2e/autoscaling/custom_metrics_stackdriver_autoscaling.go +++ b/test/e2e/autoscaling/custom_metrics_stackdriver_autoscaling.go @@ -86,7 +86,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me initialReplicas := 2 // metric should cause scale down metricValue := externalMetricValue - metricTarget := 2 * metricValue + metricTarget := 3 * metricValue metricTargets := map[string]externalMetricTarget{ "target": { value: metricTarget, @@ -109,7 +109,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me initialReplicas := 2 // metric should cause scale down metricValue := externalMetricValue - metricAverageTarget := 2 * metricValue + metricAverageTarget := 3 * metricValue metricTargets := map[string]externalMetricTarget{ "target_average": { value: metricAverageTarget, diff --git a/test/e2e/autoscaling/horizontal_pod_autoscaling.go b/test/e2e/autoscaling/horizontal_pod_autoscaling.go index 37efa45742812..bdba3f7392380 100644 --- a/test/e2e/autoscaling/horizontal_pod_autoscaling.go +++ b/test/e2e/autoscaling/horizontal_pod_autoscaling.go @@ -102,7 +102,7 @@ type HPAScaleTest struct { targetCPUUtilizationPercent int32 minPods int32 maxPods int32 - firstScale int32 + firstScale int firstScaleStasis time.Duration cpuBurst int secondScale int32 @@ -120,9 +120,10 @@ func (scaleTest *HPAScaleTest) run(name string, kind schema.GroupVersionKind, rc defer rc.CleanUp() hpa := common.CreateCPUHorizontalPodAutoscaler(rc, scaleTest.targetCPUUtilizationPercent, scaleTest.minPods, scaleTest.maxPods) defer common.DeleteHorizontalPodAutoscaler(rc, hpa.Name) - rc.WaitForReplicas(int(scaleTest.firstScale), timeToWait) + + rc.WaitForReplicas(scaleTest.firstScale, timeToWait) if scaleTest.firstScaleStasis > 0 { - rc.EnsureDesiredReplicas(int(scaleTest.firstScale), scaleTest.firstScaleStasis) + rc.EnsureDesiredReplicasInRange(scaleTest.firstScale, scaleTest.firstScale+1, scaleTest.firstScaleStasis, hpa.Name) } if scaleTest.cpuBurst > 0 && scaleTest.secondScale > 0 { rc.ConsumeCPU(scaleTest.cpuBurst) @@ -137,14 +138,14 @@ func scaleUp(name string, kind schema.GroupVersionKind, checkStability bool, rc } scaleTest := &HPAScaleTest{ initPods: 1, - totalInitialCPUUsage: 500, - perPodCPURequest: 1000, + totalInitialCPUUsage: 250, + perPodCPURequest: 500, targetCPUUtilizationPercent: 20, minPods: 1, maxPods: 5, firstScale: 3, firstScaleStasis: stasis, - cpuBurst: 1400, + cpuBurst: 700, secondScale: 5, } scaleTest.run(name, kind, rc, f) @@ -157,8 +158,8 @@ func scaleDown(name string, kind schema.GroupVersionKind, checkStability bool, r } scaleTest := &HPAScaleTest{ initPods: 5, - totalInitialCPUUsage: 650, - perPodCPURequest: 1000, + totalInitialCPUUsage: 325, + perPodCPURequest: 500, targetCPUUtilizationPercent: 30, minPods: 1, maxPods: 5, diff --git a/test/e2e/common/autoscaling_utils.go b/test/e2e/common/autoscaling_utils.go index 0e0d202b8d4ea..fe8b5ab97fcb6 100644 --- a/test/e2e/common/autoscaling_utils.go +++ b/test/e2e/common/autoscaling_utils.go @@ -359,6 +359,10 @@ func (rc *ResourceConsumer) GetReplicas() int { return 0 } +func (rc *ResourceConsumer) GetHpa(name string) (*autoscalingv1.HorizontalPodAutoscaler, error) { + return rc.clientSet.AutoscalingV1().HorizontalPodAutoscalers(rc.nsName).Get(name, metav1.GetOptions{}) +} + func (rc *ResourceConsumer) WaitForReplicas(desiredReplicas int, duration time.Duration) { interval := 20 * time.Second err := wait.PollImmediate(interval, duration, func() (bool, error) { @@ -369,13 +373,25 @@ func (rc *ResourceConsumer) WaitForReplicas(desiredReplicas int, duration time.D framework.ExpectNoErrorWithOffset(1, err, "timeout waiting %v for %d replicas", duration, desiredReplicas) } -func (rc *ResourceConsumer) EnsureDesiredReplicas(desiredReplicas int, duration time.Duration) { +func (rc *ResourceConsumer) EnsureDesiredReplicas(desiredReplicas int, duration time.Duration, hpaName string) { + rc.EnsureDesiredReplicasInRange(desiredReplicas, desiredReplicas, duration, hpaName) +} + +func (rc *ResourceConsumer) EnsureDesiredReplicasInRange(minDesiredReplicas, maxDesiredReplicas int, duration time.Duration, hpaName string) { interval := 10 * time.Second err := wait.PollImmediate(interval, duration, func() (bool, error) { replicas := rc.GetReplicas() - framework.Logf("expecting there to be %d replicas (are: %d)", desiredReplicas, replicas) - if replicas != desiredReplicas { - return false, fmt.Errorf("number of replicas changed unexpectedly") + framework.Logf("expecting there to be in [%d, %d] replicas (are: %d)", minDesiredReplicas, maxDesiredReplicas, replicas) + as, err := rc.GetHpa(hpaName) + if err != nil { + framework.Logf("Error getting HPA: %s", err) + } else { + framework.Logf("HPA status: %+v", as.Status) + } + if replicas < minDesiredReplicas { + return false, fmt.Errorf("number of replicas below target") + } else if replicas > maxDesiredReplicas { + return false, fmt.Errorf("number of replicas above target") } else { return false, nil // Expected number of replicas found. Continue polling until timeout. } diff --git a/test/e2e/common/configmap.go b/test/e2e/common/configmap.go index 829245fd85619..5eda31a484043 100644 --- a/test/e2e/common/configmap.go +++ b/test/e2e/common/configmap.go @@ -27,7 +27,7 @@ import ( imageutils "k8s.io/kubernetes/test/utils/image" ) -var _ = Describe("[sig-api-machinery] ConfigMap", func() { +var _ = Describe("[sig-node] ConfigMap", func() { f := framework.NewDefaultFramework("configmap") /* diff --git a/test/e2e/common/downward_api.go b/test/e2e/common/downward_api.go index 3776dd0bbc7da..00a2876a83734 100644 --- a/test/e2e/common/downward_api.go +++ b/test/e2e/common/downward_api.go @@ -35,7 +35,7 @@ var ( podUIDVersion = utilversion.MustParseSemantic("v1.8.0") ) -var _ = Describe("[sig-api-machinery] Downward API", func() { +var _ = Describe("[sig-node] Downward API", func() { f := framework.NewDefaultFramework("downward-api") /* diff --git a/test/e2e/common/downwardapi_volume.go b/test/e2e/common/downwardapi_volume.go index 9b8c52842adbb..bb12f42c139ca 100644 --- a/test/e2e/common/downwardapi_volume.go +++ b/test/e2e/common/downwardapi_volume.go @@ -33,7 +33,7 @@ import ( var _ = Describe("[sig-storage] Downward API volume", func() { // How long to wait for a log pod to be displayed - const podLogTimeout = 2 * time.Minute + const podLogTimeout = 3 * time.Minute f := framework.NewDefaultFramework("downward-api") var podClient *framework.PodClient BeforeEach(func() { diff --git a/test/e2e/common/host_path.go b/test/e2e/common/host_path.go index 942481a727941..2728b6e4c322a 100644 --- a/test/e2e/common/host_path.go +++ b/test/e2e/common/host_path.go @@ -116,101 +116,6 @@ var _ = Describe("[sig-storage] HostPath", func() { "content of file \"" + filePathInReader + "\": mount-tester new file", }) }) - - It("should support existing directory subPath", func() { - framework.SkipUnlessSSHKeyPresent() - - subPath := "sub-path" - fileName := "test-file" - retryDuration := 180 - - filePathInWriter := path.Join(volumePath, fileName) - filePathInReader := path.Join(volumePath, subPath, fileName) - - source := &v1.HostPathVolumeSource{ - Path: "/tmp", - } - pod := testPodWithHostVol(volumePath, source) - nodeList := framework.GetReadySchedulableNodesOrDie(f.ClientSet) - pod.Spec.NodeName = nodeList.Items[0].Name - - // Create the subPath directory on the host - existing := path.Join(source.Path, subPath) - nodeIP, err := framework.GetNodeExternalIP(&nodeList.Items[0]) - if err != nil { - nodeIP, err = framework.GetNodeInternalIP(&nodeList.Items[0]) - } - framework.ExpectNoError(err) - result, err := framework.SSH(fmt.Sprintf("mkdir -p %s", existing), nodeIP, framework.TestContext.Provider) - framework.LogSSHResult(result) - framework.ExpectNoError(err) - if result.Code != 0 { - framework.Failf("mkdir returned non-zero") - } - - // Write the file in the subPath from container 0 - container := &pod.Spec.Containers[0] - container.VolumeMounts[0].SubPath = subPath - container.Args = []string{ - fmt.Sprintf("--new_file_0644=%v", filePathInWriter), - fmt.Sprintf("--file_mode=%v", filePathInWriter), - } - - // Read it from outside the subPath from container 1 - pod.Spec.Containers[1].Args = []string{ - fmt.Sprintf("--file_content_in_loop=%v", filePathInReader), - fmt.Sprintf("--retry_time=%d", retryDuration), - } - - f.TestContainerOutput("hostPath subPath", pod, 1, []string{ - "content of file \"" + filePathInReader + "\": mount-tester new file", - }) - }) - - // TODO consolidate common code of this test and above - It("should support existing single file subPath", func() { - framework.SkipUnlessSSHKeyPresent() - - subPath := "sub-path-test-file" - retryDuration := 180 - - filePathInReader := path.Join(volumePath, subPath) - - source := &v1.HostPathVolumeSource{ - Path: "/tmp", - } - pod := testPodWithHostVol(volumePath, source) - nodeList := framework.GetReadySchedulableNodesOrDie(f.ClientSet) - pod.Spec.NodeName = nodeList.Items[0].Name - - // Create the subPath file on the host - existing := path.Join(source.Path, subPath) - nodeIP, err := framework.GetNodeExternalIP(&nodeList.Items[0]) - if err != nil { - nodeIP, err = framework.GetNodeInternalIP(&nodeList.Items[0]) - } - framework.ExpectNoError(err) - result, err := framework.SSH(fmt.Sprintf("echo \"mount-tester new file\" > %s", existing), nodeIP, framework.TestContext.Provider) - framework.LogSSHResult(result) - framework.ExpectNoError(err) - if result.Code != 0 { - framework.Failf("echo returned non-zero") - } - - // Mount the file to the subPath in container 0 - container := &pod.Spec.Containers[0] - container.VolumeMounts[0].SubPath = subPath - - // Read it from outside the subPath from container 1 - pod.Spec.Containers[1].Args = []string{ - fmt.Sprintf("--file_content_in_loop=%v", filePathInReader), - fmt.Sprintf("--retry_time=%d", retryDuration), - } - - f.TestContainerOutput("hostPath subPath", pod, 1, []string{ - "content of file \"" + filePathInReader + "\": mount-tester new file", - }) - }) }) //These constants are borrowed from the other test. diff --git a/test/e2e/framework/BUILD b/test/e2e/framework/BUILD index 11b184cb7f413..002477db7d648 100644 --- a/test/e2e/framework/BUILD +++ b/test/e2e/framework/BUILD @@ -8,6 +8,7 @@ go_library( "authorizer_util.go", "cleanup.go", "crd_util.go", + "create.go", "deployment_util.go", "exec_util.go", "flake_reporting_util.go", @@ -78,7 +79,9 @@ go_library( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1: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/api/rbac/v1beta1:go_default_library", + "//staging/src/k8s.io/api/storage/v1:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1: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", @@ -116,6 +119,7 @@ go_library( "//staging/src/k8s.io/client-go/rest:go_default_library", "//staging/src/k8s.io/client-go/restmapper:go_default_library", "//staging/src/k8s.io/client-go/scale:go_default_library", + "//staging/src/k8s.io/client-go/tools/cache:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", "//staging/src/k8s.io/client-go/tools/remotecommand:go_default_library", @@ -125,6 +129,7 @@ go_library( "//staging/src/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset:go_default_library", "//test/e2e/framework/ginkgowrapper:go_default_library", "//test/e2e/framework/metrics:go_default_library", + "//test/e2e/framework/testfiles:go_default_library", "//test/e2e/manifest:go_default_library", "//test/e2e/perftype:go_default_library", "//test/utils:go_default_library", @@ -134,6 +139,7 @@ go_library( "//vendor/github.com/onsi/ginkgo/config:go_default_library", "//vendor/github.com/onsi/gomega:go_default_library", "//vendor/github.com/onsi/gomega/types:go_default_library", + "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/prometheus/common/expfmt:go_default_library", "//vendor/github.com/prometheus/common/model:go_default_library", "//vendor/golang.org/x/crypto/ssh:go_default_library", @@ -157,6 +163,7 @@ filegroup( "//test/e2e/framework/ginkgowrapper:all-srcs", "//test/e2e/framework/ingress:all-srcs", "//test/e2e/framework/metrics:all-srcs", + "//test/e2e/framework/podlogs:all-srcs", "//test/e2e/framework/providers/aws:all-srcs", "//test/e2e/framework/providers/azure:all-srcs", "//test/e2e/framework/providers/gce:all-srcs", diff --git a/test/e2e/framework/create.go b/test/e2e/framework/create.go new file mode 100644 index 0000000000000..b4d38beda6866 --- /dev/null +++ b/test/e2e/framework/create.go @@ -0,0 +1,603 @@ +/* +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 framework + +import ( + "bytes" + "encoding/json" + "fmt" + + "github.com/pkg/errors" + + apps "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" + rbac "k8s.io/api/rbac/v1" + storage "k8s.io/api/storage/v1" + apierrs "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + clientset "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" + "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/test/e2e/framework/testfiles" +) + +// LoadFromManifests loads .yaml or .json manifest files and returns +// all items that it finds in them. It supports all items for which +// there is a factory registered in Factories and .yaml files with +// multiple items separated by "---". Files are accessed via the +// "testfiles" package, which means they can come from a file system +// or be built into the binary. +// +// LoadFromManifests has some limitations: +// - aliases are not supported (i.e. use serviceAccountName instead of the deprecated serviceAccount, +// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#podspec-v1-core) +// and silently ignored +// - the latest stable API version for each item is used, regardless of what +// is specified in the manifest files +func (f *Framework) LoadFromManifests(files ...string) ([]interface{}, error) { + var items []interface{} + err := visitManifests(func(data []byte) error { + // Ignore any additional fields for now, just determine what we have. + var what What + if err := runtime.DecodeInto(legacyscheme.Codecs.UniversalDecoder(), data, &what); err != nil { + return errors.Wrap(err, "decode TypeMeta") + } + + factory := Factories[what] + if factory == nil { + return errors.Errorf("item of type %+v not supported", what) + } + + object := factory.New() + if err := runtime.DecodeInto(legacyscheme.Codecs.UniversalDecoder(), data, object); err != nil { + return errors.Wrapf(err, "decode %+v", what) + } + items = append(items, object) + return nil + }, files...) + + return items, err +} + +func visitManifests(cb func([]byte) error, files ...string) error { + for _, fileName := range files { + data, err := testfiles.Read(fileName) + if err != nil { + Failf("reading manifest file: %v", err) + } + + // Split at the "---" separator before working on + // individual item. Only works for .yaml. + // + // We need to split ourselves because we need access + // to each original chunk of data for + // runtime.DecodeInto. kubectl has its own + // infrastructure for this, but that is a lot of code + // with many dependencies. + items := bytes.Split(data, []byte("\n---")) + + for _, item := range items { + if err := cb(item); err != nil { + return errors.Wrap(err, fileName) + } + } + } + return nil +} + +// PatchItems modifies the given items in place such that each test +// gets its own instances, to avoid conflicts between different tests +// and between tests and normal deployments. +// +// This is done by: +// - creating namespaced items inside the test's namespace +// - changing the name of non-namespaced items like ClusterRole +// +// PatchItems has some limitations: +// - only some common items are supported, unknown ones trigger an error +// - only the latest stable API version for each item is supported +func (f *Framework) PatchItems(items ...interface{}) error { + for _, item := range items { + // Uncomment when debugging the loading and patching of items. + // Logf("patching original content of %T:\n%s", item, PrettyPrint(item)) + if err := f.patchItemRecursively(item); err != nil { + return err + } + } + return nil +} + +// CreateItems creates the items. Each of them must be an API object +// of a type that is registered in Factory. +// +// It returns either a cleanup function or an error, but never both. +// +// Cleaning up after a test can be triggered in two ways: +// - the test invokes the returned cleanup function, +// usually in an AfterEach +// - the test suite terminates, potentially after +// skipping the test's AfterEach (https://github.com/onsi/ginkgo/issues/222) +// +// PatchItems has the some limitations as LoadFromManifests: +// - only some common items are supported, unknown ones trigger an error +// - only the latest stable API version for each item is supported +func (f *Framework) CreateItems(items ...interface{}) (func(), error) { + var destructors []func() error + var cleanupHandle CleanupActionHandle + cleanup := func() { + if cleanupHandle == nil { + // Already done. + return + } + RemoveCleanupAction(cleanupHandle) + + // TODO (?): use same logic as framework.go for determining + // whether we are expected to clean up? This would change the + // meaning of the -delete-namespace and -delete-namespace-on-failure + // command line flags, because they would also start to apply + // to non-namespaced items. + for _, destructor := range destructors { + if err := destructor(); err != nil && !apierrs.IsNotFound(err) { + Logf("deleting failed: %s", err) + } + } + } + cleanupHandle = AddCleanupAction(cleanup) + + var result error + for _, item := range items { + // Each factory knows which item(s) it supports, so try each one. + done := false + description := DescribeItem(item) + // Uncomment this line to get a full dump of the entire item. + // description = fmt.Sprintf("%s:\n%s", description, PrettyPrint(item)) + Logf("creating %s", description) + for _, factory := range Factories { + destructor, err := factory.Create(f, item) + if destructor != nil { + destructors = append(destructors, func() error { + Logf("deleting %s", description) + return destructor() + }) + } + if err == nil { + done = true + break + } else if errors.Cause(err) != ItemNotSupported { + result = err + break + } + } + if result == nil && !done { + result = errors.Errorf("item of type %T not supported", item) + break + } + } + + if result != nil { + cleanup() + return nil, result + } + + return cleanup, nil +} + +// CreateFromManifests is a combination of LoadFromManifests, +// PatchItems, patching with an optional custom function, +// and CreateItems. +func (f *Framework) CreateFromManifests(patch func(item interface{}) error, files ...string) (func(), error) { + items, err := f.LoadFromManifests(files...) + if err != nil { + return nil, errors.Wrap(err, "CreateFromManifests") + } + if err := f.PatchItems(items...); err != nil { + return nil, err + } + if patch != nil { + for _, item := range items { + if err := patch(item); err != nil { + return nil, err + } + } + } + return f.CreateItems(items...) +} + +// What is a subset of metav1.TypeMeta which (in contrast to +// metav1.TypeMeta itself) satisfies the runtime.Object interface. +type What struct { + Kind string `json:"kind"` +} + +func (in *What) DeepCopy() *What { + return &What{Kind: in.Kind} +} + +func (in *What) DeepCopyInto(out *What) { + out.Kind = in.Kind +} + +func (in *What) DeepCopyObject() runtime.Object { + return &What{Kind: in.Kind} +} + +func (in *What) GetObjectKind() schema.ObjectKind { + return nil +} + +// ItemFactory provides support for creating one particular item. +// The type gets exported because other packages might want to +// extend the set of pre-defined factories. +type ItemFactory interface { + // New returns a new empty item. + New() runtime.Object + + // Create is responsible for creating the item. It returns an + // error or a cleanup function for the created item. + // If the item is of an unsupported type, it must return + // an error that has ItemNotSupported as cause. + Create(f *Framework, item interface{}) (func() error, error) +} + +// DescribeItem always returns a string that describes the item, +// usually by calling out to cache.MetaNamespaceKeyFunc which +// concatenates namespace (if set) and name. If that fails, the entire +// item gets converted to a string. +func DescribeItem(item interface{}) string { + key, err := cache.MetaNamespaceKeyFunc(item) + if err == nil && key != "" { + return fmt.Sprintf("%T: %s", item, key) + } + return fmt.Sprintf("%T: %s", item, item) +} + +// ItemNotSupported is the error that Create methods +// must return or wrap when they don't support the given item. +var ItemNotSupported = errors.New("not supported") + +var Factories = map[What]ItemFactory{ + {"ClusterRole"}: &clusterRoleFactory{}, + {"ClusterRoleBinding"}: &clusterRoleBindingFactory{}, + {"DaemonSet"}: &daemonSetFactory{}, + {"Role"}: &roleFactory{}, + {"RoleBinding"}: &roleBindingFactory{}, + {"Secret"}: &secretFactory{}, + {"Service"}: &serviceFactory{}, + {"ServiceAccount"}: &serviceAccountFactory{}, + {"StatefulSet"}: &statefulSetFactory{}, + {"StorageClass"}: &storageClassFactory{}, +} + +// PatchName makes the name of some item unique by appending the +// generated unique name. +func (f *Framework) PatchName(item *string) { + if *item != "" { + *item = *item + "-" + f.UniqueName + } +} + +// PatchNamespace moves the item into the test's namespace. Not +// all items can be namespaced. For those, the name also needs to be +// patched. +func (f *Framework) PatchNamespace(item *string) { + if f.Namespace != nil { + *item = f.Namespace.GetName() + } +} + +func (f *Framework) patchItemRecursively(item interface{}) error { + switch item := item.(type) { + case *rbac.Subject: + f.PatchNamespace(&item.Namespace) + case *rbac.RoleRef: + // TODO: avoid hard-coding this special name. Perhaps add a Framework.PredefinedRoles + // which contains all role names that are defined cluster-wide before the test starts? + // All those names are excempt from renaming. That list could be populated by querying + // and get extended by tests. + if item.Name != "e2e-test-privileged-psp" { + f.PatchName(&item.Name) + } + case *rbac.ClusterRole: + f.PatchName(&item.Name) + case *rbac.Role: + f.PatchNamespace(&item.Namespace) + // Roles are namespaced, but because for RoleRef above we don't + // know whether the referenced role is a ClusterRole or Role + // and therefore always renames, we have to do the same here. + f.PatchName(&item.Name) + case *storage.StorageClass: + f.PatchName(&item.Name) + case *v1.ServiceAccount: + f.PatchNamespace(&item.ObjectMeta.Namespace) + case *v1.Secret: + f.PatchNamespace(&item.ObjectMeta.Namespace) + case *rbac.ClusterRoleBinding: + f.PatchName(&item.Name) + for i := range item.Subjects { + if err := f.patchItemRecursively(&item.Subjects[i]); err != nil { + return errors.Wrapf(err, "%T", f) + } + } + if err := f.patchItemRecursively(&item.RoleRef); err != nil { + return errors.Wrapf(err, "%T", f) + } + case *rbac.RoleBinding: + f.PatchNamespace(&item.Namespace) + for i := range item.Subjects { + if err := f.patchItemRecursively(&item.Subjects[i]); err != nil { + return errors.Wrapf(err, "%T", f) + } + } + if err := f.patchItemRecursively(&item.RoleRef); err != nil { + return errors.Wrapf(err, "%T", f) + } + case *v1.Service: + f.PatchNamespace(&item.ObjectMeta.Namespace) + case *apps.StatefulSet: + f.PatchNamespace(&item.ObjectMeta.Namespace) + case *apps.DaemonSet: + f.PatchNamespace(&item.ObjectMeta.Namespace) + default: + return errors.Errorf("missing support for patching item of type %T", item) + } + return nil +} + +// The individual factories all follow the same template, but with +// enough differences in types and functions that copy-and-paste +// looked like the least dirty approach. Perhaps one day Go will have +// generics. + +type serviceAccountFactory struct{} + +func (f *serviceAccountFactory) New() runtime.Object { + return &v1.ServiceAccount{} +} + +func (*serviceAccountFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*v1.ServiceAccount) + if !ok { + return nil, ItemNotSupported + } + client := f.ClientSet.CoreV1().ServiceAccounts(f.Namespace.GetName()) + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create ServiceAccount") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type clusterRoleFactory struct{} + +func (f *clusterRoleFactory) New() runtime.Object { + return &rbac.ClusterRole{} +} + +func (*clusterRoleFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*rbac.ClusterRole) + if !ok { + return nil, ItemNotSupported + } + + // Impersonation is required for Kubernetes < 1.12, see + // https://github.com/kubernetes/kubernetes/issues/62237#issuecomment-429315111 + // + // This code is kept even for more recent Kubernetes, because users of + // the framework outside of Kubernetes might run against an older version + // of Kubernetes. It will be deprecated eventually. + // + // TODO: is this only needed for a ClusterRole or also for other non-namespaced + // items? + Logf("Creating an impersonating superuser kubernetes clientset to define cluster role") + rc, err := LoadConfig() + ExpectNoError(err) + rc.Impersonate = restclient.ImpersonationConfig{ + UserName: "superuser", + Groups: []string{"system:masters"}, + } + superuserClientset, err := clientset.NewForConfig(rc) + ExpectNoError(err, "create superuser clientset") + + client := superuserClientset.RbacV1().ClusterRoles() + if _, err = client.Create(item); err != nil { + return nil, errors.Wrap(err, "create ClusterRole") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type clusterRoleBindingFactory struct{} + +func (f *clusterRoleBindingFactory) New() runtime.Object { + return &rbac.ClusterRoleBinding{} +} + +func (*clusterRoleBindingFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*rbac.ClusterRoleBinding) + if !ok { + return nil, ItemNotSupported + } + + client := f.ClientSet.RbacV1().ClusterRoleBindings() + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create ClusterRoleBinding") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type roleFactory struct{} + +func (f *roleFactory) New() runtime.Object { + return &rbac.Role{} +} + +func (*roleFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*rbac.Role) + if !ok { + return nil, ItemNotSupported + } + + client := f.ClientSet.RbacV1().Roles(f.Namespace.GetName()) + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create Role") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type roleBindingFactory struct{} + +func (f *roleBindingFactory) New() runtime.Object { + return &rbac.RoleBinding{} +} + +func (*roleBindingFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*rbac.RoleBinding) + if !ok { + return nil, ItemNotSupported + } + + client := f.ClientSet.RbacV1().RoleBindings(f.Namespace.GetName()) + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create RoleBinding") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type serviceFactory struct{} + +func (f *serviceFactory) New() runtime.Object { + return &v1.Service{} +} + +func (*serviceFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*v1.Service) + if !ok { + return nil, ItemNotSupported + } + + client := f.ClientSet.CoreV1().Services(f.Namespace.GetName()) + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create Service") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type statefulSetFactory struct{} + +func (f *statefulSetFactory) New() runtime.Object { + return &apps.StatefulSet{} +} + +func (*statefulSetFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*apps.StatefulSet) + if !ok { + return nil, ItemNotSupported + } + + client := f.ClientSet.AppsV1().StatefulSets(f.Namespace.GetName()) + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create StatefulSet") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type daemonSetFactory struct{} + +func (f *daemonSetFactory) New() runtime.Object { + return &apps.DaemonSet{} +} + +func (*daemonSetFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*apps.DaemonSet) + if !ok { + return nil, ItemNotSupported + } + + client := f.ClientSet.AppsV1().DaemonSets(f.Namespace.GetName()) + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create DaemonSet") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type storageClassFactory struct{} + +func (f *storageClassFactory) New() runtime.Object { + return &storage.StorageClass{} +} + +func (*storageClassFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*storage.StorageClass) + if !ok { + return nil, ItemNotSupported + } + + client := f.ClientSet.StorageV1().StorageClasses() + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create StorageClass") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +type secretFactory struct{} + +func (f *secretFactory) New() runtime.Object { + return &v1.Secret{} +} + +func (*secretFactory) Create(f *Framework, i interface{}) (func() error, error) { + item, ok := i.(*v1.Secret) + if !ok { + return nil, ItemNotSupported + } + + client := f.ClientSet.CoreV1().Secrets(f.Namespace.GetName()) + if _, err := client.Create(item); err != nil { + return nil, errors.Wrap(err, "create Secret") + } + return func() error { + return client.Delete(item.GetName(), &metav1.DeleteOptions{}) + }, nil +} + +// PrettyPrint returns a human-readable representation of an item. +func PrettyPrint(item interface{}) string { + data, err := json.MarshalIndent(item, "", " ") + if err == nil { + return string(data) + } + return fmt.Sprintf("%+v", item) +} diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index 29f136ad2cac2..8bd4c931b5bf2 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -25,6 +25,7 @@ import ( "bufio" "bytes" "fmt" + "math/rand" "os" "strings" "sync" @@ -68,6 +69,11 @@ const ( type Framework struct { BaseName string + // Set together with creating the ClientSet and the namespace. + // Guaranteed to be unique in the cluster even when running the same + // test multiple times in parallel. + UniqueName string + ClientSet clientset.Interface KubemarkExternalClusterClientSet clientset.Interface APIExtensionsClientSet apiextensionsclient.Interface @@ -229,6 +235,10 @@ func (f *Framework) BeforeEach() { } else { Logf("Skipping waiting for service account") } + f.UniqueName = f.Namespace.GetName() + } else { + // not guaranteed to be unique, but very likely + f.UniqueName = fmt.Sprintf("%s-%08x", f.BaseName, rand.Int31()) } if TestContext.GatherKubeSystemResourceUsageData != "false" && TestContext.GatherKubeSystemResourceUsageData != "none" { diff --git a/test/e2e/framework/networking_utils.go b/test/e2e/framework/networking_utils.go index 7f507a8390f0f..a8f8831d2c5ae 100644 --- a/test/e2e/framework/networking_utils.go +++ b/test/e2e/framework/networking_utils.go @@ -952,7 +952,7 @@ func TestUnderTemporaryNetworkFailure(c clientset.Interface, ns string, node *v1 if err != nil { Failf("Error getting node external ip : %v", err) } - master := GetMasterAddress(c) + masterAddresses := GetAllMasterAddresses(c) By(fmt.Sprintf("block network traffic from node %s to the master", node.Name)) defer func() { // This code will execute even if setting the iptables rule failed. @@ -960,14 +960,18 @@ func TestUnderTemporaryNetworkFailure(c clientset.Interface, ns string, node *v1 // had been inserted. (yes, we could look at the error code and ssh error // separately, but I prefer to stay on the safe side). By(fmt.Sprintf("Unblock network traffic from node %s to the master", node.Name)) - UnblockNetwork(host, master) + for _, masterAddress := range masterAddresses { + UnblockNetwork(host, masterAddress) + } }() Logf("Waiting %v to ensure node %s is ready before beginning test...", resizeNodeReadyTimeout, node.Name) if !WaitForNodeToBe(c, node.Name, v1.NodeReady, true, resizeNodeReadyTimeout) { Failf("Node %s did not become ready within %v", node.Name, resizeNodeReadyTimeout) } - BlockNetwork(host, master) + for _, masterAddress := range masterAddresses { + BlockNetwork(host, masterAddress) + } Logf("Waiting %v for node %s to be not ready after simulated network failure", resizeNodeNotReadyTimeout, node.Name) if !WaitForNodeToBe(c, node.Name, v1.NodeReady, false, resizeNodeNotReadyTimeout) { diff --git a/test/e2e/framework/podlogs/BUILD b/test/e2e/framework/podlogs/BUILD new file mode 100644 index 0000000000000..404f6b7a98d97 --- /dev/null +++ b/test/e2e/framework/podlogs/BUILD @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["podlogs.go"], + importpath = "k8s.io/kubernetes/test/e2e/framework/podlogs", + visibility = ["//visibility:public"], + deps = [ + "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes:go_default_library", + "//vendor/github.com/pkg/errors: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/test/e2e/framework/podlogs/podlogs.go b/test/e2e/framework/podlogs/podlogs.go new file mode 100644 index 0000000000000..77fae293af027 --- /dev/null +++ b/test/e2e/framework/podlogs/podlogs.go @@ -0,0 +1,263 @@ +/* +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 podlogs enables live capturing of all events and log +// messages for some or all pods in a namespace as they get generated. +// This helps debugging both a running test (what is currently going +// on?) and the output of a CI run (events appear in chronological +// order and output that normally isn't available like the command +// stdout messages are available). +package podlogs + +import ( + "bufio" + "bytes" + "context" + "fmt" + "github.com/pkg/errors" + "io" + "os" + "path" + "regexp" + "strings" + "sync" + + "k8s.io/api/core/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + clientset "k8s.io/client-go/kubernetes" +) + +// LogsForPod starts reading the logs for a certain pod. If the pod has more than one +// container, opts.Container must be set. Reading stops when the context is done. +// The stream includes formatted error messages and ends with +// rpc error: code = Unknown desc = Error: No such container: 41a... +// when the pod gets deleted while streaming. +func LogsForPod(ctx context.Context, cs clientset.Interface, ns, pod string, opts *v1.PodLogOptions) (io.ReadCloser, error) { + req := cs.Core().Pods(ns).GetLogs(pod, opts) + return req.Context(ctx).Stream() +} + +// LogOutput determines where output from CopyAllLogs goes. +type LogOutput struct { + // If not nil, errors will be logged here. + StatusWriter io.Writer + + // If not nil, all output goes to this writer with "/:" as prefix. + LogWriter io.Writer + + // Base directory for one log file per container. + // The full path of each log file will be -.log. + LogPathPrefix string +} + +// Matches harmless errors from pkg/kubelet/kubelet_pods.go. +var expectedErrors = regexp.MustCompile(`container .* in pod .* is (terminated|waiting to start|not available)|the server could not find the requested resource`) + +// CopyAllLogs follows the logs of all containers in all pods, +// including those that get created in the future, and writes each log +// line as configured in the output options. It does that until the +// context is done or until an error occurs. +// +// Beware that there is currently no way to force log collection +// before removing pods, which means that there is a known race +// between "stop pod" and "collecting log entries". The alternative +// would be a blocking function with collects logs from all currently +// running pods, but that then would have the disadvantage that +// already deleted pods aren't covered. +func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogOutput) error { + watcher, err := cs.Core().Pods(ns).Watch(meta.ListOptions{}) + if err != nil { + return errors.Wrap(err, "cannot create Pod event watcher") + } + + go func() { + var m sync.Mutex + logging := map[string]bool{} + check := func() { + m.Lock() + defer m.Unlock() + + pods, err := cs.Core().Pods(ns).List(meta.ListOptions{}) + if err != nil { + if to.StatusWriter != nil { + fmt.Fprintf(to.StatusWriter, "ERROR: get pod list in %s: %s\n", ns, err) + } + return + } + + for _, pod := range pods.Items { + for _, c := range pod.Spec.Containers { + name := pod.ObjectMeta.Name + "/" + c.Name + if logging[name] { + continue + } + readCloser, err := LogsForPod(ctx, cs, ns, pod.ObjectMeta.Name, + &v1.PodLogOptions{ + Container: c.Name, + Follow: true, + }) + if err != nil { + // We do get "normal" errors here, like trying to read too early. + // We can ignore those. + if to.StatusWriter != nil && + expectedErrors.FindStringIndex(err.Error()) == nil { + fmt.Fprintf(to.StatusWriter, "WARNING: pod log: %s: %s\n", name, err) + } + continue + } + + // Determine where we write. If this fails, we intentionally return without clearing + // the logging[name] flag, which prevents trying over and over again to + // create the output file. + var out io.Writer + var closer io.Closer + var prefix string + if to.LogWriter != nil { + out = to.LogWriter + prefix = name + ": " + } else { + var err error + filename := to.LogPathPrefix + pod.ObjectMeta.Name + "-" + c.Name + ".log" + err = os.MkdirAll(path.Dir(filename), 0755) + if err != nil { + if to.StatusWriter != nil { + fmt.Fprintf(to.StatusWriter, "ERROR: pod log: create directory for %s: %s\n", filename, err) + } + return + } + // The test suite might run the same test multiple times, + // so we have to append here. + file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + if to.StatusWriter != nil { + fmt.Fprintf(to.StatusWriter, "ERROR: pod log: create file %s: %s\n", filename, err) + } + return + } + closer = file + out = file + } + go func() { + if closer != nil { + defer closer.Close() + } + defer func() { + m.Lock() + logging[name] = false + m.Unlock() + readCloser.Close() + }() + scanner := bufio.NewScanner(readCloser) + first := true + for scanner.Scan() { + line := scanner.Text() + // Filter out the expected "end of stream" error message, + // it would just confuse developers who don't know about it. + // Same for attempts to read logs from a container that + // isn't ready (yet?!). + if !strings.HasPrefix(line, "rpc error: code = Unknown desc = Error: No such container:") && + !strings.HasPrefix(line, "Unable to retrieve container logs for ") { + if first { + if to.LogWriter == nil { + // Because the same log might be written to multiple times + // in different test instances, log an extra line to separate them. + // Also provides some useful extra information. + fmt.Fprintf(out, "==== start of log for container %s ====\n", name) + } + first = false + } + fmt.Fprintf(out, "%s%s\n", prefix, scanner.Text()) + } + } + }() + logging[name] = true + } + } + } + + // Watch events to see whether we can start logging + // and log interesting ones. + check() + for { + select { + case <-watcher.ResultChan(): + check() + case <-ctx.Done(): + return + } + } + }() + + return nil +} + +// WatchPods prints pod status events for a certain namespace or all namespaces +// when namespace name is empty. +func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Writer) error { + watcher, err := cs.Core().Pods(ns).Watch(meta.ListOptions{}) + if err != nil { + return errors.Wrap(err, "cannot create Pod event watcher") + } + + go func() { + defer watcher.Stop() + for { + select { + case e := <-watcher.ResultChan(): + if e.Object == nil { + continue + } + + pod, ok := e.Object.(*v1.Pod) + if !ok { + continue + } + buffer := new(bytes.Buffer) + fmt.Fprintf(buffer, + "pod event: %s: %s/%s %s: %s %s\n", + e.Type, + pod.Namespace, + pod.Name, + pod.Status.Phase, + pod.Status.Reason, + pod.Status.Conditions, + ) + for _, cst := range pod.Status.ContainerStatuses { + fmt.Fprintf(buffer, " %s: ", cst.Name) + if cst.State.Waiting != nil { + fmt.Fprintf(buffer, "WAITING: %s - %s", + cst.State.Waiting.Reason, + cst.State.Waiting.Message, + ) + } else if cst.State.Running != nil { + fmt.Fprintf(buffer, "RUNNING") + } else if cst.State.Waiting != nil { + fmt.Fprintf(buffer, "TERMINATED: %s - %s", + cst.State.Waiting.Reason, + cst.State.Waiting.Message, + ) + } + fmt.Fprintf(buffer, "\n") + } + to.Write(buffer.Bytes()) + case <-ctx.Done(): + return + } + } + }() + + return nil +} diff --git a/test/e2e/framework/provider.go b/test/e2e/framework/provider.go index f6c8181e0cfc4..7c75b15ee23bf 100644 --- a/test/e2e/framework/provider.go +++ b/test/e2e/framework/provider.go @@ -18,8 +18,11 @@ package framework import ( "fmt" + "os" "sync" + "github.com/pkg/errors" + "k8s.io/api/core/v1" clientset "k8s.io/client-go/kubernetes" ) @@ -66,7 +69,7 @@ func SetupProviderConfig(providerName string) (ProviderInterface, error) { defer mutex.Unlock() factory, ok := providers[providerName] if !ok { - return nil, fmt.Errorf("The provider %s is unknown.", providerName) + return nil, errors.Wrapf(os.ErrNotExist, "The provider %s is unknown.", providerName) } provider, err := factory() diff --git a/test/e2e/framework/providers/gce/firewall.go b/test/e2e/framework/providers/gce/firewall.go index 6894cb36b9aa8..70468920d2128 100644 --- a/test/e2e/framework/providers/gce/firewall.go +++ b/test/e2e/framework/providers/gce/firewall.go @@ -401,7 +401,7 @@ func VerifyFirewallRule(res, exp *compute.Firewall, network string, portsSubset return nil } -func WaitForFirewallRule(gceCloud *gcecloud.GCECloud, fwName string, exist bool, timeout time.Duration) (*compute.Firewall, error) { +func WaitForFirewallRule(gceCloud *gcecloud.Cloud, fwName string, exist bool, timeout time.Duration) (*compute.Firewall, error) { framework.Logf("Waiting up to %v for firewall %v exist=%v", timeout, fwName, exist) var fw *compute.Firewall var err error diff --git a/test/e2e/framework/providers/gce/gce.go b/test/e2e/framework/providers/gce/gce.go index 29da3e4d7964b..9236ef13405d9 100644 --- a/test/e2e/framework/providers/gce/gce.go +++ b/test/e2e/framework/providers/gce/gce.go @@ -58,7 +58,7 @@ func factory() (framework.ProviderInterface, error) { } gceCloud, err := gcecloud.CreateGCECloud(&gcecloud.CloudConfig{ - ApiEndpoint: framework.TestContext.CloudConfig.ApiEndpoint, + APIEndpoint: framework.TestContext.CloudConfig.ApiEndpoint, ProjectID: framework.TestContext.CloudConfig.ProjectID, Region: region, Zone: zone, @@ -89,7 +89,7 @@ func factory() (framework.ProviderInterface, error) { return NewProvider(gceCloud), nil } -func NewProvider(gceCloud *gcecloud.GCECloud) framework.ProviderInterface { +func NewProvider(gceCloud *gcecloud.Cloud) framework.ProviderInterface { return &Provider{ gceCloud: gceCloud, } @@ -97,7 +97,7 @@ func NewProvider(gceCloud *gcecloud.GCECloud) framework.ProviderInterface { type Provider struct { framework.NullProvider - gceCloud *gcecloud.GCECloud + gceCloud *gcecloud.Cloud } func (p *Provider) ResizeGroup(group string, size int32) error { @@ -279,7 +279,7 @@ func (p *Provider) cleanupGCEResources(c clientset.Interface, loadBalancerName, return } hcNames := []string{gcecloud.MakeNodesHealthCheckName(clusterID)} - hc, getErr := p.gceCloud.GetHttpHealthCheck(loadBalancerName) + hc, getErr := p.gceCloud.GetHTTPHealthCheck(loadBalancerName) if getErr != nil && !IsGoogleAPIHTTPErrorCode(getErr, http.StatusNotFound) { retErr = fmt.Errorf("%v\n%v", retErr, getErr) return @@ -351,7 +351,7 @@ func IsGoogleAPIHTTPErrorCode(err error, code int) bool { return ok && apiErr.Code == code } -func GetGCECloud() (*gcecloud.GCECloud, error) { +func GetGCECloud() (*gcecloud.Cloud, error) { p, ok := framework.TestContext.CloudConfig.Provider.(*Provider) if !ok { return nil, fmt.Errorf("failed to convert CloudConfig.Provider to GCE provider: %#v", framework.TestContext.CloudConfig.Provider) diff --git a/test/e2e/framework/providers/gce/ingress.go b/test/e2e/framework/providers/gce/ingress.go index b11598fb7561d..9ea772c7ee9fd 100644 --- a/test/e2e/framework/providers/gce/ingress.go +++ b/test/e2e/framework/providers/gce/ingress.go @@ -198,7 +198,7 @@ func (cont *GCEIngressController) deleteAddresses(del bool) string { func (cont *GCEIngressController) ListTargetHttpProxies() []*compute.TargetHttpProxy { gceCloud := cont.Cloud.Provider.(*Provider).gceCloud tpList := []*compute.TargetHttpProxy{} - l, err := gceCloud.ListTargetHttpProxies() + l, err := gceCloud.ListTargetHTTPProxies() Expect(err).NotTo(HaveOccurred()) for _, tp := range l { if cont.isOwned(tp.Name) { @@ -211,7 +211,7 @@ func (cont *GCEIngressController) ListTargetHttpProxies() []*compute.TargetHttpP func (cont *GCEIngressController) ListTargetHttpsProxies() []*compute.TargetHttpsProxy { gceCloud := cont.Cloud.Provider.(*Provider).gceCloud tpsList := []*compute.TargetHttpsProxy{} - l, err := gceCloud.ListTargetHttpsProxies() + l, err := gceCloud.ListTargetHTTPSProxies() Expect(err).NotTo(HaveOccurred()) for _, tps := range l { if cont.isOwned(tps.Name) { @@ -259,7 +259,7 @@ func (cont *GCEIngressController) deleteTargetProxy(del bool) string { func (cont *GCEIngressController) ListUrlMaps() []*compute.UrlMap { gceCloud := cont.Cloud.Provider.(*Provider).gceCloud umList := []*compute.UrlMap{} - l, err := gceCloud.ListUrlMaps() + l, err := gceCloud.ListURLMaps() Expect(err).NotTo(HaveOccurred()) for _, um := range l { if cont.isOwned(um.Name) { @@ -271,7 +271,7 @@ func (cont *GCEIngressController) ListUrlMaps() []*compute.UrlMap { func (cont *GCEIngressController) deleteURLMap(del bool) (msg string) { gceCloud := cont.Cloud.Provider.(*Provider).gceCloud - umList, err := gceCloud.ListUrlMaps() + umList, err := gceCloud.ListURLMaps() if err != nil { if cont.isHTTPErrorCode(err, http.StatusNotFound) { return msg @@ -287,7 +287,7 @@ func (cont *GCEIngressController) deleteURLMap(del bool) (msg string) { } if del { framework.Logf("Deleting url-map: %s", um.Name) - if err := gceCloud.DeleteUrlMap(um.Name); err != nil && + if err := gceCloud.DeleteURLMap(um.Name); err != nil && !cont.isHTTPErrorCode(err, http.StatusNotFound) { msg += fmt.Sprintf("Failed to delete url map %v\n", um.Name) } @@ -343,7 +343,7 @@ func (cont *GCEIngressController) deleteBackendService(del bool) (msg string) { func (cont *GCEIngressController) deleteHTTPHealthCheck(del bool) (msg string) { gceCloud := cont.Cloud.Provider.(*Provider).gceCloud - hcList, err := gceCloud.ListHttpHealthChecks() + hcList, err := gceCloud.ListHTTPHealthChecks() if err != nil { if cont.isHTTPErrorCode(err, http.StatusNotFound) { return msg @@ -359,7 +359,7 @@ func (cont *GCEIngressController) deleteHTTPHealthCheck(del bool) (msg string) { } if del { framework.Logf("Deleting http-health-check: %s", hc.Name) - if err := gceCloud.DeleteHttpHealthCheck(hc.Name); err != nil && + if err := gceCloud.DeleteHTTPHealthCheck(hc.Name); err != nil && !cont.isHTTPErrorCode(err, http.StatusNotFound) { msg += fmt.Sprintf("Failed to delete HTTP health check %v\n", hc.Name) } diff --git a/test/e2e/framework/psp_util.go b/test/e2e/framework/psp_util.go index 30ba939095d5f..82363ed04f6f8 100644 --- a/test/e2e/framework/psp_util.go +++ b/test/e2e/framework/psp_util.go @@ -21,7 +21,7 @@ import ( "sync" corev1 "k8s.io/api/core/v1" - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + policy "k8s.io/api/policy/v1beta1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" apierrs "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,33 +42,33 @@ var ( ) // Creates a PodSecurityPolicy that allows everything. -func PrivilegedPSP(name string) *extensionsv1beta1.PodSecurityPolicy { +func PrivilegedPSP(name string) *policy.PodSecurityPolicy { allowPrivilegeEscalation := true - return &extensionsv1beta1.PodSecurityPolicy{ + return &policy.PodSecurityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: name, Annotations: map[string]string{seccomp.AllowedProfilesAnnotationKey: seccomp.AllowAny}, }, - Spec: extensionsv1beta1.PodSecurityPolicySpec{ + Spec: policy.PodSecurityPolicySpec{ Privileged: true, AllowPrivilegeEscalation: &allowPrivilegeEscalation, AllowedCapabilities: []corev1.Capability{"*"}, - Volumes: []extensionsv1beta1.FSType{extensionsv1beta1.All}, + Volumes: []policy.FSType{policy.All}, HostNetwork: true, - HostPorts: []extensionsv1beta1.HostPortRange{{Min: 0, Max: 65535}}, + HostPorts: []policy.HostPortRange{{Min: 0, Max: 65535}}, HostIPC: true, HostPID: true, - RunAsUser: extensionsv1beta1.RunAsUserStrategyOptions{ - Rule: extensionsv1beta1.RunAsUserStrategyRunAsAny, + RunAsUser: policy.RunAsUserStrategyOptions{ + Rule: policy.RunAsUserStrategyRunAsAny, }, - SELinux: extensionsv1beta1.SELinuxStrategyOptions{ - Rule: extensionsv1beta1.SELinuxStrategyRunAsAny, + SELinux: policy.SELinuxStrategyOptions{ + Rule: policy.SELinuxStrategyRunAsAny, }, - SupplementalGroups: extensionsv1beta1.SupplementalGroupsStrategyOptions{ - Rule: extensionsv1beta1.SupplementalGroupsStrategyRunAsAny, + SupplementalGroups: policy.SupplementalGroupsStrategyOptions{ + Rule: policy.SupplementalGroupsStrategyRunAsAny, }, - FSGroup: extensionsv1beta1.FSGroupStrategyOptions{ - Rule: extensionsv1beta1.FSGroupStrategyRunAsAny, + FSGroup: policy.FSGroupStrategyOptions{ + Rule: policy.FSGroupStrategyRunAsAny, }, ReadOnlyRootFilesystem: false, AllowedUnsafeSysctls: []string{"*"}, @@ -112,7 +112,7 @@ func CreatePrivilegedPSPBinding(f *Framework, namespace string) { } psp := PrivilegedPSP(podSecurityPolicyPrivileged) - psp, err = f.ClientSet.ExtensionsV1beta1().PodSecurityPolicies().Create(psp) + psp, err = f.ClientSet.PolicyV1beta1().PodSecurityPolicies().Create(psp) if !apierrs.IsAlreadyExists(err) { ExpectNoError(err, "Failed to create PSP %s", podSecurityPolicyPrivileged) } diff --git a/test/e2e/framework/rc_util.go b/test/e2e/framework/rc_util.go index edd88dd0ba46a..d7a88937f268d 100644 --- a/test/e2e/framework/rc_util.go +++ b/test/e2e/framework/rc_util.go @@ -247,7 +247,7 @@ func ValidateController(c clientset.Interface, containerImage string, replicas i // You can read about the syntax here: http://golang.org/pkg/text/template/. getContainerStateTemplate := fmt.Sprintf(`--template={{if (exists . "status" "containerStatuses")}}{{range .status.containerStatuses}}{{if (and (eq .name "%s") (exists . "state" "running"))}}true{{end}}{{end}}{{end}}`, containername) - getImageTemplate := fmt.Sprintf(`--template={{if (exists . "status" "containerStatuses")}}{{range .status.containerStatuses}}{{if eq .name "%s"}}{{.image}}{{end}}{{end}}{{end}}`, containername) + getImageTemplate := fmt.Sprintf(`--template={{if (exists . "spec" "containers")}}{{range .spec.containers}}{{if eq .name "%s"}}{{.image}}{{end}}{{end}}{{end}}`, containername) By(fmt.Sprintf("waiting for all containers in %s pods to come up.", testname)) //testname should be selector waitLoop: diff --git a/test/e2e/framework/test_context.go b/test/e2e/framework/test_context.go index dc3bd24640cc6..be50ec1c6bee5 100644 --- a/test/e2e/framework/test_context.go +++ b/test/e2e/framework/test_context.go @@ -25,6 +25,7 @@ import ( "github.com/golang/glog" "github.com/onsi/ginkgo/config" + "github.com/pkg/errors" utilflag "k8s.io/apiserver/pkg/util/flag" restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -144,6 +145,9 @@ type TestContextType struct { // Indicates what path the kubernetes-anywhere is installed on KubernetesAnywherePath string + + // The DNS Domain of the cluster. + ClusterDNSDomain string } // NodeTestContextType is part of TestContextType, it is shared by all node e2e test. @@ -247,11 +251,12 @@ func RegisterClusterFlags() { flag.StringVar(&TestContext.NodeOSDistro, "node-os-distro", "debian", "The OS distribution of cluster VM instances (debian, ubuntu, gci, coreos, or custom).") flag.StringVar(&TestContext.ClusterMonitoringMode, "cluster-monitoring-mode", "standalone", "The monitoring solution that is used in the cluster.") flag.BoolVar(&TestContext.EnablePrometheusMonitoring, "prometheus-monitoring", false, "Separate Prometheus monitoring deployed in cluster.") + flag.StringVar(&TestContext.ClusterDNSDomain, "dns-domain", "cluster.local", "The DNS Domain of the cluster.") // TODO: Flags per provider? Rename gce-project/gce-zone? cloudConfig := &TestContext.CloudConfig flag.StringVar(&cloudConfig.MasterName, "kube-master", "", "Name of the kubernetes master. Only required if provider is gce or gke") - flag.StringVar(&cloudConfig.ApiEndpoint, "gce-api-endpoint", "", "The GCE ApiEndpoint being used, if applicable") + flag.StringVar(&cloudConfig.ApiEndpoint, "gce-api-endpoint", "", "The GCE APIEndpoint being used, if applicable") flag.StringVar(&cloudConfig.ProjectID, "gce-project", "", "The GCE project being used, if applicable") flag.StringVar(&cloudConfig.Zone, "gce-zone", "", "GCE zone being used, if applicable") flag.StringVar(&cloudConfig.Region, "gce-region", "", "GCE region being used, if applicable") @@ -366,7 +371,20 @@ func AfterReadingAllFlags(t *TestContextType) { // Make sure that all test runs have a valid TestContext.CloudConfig.Provider. var err error TestContext.CloudConfig.Provider, err = SetupProviderConfig(TestContext.Provider) + if err == nil { + return + } + if !os.IsNotExist(errors.Cause(err)) { + Failf("Failed to setup provider config: %v", err) + } + // We allow unknown provider parameters for historic reasons. At least log a + // warning to catch typos. + // TODO (https://github.com/kubernetes/kubernetes/issues/70200): + // - remove the fallback for unknown providers + // - proper error message instead of Failf (which panics) + glog.Warningf("Unknown provider %q, proceeding as for --provider=skeleton.", TestContext.Provider) + TestContext.CloudConfig.Provider, err = SetupProviderConfig("skeleton") if err != nil { - Failf("Failed to setup provide r config: %v", err) + Failf("Failed to setup fallback skeleton provider config: %v", err) } } diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index 8e29c8bb03a3d..8320c0519d175 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -394,6 +394,12 @@ func SkipUnlessSecretExistsAfterWait(c clientset.Interface, name, namespace stri Logf("Secret %v in namespace %v found after duration %v", name, namespace, time.Since(start)) } +func SkipUnlessTaintBasedEvictionsEnabled() { + if !utilfeature.DefaultFeatureGate.Enabled(features.TaintBasedEvictions) { + Skipf("Only supported when %v feature is enabled", features.TaintBasedEvictions) + } +} + func SkipIfContainerRuntimeIs(runtimes ...string) { for _, runtime := range runtimes { if runtime == TestContext.ContainerRuntime { @@ -3155,7 +3161,10 @@ func DeleteResourceAndWaitForGC(c clientset.Interface, kind schema.GroupKind, ns terminatePodTime := time.Since(startTime) - deleteTime Logf("Terminating %v %s pods took: %v", kind, name, terminatePodTime) - err = waitForPodsGone(ps, interval, 10*time.Minute) + // In gce, at any point, small percentage of nodes can disappear for + // ~10 minutes due to hostError. 20 minutes should be long enough to + // restart VM in that case and delete the pod. + err = waitForPodsGone(ps, interval, 20*time.Minute) if err != nil { return fmt.Errorf("error while waiting for pods gone %s: %v", name, err) } @@ -3167,25 +3176,48 @@ func DeleteResourceAndWaitForGC(c clientset.Interface, kind schema.GroupKind, ns // and DeleteRCAndWaitForGC, because the RC controller decreases status.replicas // when the pod is inactvie. func waitForPodsInactive(ps *testutils.PodStore, interval, timeout time.Duration) error { - return wait.PollImmediate(interval, timeout, func() (bool, error) { + var activePods []*v1.Pod + err := wait.PollImmediate(interval, timeout, func() (bool, error) { pods := ps.List() + activePods = nil for _, pod := range pods { if controller.IsPodActive(pod) { - return false, nil + activePods = append(activePods, pod) } } + + if len(activePods) != 0 { + return false, nil + } return true, nil }) + + if err == wait.ErrWaitTimeout { + for _, pod := range activePods { + Logf("ERROR: Pod %q running on %q is still active", pod.Name, pod.Spec.NodeName) + } + return fmt.Errorf("there are %d active pods. E.g. %q on node %q", len(activePods), activePods[0].Name, activePods[0].Spec.NodeName) + } + return err } // waitForPodsGone waits until there are no pods left in the PodStore. func waitForPodsGone(ps *testutils.PodStore, interval, timeout time.Duration) error { - return wait.PollImmediate(interval, timeout, func() (bool, error) { - if pods := ps.List(); len(pods) == 0 { + var pods []*v1.Pod + err := wait.PollImmediate(interval, timeout, func() (bool, error) { + if pods = ps.List(); len(pods) == 0 { return true, nil } return false, nil }) + + if err == wait.ErrWaitTimeout { + for _, pod := range pods { + Logf("ERROR: Pod %q still exists. Node: %q", pod.Name, pod.Spec.NodeName) + } + return fmt.Errorf("there are %d pods left. E.g. %q on node %q", len(pods), pods[0].Name, pods[0].Spec.NodeName) + } + return err } func WaitForPodsReady(c clientset.Interface, ns, name string, minReadySeconds int) error { @@ -3895,7 +3927,7 @@ func ParseKVLines(output, key string) string { func RestartKubeProxy(host string) error { // TODO: Make it work for all providers. if !ProviderIs("gce", "gke", "aws") { - return fmt.Errorf("unsupported provider: %s", TestContext.Provider) + return fmt.Errorf("unsupported provider for RestartKubeProxy: %s", TestContext.Provider) } // kubelet will restart the kube-proxy since it's running in a static pod Logf("Killing kube-proxy on node %v", host) @@ -3932,7 +3964,7 @@ func RestartKubelet(host string) error { // TODO: Make it work for all providers and distros. supportedProviders := []string{"gce", "aws", "vsphere"} if !ProviderIs(supportedProviders...) { - return fmt.Errorf("unsupported provider: %s, supported providers are: %v", TestContext.Provider, supportedProviders) + return fmt.Errorf("unsupported provider for RestartKubelet: %s, supported providers are: %v", TestContext.Provider, supportedProviders) } if ProviderIs("gce") && !NodeOSDistroIs("debian", "gci") { return fmt.Errorf("unsupported node OS distro: %s", TestContext.NodeOSDistro) @@ -3988,7 +4020,7 @@ func WaitForKubeletUp(host string) error { func RestartApiserver(cs clientset.Interface) error { // TODO: Make it work for all providers. if !ProviderIs("gce", "gke", "aws") { - return fmt.Errorf("unsupported provider: %s", TestContext.Provider) + return fmt.Errorf("unsupported provider for RestartApiserver: %s", TestContext.Provider) } if ProviderIs("gce", "aws") { initialRestartCount, err := getApiserverRestartCount(cs) @@ -4011,7 +4043,7 @@ func RestartApiserver(cs clientset.Interface) error { func sshRestartMaster() error { if !ProviderIs("gce", "aws") { - return fmt.Errorf("unsupported provider: %s", TestContext.Provider) + return fmt.Errorf("unsupported provider for sshRestartMaster: %s", TestContext.Provider) } var command string if ProviderIs("gce") { @@ -4077,7 +4109,7 @@ func getApiserverRestartCount(c clientset.Interface) (int32, error) { func RestartControllerManager() error { // TODO: Make it work for all providers and distros. if !ProviderIs("gce", "aws") { - return fmt.Errorf("unsupported provider: %s", TestContext.Provider) + return fmt.Errorf("unsupported provider for RestartControllerManager: %s", TestContext.Provider) } if ProviderIs("gce") && !MasterOSDistroIs("gci") { return fmt.Errorf("unsupported master OS distro: %s", TestContext.MasterOSDistro) @@ -4928,19 +4960,28 @@ func getMaster(c clientset.Interface) Address { return master } -// GetMasterAddress returns the hostname/external IP/internal IP as appropriate for e2e tests on a particular provider -// which is the address of the interface used for communication with the kubelet. -func GetMasterAddress(c clientset.Interface) string { +// GetAllMasterAddresses returns all IP addresses on which the kubelet can reach the master. +// It may return internal and external IPs, even if we expect for +// e.g. internal IPs to be used (issue #56787), so that we can be +// sure to block the master fully during tests. +func GetAllMasterAddresses(c clientset.Interface) []string { master := getMaster(c) + + ips := sets.NewString() switch TestContext.Provider { case "gce", "gke": - return master.externalIP + if master.externalIP != "" { + ips.Insert(master.externalIP) + } + if master.internalIP != "" { + ips.Insert(master.internalIP) + } case "aws": - return awsMasterIP + ips.Insert(awsMasterIP) default: Failf("This test is not supported for provider %s and should be disabled", TestContext.Provider) } - return "" + return ips.List() } // GetNodeExternalIP returns node external IP concatenated with port 22 for ssh @@ -5197,3 +5238,17 @@ func GetClusterZones(c clientset.Interface) (sets.String, error) { } return zones, nil } + +// WaitForNodeHasTaintOrNot waits for a taint to be added/removed from the node until timeout occurs, whichever comes first. +func WaitForNodeHasTaintOrNot(c clientset.Interface, nodeName string, taint *v1.Taint, wantTrue bool, timeout time.Duration) error { + if err := wait.PollImmediate(Poll, timeout, func() (bool, error) { + has, err := NodeHasTaint(c, nodeName, taint) + if err != nil { + return false, fmt.Errorf("failed to check taint %s on node %s or not", taint.ToString(), nodeName) + } + return has == wantTrue, nil + }); err != nil { + return fmt.Errorf("expect node %v to have taint = %v within %v: %v", nodeName, wantTrue, timeout, err) + } + return nil +} diff --git a/test/e2e/network/dns.go b/test/e2e/network/dns.go index 910af0feb0663..8af7177b92243 100644 --- a/test/e2e/network/dns.go +++ b/test/e2e/network/dns.go @@ -47,17 +47,17 @@ var _ = SIGDescribe("DNS", func() { namesToResolve := []string{ "kubernetes.default", "kubernetes.default.svc", - "kubernetes.default.svc.cluster.local", + fmt.Sprintf("kubernetes.default.svc.%s", framework.TestContext.ClusterDNSDomain), } // Added due to #8512. This is critical for GCE and GKE deployments. if framework.ProviderIs("gce", "gke") { namesToResolve = append(namesToResolve, "google.com") namesToResolve = append(namesToResolve, "metadata") } - hostFQDN := fmt.Sprintf("%s.%s.%s.svc.cluster.local", dnsTestPodHostName, dnsTestServiceName, f.Namespace.Name) + hostFQDN := fmt.Sprintf("%s.%s.%s.svc.%s", dnsTestPodHostName, dnsTestServiceName, f.Namespace.Name, framework.TestContext.ClusterDNSDomain) hostEntries := []string{hostFQDN, dnsTestPodHostName} - wheezyProbeCmd, wheezyFileNames := createProbeCommand(namesToResolve, hostEntries, "", "wheezy", f.Namespace.Name) - jessieProbeCmd, jessieFileNames := createProbeCommand(namesToResolve, hostEntries, "", "jessie", f.Namespace.Name) + wheezyProbeCmd, wheezyFileNames := createProbeCommand(namesToResolve, hostEntries, "", "wheezy", f.Namespace.Name, framework.TestContext.ClusterDNSDomain) + jessieProbeCmd, jessieFileNames := createProbeCommand(namesToResolve, hostEntries, "", "jessie", f.Namespace.Name, framework.TestContext.ClusterDNSDomain) By("Running these commands on wheezy: " + wheezyProbeCmd + "\n") By("Running these commands on jessie: " + jessieProbeCmd + "\n") @@ -91,6 +91,7 @@ var _ = SIGDescribe("DNS", func() { regularService := framework.CreateServiceSpec(regularServiceName, "", false, testServiceSelector) regularService, err = f.ClientSet.CoreV1().Services(f.Namespace.Name).Create(regularService) Expect(err).NotTo(HaveOccurred(), "failed to create regular service: %s", regularServiceName) + defer func() { By("deleting the test service") defer GinkgoRecover() @@ -108,8 +109,8 @@ var _ = SIGDescribe("DNS", func() { fmt.Sprintf("_http._tcp.%s.%s.svc", regularService.Name, f.Namespace.Name), } - wheezyProbeCmd, wheezyFileNames := createProbeCommand(namesToResolve, nil, regularService.Spec.ClusterIP, "wheezy", f.Namespace.Name) - jessieProbeCmd, jessieFileNames := createProbeCommand(namesToResolve, nil, regularService.Spec.ClusterIP, "jessie", f.Namespace.Name) + wheezyProbeCmd, wheezyFileNames := createProbeCommand(namesToResolve, nil, regularService.Spec.ClusterIP, "wheezy", f.Namespace.Name, framework.TestContext.ClusterDNSDomain) + jessieProbeCmd, jessieFileNames := createProbeCommand(namesToResolve, nil, regularService.Spec.ClusterIP, "jessie", f.Namespace.Name, framework.TestContext.ClusterDNSDomain) By("Running these commands on wheezy: " + wheezyProbeCmd + "\n") By("Running these commands on jessie: " + jessieProbeCmd + "\n") @@ -132,17 +133,18 @@ var _ = SIGDescribe("DNS", func() { headlessService := framework.CreateServiceSpec(serviceName, "", true, testServiceSelector) _, err := f.ClientSet.CoreV1().Services(f.Namespace.Name).Create(headlessService) Expect(err).NotTo(HaveOccurred(), "failed to create headless service: %s", serviceName) + defer func() { By("deleting the test headless service") defer GinkgoRecover() f.ClientSet.CoreV1().Services(f.Namespace.Name).Delete(headlessService.Name, nil) }() - hostFQDN := fmt.Sprintf("%s.%s.%s.svc.cluster.local", podHostname, serviceName, f.Namespace.Name) + hostFQDN := fmt.Sprintf("%s.%s.%s.svc.%s", podHostname, serviceName, f.Namespace.Name, framework.TestContext.ClusterDNSDomain) hostNames := []string{hostFQDN, podHostname} namesToResolve := []string{hostFQDN} - wheezyProbeCmd, wheezyFileNames := createProbeCommand(namesToResolve, hostNames, "", "wheezy", f.Namespace.Name) - jessieProbeCmd, jessieFileNames := createProbeCommand(namesToResolve, hostNames, "", "jessie", f.Namespace.Name) + wheezyProbeCmd, wheezyFileNames := createProbeCommand(namesToResolve, hostNames, "", "wheezy", f.Namespace.Name, framework.TestContext.ClusterDNSDomain) + jessieProbeCmd, jessieFileNames := createProbeCommand(namesToResolve, hostNames, "", "jessie", f.Namespace.Name, framework.TestContext.ClusterDNSDomain) By("Running these commands on wheezy: " + wheezyProbeCmd + "\n") By("Running these commands on jessie: " + jessieProbeCmd + "\n") @@ -163,13 +165,13 @@ var _ = SIGDescribe("DNS", func() { externalNameService := framework.CreateServiceSpec(serviceName, "foo.example.com", false, nil) _, err := f.ClientSet.CoreV1().Services(f.Namespace.Name).Create(externalNameService) Expect(err).NotTo(HaveOccurred(), "failed to create ExternalName service: %s", serviceName) + defer func() { By("deleting the test externalName service") defer GinkgoRecover() f.ClientSet.CoreV1().Services(f.Namespace.Name).Delete(externalNameService.Name, nil) }() - - hostFQDN := fmt.Sprintf("%s.%s.svc.cluster.local", serviceName, f.Namespace.Name) + hostFQDN := fmt.Sprintf("%s.%s.svc.%s", serviceName, f.Namespace.Name, framework.TestContext.ClusterDNSDomain) wheezyProbeCmd, wheezyFileName := createTargetedProbeCommand(hostFQDN, "CNAME", "wheezy") jessieProbeCmd, jessieFileName := createTargetedProbeCommand(hostFQDN, "CNAME", "jessie") By("Running these commands on wheezy: " + wheezyProbeCmd + "\n") diff --git a/test/e2e/network/dns_common.go b/test/e2e/network/dns_common.go index 73a9499593185..ca1dc35283d99 100644 --- a/test/e2e/network/dns_common.go +++ b/test/e2e/network/dns_common.go @@ -112,14 +112,15 @@ func (t *dnsTestCommon) runDig(dnsName, target string) []string { cmd = append(cmd, "@"+t.dnsPod.Status.PodIP) case "kube-dns": cmd = append(cmd, "@"+t.dnsPod.Status.PodIP, "-p", "10053") + case "ptr-record": + cmd = append(cmd, "-x") case "cluster-dns": + case "cluster-dns-ipv6": + cmd = append(cmd, "AAAA") break default: panic(fmt.Errorf("invalid target: " + target)) } - if strings.HasSuffix(dnsName, "in-addr.arpa") || strings.HasSuffix(dnsName, "in-addr.arpa.") { - cmd = append(cmd, []string{"-t", "ptr"}...) - } cmd = append(cmd, dnsName) stdout, stderr, err := t.f.ExecWithOptions(framework.ExecOptions{ @@ -327,7 +328,7 @@ func (t *dnsTestCommon) createDNSServer(aRecords map[string]string) { t.createDNSPodFromObj(generateDNSServerPod(aRecords)) } -func (t *dnsTestCommon) createDNSServerWithPtrRecord() { +func (t *dnsTestCommon) createDNSServerWithPtrRecord(isIPv6 bool) { pod := &v1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", @@ -345,7 +346,6 @@ func (t *dnsTestCommon) createDNSServerWithPtrRecord() { "-u", "root", "-k", "--log-facility", "-", - "--host-record=my.test,192.0.2.123", "-q", }, }, @@ -354,6 +354,16 @@ func (t *dnsTestCommon) createDNSServerWithPtrRecord() { }, } + if isIPv6 { + pod.Spec.Containers[0].Command = append( + pod.Spec.Containers[0].Command, + fmt.Sprintf("--host-record=my.test,2001:db8::29")) + } else { + pod.Spec.Containers[0].Command = append( + pod.Spec.Containers[0].Command, + fmt.Sprintf("--host-record=my.test,192.0.2.123")) + } + t.createDNSPodFromObj(pod) } @@ -434,7 +444,7 @@ func createDNSPod(namespace, wheezyProbeCmd, jessieProbeCmd, podHostName, servic return dnsPod } -func createProbeCommand(namesToResolve []string, hostEntries []string, ptrLookupIP string, fileNamePrefix, namespace string) (string, []string) { +func createProbeCommand(namesToResolve []string, hostEntries []string, ptrLookupIP string, fileNamePrefix, namespace, dnsDomain string) (string, []string) { fileNames := make([]string, 0, len(namesToResolve)*2) probeCmd := "for i in `seq 1 600`; do " for _, name := range namesToResolve { @@ -447,10 +457,10 @@ func createProbeCommand(namesToResolve []string, hostEntries []string, ptrLookup } fileName := fmt.Sprintf("%s_udp@%s", fileNamePrefix, name) fileNames = append(fileNames, fileName) - probeCmd += fmt.Sprintf(`test -n "$$(dig +notcp +noall +answer +search %s %s)" && echo OK > /results/%s;`, name, lookup, fileName) + probeCmd += fmt.Sprintf(`check="$$(dig +notcp +noall +answer +search %s %s)" && test -n "$$check" && echo OK > /results/%s;`, name, lookup, fileName) fileName = fmt.Sprintf("%s_tcp@%s", fileNamePrefix, name) fileNames = append(fileNames, fileName) - probeCmd += fmt.Sprintf(`test -n "$$(dig +tcp +noall +answer +search %s %s)" && echo OK > /results/%s;`, name, lookup, fileName) + probeCmd += fmt.Sprintf(`check="$$(dig +tcp +noall +answer +search %s %s)" && test -n "$$check" && echo OK > /results/%s;`, name, lookup, fileName) } for _, name := range hostEntries { @@ -461,9 +471,9 @@ func createProbeCommand(namesToResolve []string, hostEntries []string, ptrLookup podARecByUDPFileName := fmt.Sprintf("%s_udp@PodARecord", fileNamePrefix) podARecByTCPFileName := fmt.Sprintf("%s_tcp@PodARecord", fileNamePrefix) - probeCmd += fmt.Sprintf(`podARec=$$(hostname -i| awk -F. '{print $$1"-"$$2"-"$$3"-"$$4".%s.pod.cluster.local"}');`, namespace) - probeCmd += fmt.Sprintf(`test -n "$$(dig +notcp +noall +answer +search $${podARec} A)" && echo OK > /results/%s;`, podARecByUDPFileName) - probeCmd += fmt.Sprintf(`test -n "$$(dig +tcp +noall +answer +search $${podARec} A)" && echo OK > /results/%s;`, podARecByTCPFileName) + probeCmd += fmt.Sprintf(`podARec=$$(hostname -i| awk -F. '{print $$1"-"$$2"-"$$3"-"$$4".%s.pod.%s"}');`, namespace, dnsDomain) + probeCmd += fmt.Sprintf(`check="$$(dig +notcp +noall +answer +search $${podARec} A)" && test -n "$$check" && echo OK > /results/%s;`, podARecByUDPFileName) + probeCmd += fmt.Sprintf(`check="$$(dig +tcp +noall +answer +search $${podARec} A)" && test -n "$$check" && echo OK > /results/%s;`, podARecByTCPFileName) fileNames = append(fileNames, podARecByUDPFileName) fileNames = append(fileNames, podARecByTCPFileName) @@ -471,8 +481,8 @@ func createProbeCommand(namesToResolve []string, hostEntries []string, ptrLookup ptrLookup := fmt.Sprintf("%s.in-addr.arpa.", strings.Join(reverseArray(strings.Split(ptrLookupIP, ".")), ".")) ptrRecByUDPFileName := fmt.Sprintf("%s_udp@PTR", ptrLookupIP) ptrRecByTCPFileName := fmt.Sprintf("%s_tcp@PTR", ptrLookupIP) - probeCmd += fmt.Sprintf(`test -n "$$(dig +notcp +noall +answer +search %s PTR)" && echo OK > /results/%s;`, ptrLookup, ptrRecByUDPFileName) - probeCmd += fmt.Sprintf(`test -n "$$(dig +tcp +noall +answer +search %s PTR)" && echo OK > /results/%s;`, ptrLookup, ptrRecByTCPFileName) + probeCmd += fmt.Sprintf(`check="$$(dig +notcp +noall +answer +search %s PTR)" && test -n "$$check" && echo OK > /results/%s;`, ptrLookup, ptrRecByUDPFileName) + probeCmd += fmt.Sprintf(`check="$$(dig +tcp +noall +answer +search %s PTR)" && test -n "$$check" && echo OK > /results/%s;`, ptrLookup, ptrRecByTCPFileName) fileNames = append(fileNames, ptrRecByUDPFileName) fileNames = append(fileNames, ptrRecByTCPFileName) } diff --git a/test/e2e/network/dns_configmap.go b/test/e2e/network/dns_configmap.go index c4203821a4e2c..97dbd44b7ee4d 100644 --- a/test/e2e/network/dns_configmap.go +++ b/test/e2e/network/dns_configmap.go @@ -60,61 +60,54 @@ func (t *dnsFederationsConfigMapTest) run() { originalConfigMapData := t.fetchDNSConfigMapData() defer t.restoreDNSConfigMap(originalConfigMapData) - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) if t.name == "coredns" { t.labels = []string{"abc", "ghi"} - defaultConfig := map[string]string{ - "Corefile": `.:53 { - kubernetes cluster.local in-addr.arpa ip6.arpa { - pods insecure - upstream - fallthrough in-addr.arpa ip6.arpa - } - }`} - valid1 := map[string]string{ - "Corefile": `.:53 { - kubernetes cluster.local in-addr.arpa ip6.arpa { + "Corefile": fmt.Sprintf(`.:53 { + kubernetes %v in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } - federation cluster.local { + federation %v { abc def.com } proxy . /etc/resolv.conf - }`} + }`, framework.TestContext.ClusterDNSDomain, framework.TestContext.ClusterDNSDomain)} valid1m := map[string]string{t.labels[0]: "def.com"} valid2 := map[string]string{ - "Corefile": `:53 { - kubernetes cluster.local in-addr.arpa ip6.arpa { + "Corefile": fmt.Sprintf(`:53 { + kubernetes %v in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } - federation cluster.local { + federation %v { ghi xyz.com } proxy . /etc/resolv.conf - }`} + }`, framework.TestContext.ClusterDNSDomain, framework.TestContext.ClusterDNSDomain)} valid2m := map[string]string{t.labels[1]: "xyz.com"} By("default -> valid1") t.setConfigMap(&v1.ConfigMap{Data: valid1}, valid1m, true) t.deleteCoreDNSPods() - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) By("valid1 -> valid2") t.setConfigMap(&v1.ConfigMap{Data: valid2}, valid2m, true) t.deleteCoreDNSPods() - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) By("valid2 -> default") - t.setConfigMap(&v1.ConfigMap{Data: defaultConfig}, nil, false) + t.setConfigMap(&v1.ConfigMap{Data: originalConfigMapData}, nil, false) t.deleteCoreDNSPods() - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) + + t.restoreDNSConfigMap(originalConfigMapData) } else { t.labels = []string{"abc", "ghi"} @@ -126,39 +119,39 @@ func (t *dnsFederationsConfigMapTest) run() { By("empty -> valid1") t.setConfigMap(&v1.ConfigMap{Data: valid1}, valid1m, true) - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) By("valid1 -> valid2") t.setConfigMap(&v1.ConfigMap{Data: valid2}, valid2m, true) - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) By("valid2 -> invalid") t.setConfigMap(&v1.ConfigMap{Data: invalid}, nil, false) - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) By("invalid -> valid1") t.setConfigMap(&v1.ConfigMap{Data: valid1}, valid1m, true) - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) By("valid1 -> deleted") t.deleteConfigMap() - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) By("deleted -> invalid") t.setConfigMap(&v1.ConfigMap{Data: invalid}, nil, false) - t.validate() + t.validate(framework.TestContext.ClusterDNSDomain) } } -func (t *dnsFederationsConfigMapTest) validate() { +func (t *dnsFederationsConfigMapTest) validate(dnsDomain string) { federations := t.fedMap if len(federations) == 0 { By(fmt.Sprintf("Validating federation labels %v do not exist", t.labels)) for _, label := range t.labels { - var federationDNS = fmt.Sprintf("e2e-dns-configmap.%s.%s.svc.cluster.local.", - t.f.Namespace.Name, label) + var federationDNS = fmt.Sprintf("e2e-dns-configmap.%s.%s.svc.%s.", + t.f.Namespace.Name, label, framework.TestContext.ClusterDNSDomain) predicate := func(actual []string) bool { return len(actual) == 0 } @@ -166,10 +159,10 @@ func (t *dnsFederationsConfigMapTest) validate() { } } else { for label := range federations { - var federationDNS = fmt.Sprintf("%s.%s.%s.svc.cluster.local.", - t.utilService.ObjectMeta.Name, t.f.Namespace.Name, label) - var localDNS = fmt.Sprintf("%s.%s.svc.cluster.local.", - t.utilService.ObjectMeta.Name, t.f.Namespace.Name) + var federationDNS = fmt.Sprintf("%s.%s.%s.svc.%s.", + t.utilService.ObjectMeta.Name, t.f.Namespace.Name, label, framework.TestContext.ClusterDNSDomain) + var localDNS = fmt.Sprintf("%s.%s.svc.%s.", + t.utilService.ObjectMeta.Name, t.f.Namespace.Name, framework.TestContext.ClusterDNSDomain) if t.name == "coredns" { localDNS = t.utilService.Spec.ClusterIP } @@ -209,7 +202,7 @@ type dnsNameserverTest struct { dnsTestCommon } -func (t *dnsNameserverTest) run() { +func (t *dnsNameserverTest) run(isIPv6 bool) { t.init() t.createUtilPodLabel("e2e-dns-configmap") @@ -217,17 +210,25 @@ func (t *dnsNameserverTest) run() { originalConfigMapData := t.fetchDNSConfigMapData() defer t.restoreDNSConfigMap(originalConfigMapData) - t.createDNSServer(map[string]string{ - "abc.acme.local": "1.1.1.1", - "def.acme.local": "2.2.2.2", - "widget.local": "3.3.3.3", - }) + if isIPv6 { + t.createDNSServer(map[string]string{ + "abc.acme.local": "2606:4700:4700::1111", + "def.acme.local": "2606:4700:4700::2222", + "widget.local": "2606:4700:4700::3333", + }) + } else { + t.createDNSServer(map[string]string{ + "abc.acme.local": "1.1.1.1", + "def.acme.local": "2.2.2.2", + "widget.local": "3.3.3.3", + }) + } defer t.deleteDNSServerPod() if t.name == "coredns" { t.setConfigMap(&v1.ConfigMap{Data: map[string]string{ "Corefile": fmt.Sprintf(`.:53 { - kubernetes cluster.local in-addr.arpa ip6.arpa { + kubernetes %v in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa @@ -236,7 +237,7 @@ func (t *dnsNameserverTest) run() { } acme.local:53 { proxy . %v - }`, t.dnsServerPod.Status.PodIP, t.dnsServerPod.Status.PodIP), + }`, framework.TestContext.ClusterDNSDomain, t.dnsServerPod.Status.PodIP, t.dnsServerPod.Status.PodIP), }}) t.deleteCoreDNSPods() @@ -247,21 +248,39 @@ func (t *dnsNameserverTest) run() { }}) } - t.checkDNSRecordFrom( - "abc.acme.local", - func(actual []string) bool { return len(actual) == 1 && actual[0] == "1.1.1.1" }, - "cluster-dns", - moreForeverTestTimeout) - t.checkDNSRecordFrom( - "def.acme.local", - func(actual []string) bool { return len(actual) == 1 && actual[0] == "2.2.2.2" }, - "cluster-dns", - moreForeverTestTimeout) - t.checkDNSRecordFrom( - "widget.local", - func(actual []string) bool { return len(actual) == 1 && actual[0] == "3.3.3.3" }, - "cluster-dns", - moreForeverTestTimeout) + if isIPv6 { + t.checkDNSRecordFrom( + "abc.acme.local", + func(actual []string) bool { return len(actual) == 1 && actual[0] == "2606:4700:4700::1111" }, + "cluster-dns-ipv6", + moreForeverTestTimeout) + t.checkDNSRecordFrom( + "def.acme.local", + func(actual []string) bool { return len(actual) == 1 && actual[0] == "2606:4700:4700::2222" }, + "cluster-dns-ipv6", + moreForeverTestTimeout) + t.checkDNSRecordFrom( + "widget.local", + func(actual []string) bool { return len(actual) == 1 && actual[0] == "2606:4700:4700::3333" }, + "cluster-dns-ipv6", + moreForeverTestTimeout) + } else { + t.checkDNSRecordFrom( + "abc.acme.local", + func(actual []string) bool { return len(actual) == 1 && actual[0] == "1.1.1.1" }, + "cluster-dns", + moreForeverTestTimeout) + t.checkDNSRecordFrom( + "def.acme.local", + func(actual []string) bool { return len(actual) == 1 && actual[0] == "2.2.2.2" }, + "cluster-dns", + moreForeverTestTimeout) + t.checkDNSRecordFrom( + "widget.local", + func(actual []string) bool { return len(actual) == 1 && actual[0] == "3.3.3.3" }, + "cluster-dns", + moreForeverTestTimeout) + } t.restoreDNSConfigMap(originalConfigMapData) // Wait for the deleted ConfigMap to take effect, otherwise the @@ -277,7 +296,7 @@ type dnsPtrFwdTest struct { dnsTestCommon } -func (t *dnsPtrFwdTest) run() { +func (t *dnsPtrFwdTest) run(isIPv6 bool) { t.init() t.createUtilPodLabel("e2e-dns-configmap") @@ -285,26 +304,34 @@ func (t *dnsPtrFwdTest) run() { originalConfigMapData := t.fetchDNSConfigMapData() defer t.restoreDNSConfigMap(originalConfigMapData) - t.createDNSServerWithPtrRecord() + t.createDNSServerWithPtrRecord(isIPv6) defer t.deleteDNSServerPod() // Should still be able to lookup public nameserver without explicit upstream nameserver set. - t.checkDNSRecordFrom( - "8.8.8.8.in-addr.arpa", - func(actual []string) bool { return len(actual) == 1 && actual[0] == googleDnsHostname+"." }, - "cluster-dns", - moreForeverTestTimeout) + if isIPv6 { + t.checkDNSRecordFrom( + "2001:4860:4860::8888", + func(actual []string) bool { return len(actual) == 1 && actual[0] == googleDnsHostname+"." }, + "ptr-record", + moreForeverTestTimeout) + } else { + t.checkDNSRecordFrom( + "8.8.8.8", + func(actual []string) bool { return len(actual) == 1 && actual[0] == googleDnsHostname+"." }, + "ptr-record", + moreForeverTestTimeout) + } if t.name == "coredns" { t.setConfigMap(&v1.ConfigMap{Data: map[string]string{ "Corefile": fmt.Sprintf(`.:53 { - kubernetes cluster.local in-addr.arpa ip6.arpa { + kubernetes %v in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } proxy . %v - }`, t.dnsServerPod.Status.PodIP), + }`, framework.TestContext.ClusterDNSDomain, t.dnsServerPod.Status.PodIP), }}) t.deleteCoreDNSPods() @@ -314,25 +341,41 @@ func (t *dnsPtrFwdTest) run() { }}) } - t.checkDNSRecordFrom( - "123.2.0.192.in-addr.arpa", - func(actual []string) bool { return len(actual) == 1 && actual[0] == "my.test." }, - "cluster-dns", - moreForeverTestTimeout) + if isIPv6 { + t.checkDNSRecordFrom( + "2001:db8::29", + func(actual []string) bool { return len(actual) == 1 && actual[0] == "my.test." }, + "ptr-record", + moreForeverTestTimeout) - t.restoreDNSConfigMap(originalConfigMapData) - t.checkDNSRecordFrom( - "123.2.0.192.in-addr.arpa", - func(actual []string) bool { return len(actual) == 0 }, - "cluster-dns", - moreForeverTestTimeout) + t.restoreDNSConfigMap(originalConfigMapData) + t.checkDNSRecordFrom( + "2001:db8::29", + func(actual []string) bool { return len(actual) == 0 }, + "ptr-record", + moreForeverTestTimeout) + + } else { + t.checkDNSRecordFrom( + "192.0.2.123", + func(actual []string) bool { return len(actual) == 1 && actual[0] == "my.test." }, + "ptr-record", + moreForeverTestTimeout) + + t.restoreDNSConfigMap(originalConfigMapData) + t.checkDNSRecordFrom( + "192.0.2.123", + func(actual []string) bool { return len(actual) == 0 }, + "ptr-record", + moreForeverTestTimeout) + } } type dnsExternalNameTest struct { dnsTestCommon } -func (t *dnsExternalNameTest) run() { +func (t *dnsExternalNameTest) run(isIPv6 bool) { t.init() t.createUtilPodLabel("e2e-dns-configmap") @@ -341,9 +384,15 @@ func (t *dnsExternalNameTest) run() { defer t.restoreDNSConfigMap(originalConfigMapData) fooHostname := "foo.example.com" - t.createDNSServer(map[string]string{ - fooHostname: "192.0.2.123", - }) + if isIPv6 { + t.createDNSServer(map[string]string{ + fooHostname: "2001:db8::29", + }) + } else { + t.createDNSServer(map[string]string{ + fooHostname: "192.0.2.123", + }) + } defer t.deleteDNSServerPod() f := t.f @@ -364,24 +413,34 @@ func (t *dnsExternalNameTest) run() { f.ClientSet.CoreV1().Services(f.Namespace.Name).Delete(externalNameServiceLocal.Name, nil) }() - t.checkDNSRecordFrom( - fmt.Sprintf("%s.%s.svc.cluster.local", serviceName, f.Namespace.Name), - func(actual []string) bool { - return len(actual) >= 1 && actual[0] == googleDnsHostname+"." - }, - "cluster-dns", - moreForeverTestTimeout) + if isIPv6 { + t.checkDNSRecordFrom( + fmt.Sprintf("%s.%s.svc.%s", serviceName, f.Namespace.Name, framework.TestContext.ClusterDNSDomain), + func(actual []string) bool { + return len(actual) >= 1 && actual[0] == googleDnsHostname+"." + }, + "cluster-dns-ipv6", + moreForeverTestTimeout) + } else { + t.checkDNSRecordFrom( + fmt.Sprintf("%s.%s.svc.%s", serviceName, f.Namespace.Name, framework.TestContext.ClusterDNSDomain), + func(actual []string) bool { + return len(actual) >= 1 && actual[0] == googleDnsHostname+"." + }, + "cluster-dns", + moreForeverTestTimeout) + } if t.name == "coredns" { t.setConfigMap(&v1.ConfigMap{Data: map[string]string{ "Corefile": fmt.Sprintf(`.:53 { - kubernetes cluster.local in-addr.arpa ip6.arpa { + kubernetes %v in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } proxy . %v - }`, t.dnsServerPod.Status.PodIP), + }`, framework.TestContext.ClusterDNSDomain, t.dnsServerPod.Status.PodIP), }}) t.deleteCoreDNSPods() @@ -390,26 +449,65 @@ func (t *dnsExternalNameTest) run() { "upstreamNameservers": fmt.Sprintf(`["%v"]`, t.dnsServerPod.Status.PodIP), }}) } - - t.checkDNSRecordFrom( - fmt.Sprintf("%s.%s.svc.cluster.local", serviceNameLocal, f.Namespace.Name), - func(actual []string) bool { - return len(actual) == 2 && actual[0] == fooHostname+"." && actual[1] == "192.0.2.123" - }, - "cluster-dns", - moreForeverTestTimeout) + if isIPv6 { + t.checkDNSRecordFrom( + fmt.Sprintf("%s.%s.svc.%s", serviceNameLocal, f.Namespace.Name, framework.TestContext.ClusterDNSDomain), + func(actual []string) bool { + return len(actual) >= 1 && actual[0] == fooHostname+"." && actual[1] == "2001:db8::29" + }, + "cluster-dns-ipv6", + moreForeverTestTimeout) + } else { + t.checkDNSRecordFrom( + fmt.Sprintf("%s.%s.svc.%s", serviceNameLocal, f.Namespace.Name, framework.TestContext.ClusterDNSDomain), + func(actual []string) bool { + return len(actual) == 2 && actual[0] == fooHostname+"." && actual[1] == "192.0.2.123" + }, + "cluster-dns", + moreForeverTestTimeout) + } t.restoreDNSConfigMap(originalConfigMapData) } -var _ = SIGDescribe("DNS configMap nameserver", func() { +var _ = SIGDescribe("DNS configMap nameserver [IPv4]", func() { + + Context("Change stubDomain", func() { + nsTest := &dnsNameserverTest{dnsTestCommon: newDnsTestCommon()} + + It("should be able to change stubDomain configuration [Slow][Serial]", func() { + nsTest.c = nsTest.f.ClientSet + nsTest.run(false) + }) + }) + + Context("Forward PTR lookup", func() { + fwdTest := &dnsPtrFwdTest{dnsTestCommon: newDnsTestCommon()} + + It("should forward PTR records lookup to upstream nameserver [Slow][Serial]", func() { + fwdTest.c = fwdTest.f.ClientSet + fwdTest.run(false) + }) + }) + + Context("Forward external name lookup", func() { + externalNameTest := &dnsExternalNameTest{dnsTestCommon: newDnsTestCommon()} + + 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]", func() { Context("Change stubDomain", func() { nsTest := &dnsNameserverTest{dnsTestCommon: newDnsTestCommon()} It("should be able to change stubDomain configuration [Slow][Serial]", func() { nsTest.c = nsTest.f.ClientSet - nsTest.run() + nsTest.run(true) }) }) @@ -418,7 +516,7 @@ var _ = SIGDescribe("DNS configMap nameserver", func() { It("should forward PTR records lookup to upstream nameserver [Slow][Serial]", func() { fwdTest.c = fwdTest.f.ClientSet - fwdTest.run() + fwdTest.run(true) }) }) @@ -427,7 +525,7 @@ var _ = SIGDescribe("DNS configMap nameserver", func() { It("should forward externalname lookup to upstream nameserver [Slow][Serial]", func() { externalNameTest.c = externalNameTest.f.ClientSet - externalNameTest.run() + externalNameTest.run(true) }) }) }) diff --git a/test/e2e/network/dns_scale_records.go b/test/e2e/network/dns_scale_records.go index 2d9aca03a4c18..12718970eb65f 100644 --- a/test/e2e/network/dns_scale_records.go +++ b/test/e2e/network/dns_scale_records.go @@ -83,7 +83,7 @@ var _ = SIGDescribe("[Feature:PerformanceDNS][Serial]", func() { s := services[i] svc, err := f.ClientSet.CoreV1().Services(s.Namespace).Get(s.Name, metav1.GetOptions{}) framework.ExpectNoError(err) - qname := fmt.Sprintf("%v.%v.svc.cluster.local", s.Name, s.Namespace) + qname := fmt.Sprintf("%v.%v.svc.%v", s.Name, s.Namespace, framework.TestContext.ClusterDNSDomain) framework.Logf("Querying %v expecting %v", qname, svc.Spec.ClusterIP) dnsTest.checkDNSRecordFrom( qname, diff --git a/test/e2e/network/example_cluster_dns.go b/test/e2e/network/example_cluster_dns.go index 9bbaa824b27bb..ee0fe420ab8bb 100644 --- a/test/e2e/network/example_cluster_dns.go +++ b/test/e2e/network/example_cluster_dns.go @@ -135,7 +135,7 @@ var _ = SIGDescribe("ClusterDns [Feature:Example]", func() { _, err = framework.LookForStringInPodExec(namespaces[0].Name, podName, []string{"python", "-c", queryDns}, "ok", dnsReadyTimeout) Expect(err).NotTo(HaveOccurred(), "waiting for output from pod exec") - updatedPodYaml := prepareResourceWithReplacedString(frontendPodYaml, "dns-backend.development.svc.cluster.local", fmt.Sprintf("dns-backend.%s.svc.cluster.local", namespaces[0].Name)) + updatedPodYaml := prepareResourceWithReplacedString(frontendPodYaml, fmt.Sprintf("dns-backend.development.svc.%s", framework.TestContext.ClusterDNSDomain), fmt.Sprintf("dns-backend.%s.svc.%s", namespaces[0].Name, framework.TestContext.ClusterDNSDomain)) // create a pod in each namespace for _, ns := range namespaces { diff --git a/test/e2e/network/firewall.go b/test/e2e/network/firewall.go index 89b6b03210427..d46ff96c35210 100644 --- a/test/e2e/network/firewall.go +++ b/test/e2e/network/firewall.go @@ -18,6 +18,7 @@ package network import ( "fmt" + "time" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" @@ -39,7 +40,7 @@ var _ = SIGDescribe("Firewall rule", func() { var cs clientset.Interface var cloudConfig framework.CloudConfig - var gceCloud *gcecloud.GCECloud + var gceCloud *gcecloud.Cloud BeforeEach(func() { framework.SkipUnlessProviderIs("gce") @@ -172,17 +173,27 @@ var _ = SIGDescribe("Firewall rule", func() { By("Checking well known ports on master and nodes are not exposed externally") nodeAddrs := framework.NodeAddresses(nodes, v1.NodeExternalIP) - Expect(len(nodeAddrs)).NotTo(BeZero()) - masterAddr := framework.GetMasterAddress(cs) - flag, _ := framework.TestNotReachableHTTPTimeout(masterAddr, ports.InsecureKubeControllerManagerPort, gce.FirewallTestTcpTimeout) - Expect(flag).To(BeTrue()) - flag, _ = framework.TestNotReachableHTTPTimeout(masterAddr, ports.SchedulerPort, gce.FirewallTestTcpTimeout) - Expect(flag).To(BeTrue()) - flag, _ = framework.TestNotReachableHTTPTimeout(nodeAddrs[0], ports.KubeletPort, gce.FirewallTestTcpTimeout) - Expect(flag).To(BeTrue()) - flag, _ = framework.TestNotReachableHTTPTimeout(nodeAddrs[0], ports.KubeletReadOnlyPort, gce.FirewallTestTcpTimeout) - Expect(flag).To(BeTrue()) - flag, _ = framework.TestNotReachableHTTPTimeout(nodeAddrs[0], ports.ProxyStatusPort, gce.FirewallTestTcpTimeout) - Expect(flag).To(BeTrue()) + if len(nodeAddrs) == 0 { + framework.Failf("did not find any node addresses") + } + + masterAddresses := framework.GetAllMasterAddresses(cs) + for _, masterAddress := range masterAddresses { + assertNotReachableHTTPTimeout(masterAddress, ports.InsecureKubeControllerManagerPort, gce.FirewallTestTcpTimeout) + assertNotReachableHTTPTimeout(masterAddress, ports.SchedulerPort, gce.FirewallTestTcpTimeout) + } + assertNotReachableHTTPTimeout(nodeAddrs[0], ports.KubeletPort, gce.FirewallTestTcpTimeout) + assertNotReachableHTTPTimeout(nodeAddrs[0], ports.KubeletReadOnlyPort, gce.FirewallTestTcpTimeout) + assertNotReachableHTTPTimeout(nodeAddrs[0], ports.ProxyStatusPort, gce.FirewallTestTcpTimeout) }) }) + +func assertNotReachableHTTPTimeout(ip string, port int, timeout time.Duration) { + unreachable, err := framework.TestNotReachableHTTPTimeout(ip, port, timeout) + if err != nil { + framework.Failf("Unexpected error checking for reachability of %s:%d: %v", ip, port, err) + } + if !unreachable { + framework.Failf("Was unexpectedly able to reach %s:%d", ip, port) + } +} diff --git a/test/e2e/network/ingress.go b/test/e2e/network/ingress.go index 7d2aa8f1cdc1a..c7377ecd5970a 100644 --- a/test/e2e/network/ingress.go +++ b/test/e2e/network/ingress.go @@ -26,6 +26,7 @@ import ( compute "google.golang.org/api/compute/v1" + "k8s.io/api/core/v1" extensions "k8s.io/api/extensions/v1beta1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" "k8s.io/apimachinery/pkg/api/errors" @@ -733,6 +734,61 @@ var _ = SIGDescribe("Loadbalancing: L7", func() { By("Scale down number of backends to 2") scaleAndValidateExposedNEG(3) }) + + It("should create NEGs for all ports with the Ingress annotation, and NEGs for the standalone annotation otherwise", func() { + By("Create a basic HTTP ingress using standalone NEG") + jig.CreateIngress(filepath.Join(ingress.IngressManifestPath, "neg-exposed"), ns, map[string]string{}, map[string]string{}) + jig.WaitForIngress(true) + + name := "hostname" + detectNegAnnotation(f, jig, gceController, ns, name, 2) + + // Add Ingress annotation - NEGs should stay the same. + By("Adding NEG Ingress annotation") + svcList, err := f.ClientSet.CoreV1().Services(ns).List(metav1.ListOptions{}) + Expect(err).NotTo(HaveOccurred()) + for _, svc := range svcList.Items { + svc.Annotations[ingress.NEGAnnotation] = `{"ingress":true,"exposed_ports":{"80":{},"443":{}}}` + _, err = f.ClientSet.CoreV1().Services(ns).Update(&svc) + Expect(err).NotTo(HaveOccurred()) + } + detectNegAnnotation(f, jig, gceController, ns, name, 2) + + // Modify exposed NEG annotation, but keep ingress annotation + By("Modifying exposed NEG annotation, but keep Ingress annotation") + svcList, err = f.ClientSet.CoreV1().Services(ns).List(metav1.ListOptions{}) + Expect(err).NotTo(HaveOccurred()) + for _, svc := range svcList.Items { + svc.Annotations[ingress.NEGAnnotation] = `{"ingress":true,"exposed_ports":{"443":{}}}` + _, err = f.ClientSet.CoreV1().Services(ns).Update(&svc) + Expect(err).NotTo(HaveOccurred()) + } + detectNegAnnotation(f, jig, gceController, ns, name, 2) + + // Remove Ingress annotation. Expect 1 NEG + By("Disabling Ingress annotation, but keeping one standalone NEG") + svcList, err = f.ClientSet.CoreV1().Services(ns).List(metav1.ListOptions{}) + Expect(err).NotTo(HaveOccurred()) + for _, svc := range svcList.Items { + svc.Annotations[ingress.NEGAnnotation] = `{"ingress":false,"exposed_ports":{"443":{}}}` + _, err = f.ClientSet.CoreV1().Services(ns).Update(&svc) + Expect(err).NotTo(HaveOccurred()) + } + detectNegAnnotation(f, jig, gceController, ns, name, 1) + + // Remove NEG annotation entirely. Expect 0 NEGs. + By("Removing NEG annotation") + svcList, err = f.ClientSet.CoreV1().Services(ns).List(metav1.ListOptions{}) + Expect(err).NotTo(HaveOccurred()) + for _, svc := range svcList.Items { + delete(svc.Annotations, ingress.NEGAnnotation) + // Service cannot be ClusterIP if it's using Instance Groups. + svc.Spec.Type = v1.ServiceTypeNodePort + _, err = f.ClientSet.CoreV1().Services(ns).Update(&svc) + Expect(err).NotTo(HaveOccurred()) + } + detectNegAnnotation(f, jig, gceController, ns, name, 0) + }) }) Describe("GCE [Slow] [Feature:kubemci]", func() { @@ -1044,3 +1100,49 @@ func detectHttpVersionAndSchemeTest(f *framework.Framework, jig *ingress.Ingress }) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Failed to get %s or %s, response body: %s", version, scheme, resp)) } + +func detectNegAnnotation(f *framework.Framework, jig *ingress.IngressTestJig, gceController *gce.GCEIngressController, ns, name string, negs int) { + wait.Poll(5*time.Second, framework.LoadBalancerPollTimeout, func() (bool, error) { + svc, err := f.ClientSet.CoreV1().Services(ns).Get(name, metav1.GetOptions{}) + if err != nil { + return false, nil + } + + // if we expect no NEGs, then we should be using IGs + if negs == 0 { + return gceController.BackendServiceUsingIG(jig.GetServicePorts(false)) + } + + var status ingress.NegStatus + v, ok := svc.Annotations[ingress.NEGStatusAnnotation] + if !ok { + framework.Logf("Waiting for %v, got: %+v", ingress.NEGStatusAnnotation, svc.Annotations) + return false, nil + } + + err = json.Unmarshal([]byte(v), &status) + if err != nil { + framework.Logf("Error in parsing Expose NEG annotation: %v", err) + return false, nil + } + framework.Logf("Got %v: %v", ingress.NEGStatusAnnotation, v) + + if len(status.NetworkEndpointGroups) != negs { + framework.Logf("Expected %d NEGs, got %d", negs, len(status.NetworkEndpointGroups)) + return false, nil + } + + gceCloud, err := gce.GetGCECloud() + Expect(err).NotTo(HaveOccurred()) + for _, neg := range status.NetworkEndpointGroups { + networkEndpoints, err := gceCloud.ListNetworkEndpoints(neg, gceController.Cloud.Zone, false) + Expect(err).NotTo(HaveOccurred()) + if len(networkEndpoints) != 1 { + framework.Logf("Expect NEG %s to exist, but got %d", neg, len(networkEndpoints)) + return false, nil + } + } + + return gceController.BackendServiceUsingNEG(jig.GetServicePorts(false)) + }) +} diff --git a/test/e2e/network/network_tiers.go b/test/e2e/network/network_tiers.go index 3cad210e9c10e..c102d52e3d309 100644 --- a/test/e2e/network/network_tiers.go +++ b/test/e2e/network/network_tiers.go @@ -222,7 +222,7 @@ func clearNetworkTier(svc *v1.Service) { // TODO: add retries if this turns out to be flaky. // TODO(#51665): remove this helper function once Network Tiers becomes beta. -func reserveAlphaRegionalAddress(cloud *gcecloud.GCECloud, name string, netTier cloud.NetworkTier) (string, error) { +func reserveAlphaRegionalAddress(cloud *gcecloud.Cloud, name string, netTier cloud.NetworkTier) (string, error) { alphaAddr := &computealpha.Address{ Name: name, NetworkTier: netTier.ToGCEValue(), diff --git a/test/e2e/network/service.go b/test/e2e/network/service.go index 6e92643f91fc0..a1b85257b8add 100644 --- a/test/e2e/network/service.go +++ b/test/e2e/network/service.go @@ -35,6 +35,7 @@ import ( clientset "k8s.io/client-go/kubernetes" cloudprovider "k8s.io/cloud-provider" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" "k8s.io/kubernetes/pkg/controller/endpoint" "k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework/providers/gce" @@ -1273,7 +1274,7 @@ var _ = SIGDescribe("Services", func() { By("Verifying pods for RC " + t.Name) framework.ExpectNoError(framework.VerifyPods(t.Client, t.Namespace, t.Name, false, 1)) - svcName := fmt.Sprintf("%v.%v.svc.cluster.local", serviceName, f.Namespace.Name) + svcName := fmt.Sprintf("%v.%v.svc.%v", serviceName, f.Namespace.Name, framework.TestContext.ClusterDNSDomain) By("Waiting for endpoints of Service with DNS name " + svcName) execPodName := framework.CreateExecPodOrFail(f.ClientSet, f.Namespace.Name, "execpod-", nil) @@ -1546,6 +1547,79 @@ var _ = SIGDescribe("Services", func() { jig.ChangeServiceType(svc.Namespace, svc.Name, v1.ServiceTypeClusterIP, createTimeout) }) + // This test creates a load balancer, make sure its health check interval + // equals to gceHcCheckIntervalSeconds. Then the interval is manipulated + // to be something else, see if the interval will be reconciled. + It("should reconcile LB health check interval [Slow][Serial]", func() { + const gceHcCheckIntervalSeconds = int64(8) + // This test is for clusters on GCE. + // (It restarts kube-controller-manager, which we don't support on GKE) + framework.SkipUnlessProviderIs("gce") + clusterID, err := gce.GetClusterID(cs) + if err != nil { + framework.Failf("framework.GetClusterID(cs) = _, %v; want nil", err) + } + gceCloud, err := gce.GetGCECloud() + if err != nil { + framework.Failf("framework.GetGCECloud() = _, %v; want nil", err) + } + + namespace := f.Namespace.Name + serviceName := "lb-hc-int" + jig := framework.NewServiceTestJig(cs, serviceName) + + By("create load balancer service") + // Create loadbalancer service with source range from node[0] and podAccept + svc := jig.CreateTCPServiceOrFail(namespace, func(svc *v1.Service) { + svc.Spec.Type = v1.ServiceTypeLoadBalancer + }) + + // Clean up loadbalancer service + defer func() { + jig.UpdateServiceOrFail(svc.Namespace, svc.Name, func(svc *v1.Service) { + svc.Spec.Type = v1.ServiceTypeNodePort + }) + Expect(cs.CoreV1().Services(svc.Namespace).Delete(svc.Name, nil)).NotTo(HaveOccurred()) + }() + + svc = jig.WaitForLoadBalancerOrFail(namespace, serviceName, framework.LoadBalancerCreateTimeoutDefault) + + hcName := gcecloud.MakeNodesHealthCheckName(clusterID) + hc, err := gceCloud.GetHTTPHealthCheck(hcName) + if err != nil { + framework.Failf("gceCloud.GetHttpHealthCheck(%q) = _, %v; want nil", hcName, err) + } + Expect(hc.CheckIntervalSec).To(Equal(gceHcCheckIntervalSeconds)) + + By("modify the health check interval") + hc.CheckIntervalSec = gceHcCheckIntervalSeconds - 1 + if err = gceCloud.UpdateHTTPHealthCheck(hc); err != nil { + framework.Failf("gcecloud.UpdateHttpHealthCheck(%#v) = %v; want nil", hc, err) + } + + By("restart kube-controller-manager") + if err := framework.RestartControllerManager(); err != nil { + framework.Failf("framework.RestartControllerManager() = %v; want nil", err) + } + if err := framework.WaitForControllerManagerUp(); err != nil { + framework.Failf("framework.WaitForControllerManagerUp() = %v; want nil", err) + } + + By("health check should be reconciled") + pollInterval := framework.Poll * 10 + if pollErr := wait.PollImmediate(pollInterval, framework.LoadBalancerCreateTimeoutDefault, func() (bool, error) { + hc, err := gceCloud.GetHTTPHealthCheck(hcName) + if err != nil { + framework.Logf("Failed to get HttpHealthCheck(%q): %v", hcName, err) + return false, err + } + framework.Logf("hc.CheckIntervalSec = %v", hc.CheckIntervalSec) + return hc.CheckIntervalSec == gceHcCheckIntervalSeconds, nil + }); pollErr != nil { + framework.Failf("Health check %q does not reconcile its check interval to %d.", hcName, gceHcCheckIntervalSeconds) + } + }) + It("should have session affinity work for service with type clusterIP", func() { svc := getServeHostnameService("service") svc.Spec.Type = v1.ServiceTypeClusterIP diff --git a/test/e2e/node/BUILD b/test/e2e/node/BUILD index fc4181f76d28f..d5eaeb127dbca 100644 --- a/test/e2e/node/BUILD +++ b/test/e2e/node/BUILD @@ -13,6 +13,7 @@ go_library( "pod_gc.go", "pods.go", "pre_stop.go", + "runtimeclass.go", "security_context.go", "ssh.go", ], @@ -20,11 +21,15 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", + "//pkg/kubelet/events:go_default_library", + "//pkg/kubelet/runtimeclass/testing:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//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/runtime/schema: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/wait:go_default_library", @@ -36,6 +41,7 @@ go_library( "//test/utils/image: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/test/e2e/node/runtimeclass.go b/test/e2e/node/runtimeclass.go new file mode 100644 index 0000000000000..692966aa504fc --- /dev/null +++ b/test/e2e/node/runtimeclass.go @@ -0,0 +1,188 @@ +/* +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 node + +import ( + "fmt" + "time" + + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/kubernetes/pkg/kubelet/events" + runtimeclasstest "k8s.io/kubernetes/pkg/kubelet/runtimeclass/testing" + "k8s.io/kubernetes/test/e2e/framework" + imageutils "k8s.io/kubernetes/test/utils/image" + utilpointer "k8s.io/utils/pointer" + + . "github.com/onsi/ginkgo" +) + +const runtimeClassCRDName = "runtimeclasses.node.k8s.io" + +var ( + runtimeClassGVR = schema.GroupVersionResource{ + Group: "node.k8s.io", + Version: "v1alpha1", + Resource: "runtimeclasses", + } +) + +var _ = SIGDescribe("RuntimeClass [Feature:RuntimeClass]", func() { + f := framework.NewDefaultFramework("runtimeclass") + + It("should reject a Pod requesting a non-existent RuntimeClass", func() { + rcName := f.Namespace.Name + "-nonexistent" + pod := createRuntimeClassPod(f, rcName) + expectSandboxFailureEvent(f, pod, fmt.Sprintf("\"%s\" not found", rcName)) + }) + + It("should run a Pod requesting a RuntimeClass with an empty handler", func() { + rcName := createRuntimeClass(f, "empty-handler", "") + pod := createRuntimeClassPod(f, rcName) + expectPodSuccess(f, pod) + }) + + It("should reject a Pod requesting a RuntimeClass with an unconfigured handler", func() { + handler := f.Namespace.Name + "-handler" + rcName := createRuntimeClass(f, "unconfigured-handler", handler) + pod := createRuntimeClassPod(f, rcName) + expectSandboxFailureEvent(f, pod, handler) + }) + + It("should reject a Pod requesting a deleted RuntimeClass", func() { + rcName := createRuntimeClass(f, "delete-me", "") + + By("Deleting RuntimeClass "+rcName, func() { + err := f.DynamicClient.Resource(runtimeClassGVR).Delete(rcName, nil) + framework.ExpectNoError(err, "failed to delete RuntimeClass %s", rcName) + + By("Waiting for the RuntimeClass to disappear") + framework.ExpectNoError(wait.PollImmediate(framework.Poll, time.Minute, func() (bool, error) { + _, err := f.DynamicClient.Resource(runtimeClassGVR).Get(rcName, metav1.GetOptions{}) + if errors.IsNotFound(err) { + return true, nil // done + } + if err != nil { + return true, err // stop wait with error + } + return false, nil + })) + }) + + pod := createRuntimeClassPod(f, rcName) + expectSandboxFailureEvent(f, pod, fmt.Sprintf("\"%s\" not found", rcName)) + }) + + It("should recover when the RuntimeClass CRD is deleted [Slow]", func() { + By("Deleting the RuntimeClass CRD", func() { + crds := f.APIExtensionsClientSet.ApiextensionsV1beta1().CustomResourceDefinitions() + runtimeClassCRD, err := crds.Get(runtimeClassCRDName, metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get RuntimeClass CRD %s", runtimeClassCRDName) + runtimeClassCRDUID := runtimeClassCRD.GetUID() + + err = crds.Delete(runtimeClassCRDName, nil) + framework.ExpectNoError(err, "failed to delete RuntimeClass CRD %s", runtimeClassCRDName) + + By("Waiting for the CRD to disappear") + framework.ExpectNoError(wait.PollImmediate(framework.Poll, time.Minute, func() (bool, error) { + crd, err := crds.Get(runtimeClassCRDName, metav1.GetOptions{}) + if errors.IsNotFound(err) { + return true, nil // done + } + if err != nil { + return true, err // stop wait with error + } + // If the UID changed, that means the addon manager has already recreated it. + return crd.GetUID() != runtimeClassCRDUID, nil + })) + + By("Waiting for the CRD to be recreated") + framework.ExpectNoError(wait.PollImmediate(framework.Poll, 5*time.Minute, func() (bool, error) { + crd, err := crds.Get(runtimeClassCRDName, metav1.GetOptions{}) + if errors.IsNotFound(err) { + return false, nil // still not recreated + } + if err != nil { + return true, err // stop wait with error + } + if crd.GetUID() == runtimeClassCRDUID { + return true, fmt.Errorf("RuntimeClass CRD never deleted") // this shouldn't happen + } + return true, nil + })) + }) + + rcName := createRuntimeClass(f, "valid", "") + pod := createRuntimeClassPod(f, rcName) + expectPodSuccess(f, pod) + }) + + // TODO(tallclair): Test an actual configured non-default runtimeHandler. +}) + +// createRuntimeClass generates a RuntimeClass with the desired handler and a "namespaced" name, +// synchronously creates it with the dynamic client, and returns the resulting name. +func createRuntimeClass(f *framework.Framework, name, handler string) string { + uniqueName := fmt.Sprintf("%s-%s", f.Namespace.Name, name) + rc := runtimeclasstest.NewUnstructuredRuntimeClass(uniqueName, handler) + rc, err := f.DynamicClient.Resource(runtimeClassGVR).Create(rc, metav1.CreateOptions{}) + framework.ExpectNoError(err, "failed to create RuntimeClass resource") + return rc.GetName() +} + +// createRuntimeClass creates a test pod with the given runtimeClassName. +func createRuntimeClassPod(f *framework.Framework, runtimeClassName string) *v1.Pod { + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: fmt.Sprintf("test-runtimeclass-%s-", runtimeClassName), + }, + Spec: v1.PodSpec{ + RuntimeClassName: &runtimeClassName, + Containers: []v1.Container{{ + Name: "test", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"true"}, + }}, + RestartPolicy: v1.RestartPolicyNever, + AutomountServiceAccountToken: utilpointer.BoolPtr(false), + }, + } + return f.PodClient().Create(pod) +} + +// expectPodSuccess waits for the given pod to terminate successfully. +func expectPodSuccess(f *framework.Framework, pod *v1.Pod) { + framework.ExpectNoError(framework.WaitForPodSuccessInNamespace( + f.ClientSet, pod.Name, f.Namespace.Name)) +} + +// expectSandboxFailureEvent polls for an event with reason "FailedCreatePodSandBox" containing the +// expected message string. +func expectSandboxFailureEvent(f *framework.Framework, pod *v1.Pod, msg string) { + eventSelector := fields.Set{ + "involvedObject.kind": "Pod", + "involvedObject.name": pod.Name, + "involvedObject.namespace": f.Namespace.Name, + "reason": events.FailedCreatePodSandBox, + }.AsSelector().String() + framework.ExpectNoError(framework.WaitTimeoutForPodEvent( + f.ClientSet, pod.Name, f.Namespace.Name, eventSelector, msg, framework.PodEventTimeout)) +} diff --git a/test/e2e/scalability/density.go b/test/e2e/scalability/density.go index 67d9a9235c752..4449d69dc2aa6 100644 --- a/test/e2e/scalability/density.go +++ b/test/e2e/scalability/density.go @@ -484,6 +484,18 @@ var _ = SIGDescribe("Density", func() { ns = f.Namespace.Name testPhaseDurations = timer.NewTestPhaseTimer() + // This is used to mimic what new service account token volumes will + // eventually look like. We can remove this once the controller manager + // publishes the root CA certificate to each namespace. + c.CoreV1().ConfigMaps(ns).Create(&v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kube-root-ca-crt", + }, + Data: map[string]string{ + "ca.crt": "trust me, i'm a ca.crt", + }, + }) + _, nodes = framework.GetMasterAndWorkerNodesOrDie(c) nodeCount = len(nodes.Items) Expect(nodeCount).NotTo(BeZero()) @@ -533,11 +545,12 @@ var _ = SIGDescribe("Density", func() { // Controls how often the apiserver is polled for pods interval time.Duration // What kind of resource we should be creating. Default: ReplicationController - kind schema.GroupKind - secretsPerPod int - configMapsPerPod int - daemonsPerNode int - quotas bool + kind schema.GroupKind + secretsPerPod int + configMapsPerPod int + svcacctTokenProjectionsPerPod int + daemonsPerNode int + quotas bool } densityTests := []Density{ @@ -556,6 +569,8 @@ var _ = SIGDescribe("Density", func() { {podsPerNode: 30, runLatencyTest: true, kind: extensions.Kind("Deployment"), secretsPerPod: 2}, // Test with configmaps {podsPerNode: 30, runLatencyTest: true, kind: extensions.Kind("Deployment"), configMapsPerPod: 2}, + // Test with service account projected volumes + {podsPerNode: 30, runLatencyTest: true, kind: extensions.Kind("Deployment"), svcacctTokenProjectionsPerPod: 2}, // Test with quotas {podsPerNode: 30, runLatencyTest: true, kind: api.Kind("ReplicationController"), quotas: true}, } @@ -575,12 +590,13 @@ var _ = SIGDescribe("Density", func() { feature = "HighDensityPerformance" } - name := fmt.Sprintf("[Feature:%s] should allow starting %d pods per node using %v with %v secrets, %v configmaps and %v daemons", + name := fmt.Sprintf("[Feature:%s] should allow starting %d pods per node using %v with %v secrets, %v configmaps, %v token projections, and %v daemons", feature, testArg.podsPerNode, testArg.kind, testArg.secretsPerPod, testArg.configMapsPerPod, + testArg.svcacctTokenProjectionsPerPod, testArg.daemonsPerNode, ) if testArg.quotas { @@ -653,24 +669,25 @@ var _ = SIGDescribe("Density", func() { } name := fmt.Sprintf("density%v-%v-%v", totalPods, i, uuid) baseConfig := &testutils.RCConfig{ - Client: clients[i], - InternalClient: internalClients[i], - ScalesGetter: scalesClients[i], - Image: imageutils.GetPauseImageName(), - Name: name, - Namespace: nsName, - Labels: map[string]string{"type": "densityPod"}, - PollInterval: DensityPollInterval, - Timeout: timeout, - PodStatusFile: fileHndl, - Replicas: (totalPods + numberOfCollections - 1) / numberOfCollections, - CpuRequest: nodeCpuCapacity / 100, - MemRequest: nodeMemCapacity / 100, - MaxContainerFailures: &MaxContainerFailures, - Silent: true, - LogFunc: framework.Logf, - SecretNames: secretNames, - ConfigMapNames: configMapNames, + Client: clients[i], + InternalClient: internalClients[i], + ScalesGetter: scalesClients[i], + Image: imageutils.GetPauseImageName(), + Name: name, + Namespace: nsName, + Labels: map[string]string{"type": "densityPod"}, + PollInterval: DensityPollInterval, + Timeout: timeout, + PodStatusFile: fileHndl, + Replicas: (totalPods + numberOfCollections - 1) / numberOfCollections, + CpuRequest: nodeCpuCapacity / 100, + MemRequest: nodeMemCapacity / 100, + MaxContainerFailures: &MaxContainerFailures, + Silent: true, + LogFunc: framework.Logf, + SecretNames: secretNames, + ConfigMapNames: configMapNames, + ServiceAccountTokenProjections: itArg.svcacctTokenProjectionsPerPod, } switch itArg.kind { case api.Kind("ReplicationController"): diff --git a/test/e2e/scheduling/BUILD b/test/e2e/scheduling/BUILD index 2fe2ce7287b1a..9da465bf82c8a 100644 --- a/test/e2e/scheduling/BUILD +++ b/test/e2e/scheduling/BUILD @@ -12,6 +12,7 @@ go_library( "preemption.go", "priorities.go", "resource_quota.go", + "taint_based_evictions.go", "taints.go", "ubernetes_lite.go", "ubernetes_lite_volumes.go", @@ -25,18 +26,18 @@ go_library( "//pkg/kubelet/apis:go_default_library", "//pkg/quota/v1/evaluator/core:go_default_library", "//pkg/scheduler/algorithm/priorities/util:go_default_library", + "//pkg/scheduler/api:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/api/scheduling/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//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/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/types: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/strategicpatch: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/test/e2e/scheduling/predicates.go b/test/e2e/scheduling/predicates.go index ed47b7af0511d..4360dbc5e0b0e 100644 --- a/test/e2e/scheduling/predicates.go +++ b/test/e2e/scheduling/predicates.go @@ -56,6 +56,7 @@ type pausePodConfig struct { Ports []v1.ContainerPort OwnerReferences []metav1.OwnerReference PriorityClassName string + DeletionGracePeriodSeconds *int64 } var _ = SIGDescribe("SchedulerPredicates [Serial]", func() { @@ -631,6 +632,9 @@ func initPausePod(f *framework.Framework, conf pausePodConfig) *v1.Pod { if conf.Resources != nil { pod.Spec.Containers[0].Resources = *conf.Resources } + if conf.DeletionGracePeriodSeconds != nil { + pod.ObjectMeta.DeletionGracePeriodSeconds = conf.DeletionGracePeriodSeconds + } return pod } diff --git a/test/e2e/scheduling/priorities.go b/test/e2e/scheduling/priorities.go index 96ac20649904a..b395a39f1029a 100644 --- a/test/e2e/scheduling/priorities.go +++ b/test/e2e/scheduling/priorities.go @@ -29,8 +29,6 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/strategicpatch" "k8s.io/apimachinery/pkg/util/uuid" clientset "k8s.io/client-go/kubernetes" priorityutil "k8s.io/kubernetes/pkg/scheduler/algorithm/priorities/util" @@ -83,7 +81,7 @@ var _ = SIGDescribe("SchedulerPriorities [Serial]", func() { Expect(err).NotTo(HaveOccurred()) }) - It("Pod should be schedule to node that don't match the PodAntiAffinity terms", func() { + It("Pod should be scheduled to node that don't match the PodAntiAffinity terms", func() { By("Trying to launch a pod with a label to get a node which can launch it.") pod := runPausePod(f, pausePodConfig{ Name: "pod-with-label-security-s1", @@ -144,7 +142,7 @@ var _ = SIGDescribe("SchedulerPriorities [Serial]", func() { Expect(labelPod.Spec.NodeName).NotTo(Equal(nodeName)) }) - It("Pod should avoid to schedule to node that have avoidPod annotation", func() { + It("Pod should avoid nodes that have avoidPod annotation", func() { nodeName := nodeList.Items[0].Name // make the nodes have balanced cpu,mem usage err := createBalancedPodForNodes(f, cs, ns, nodeList.Items, podRequestedResource, 0.5) @@ -207,7 +205,7 @@ var _ = SIGDescribe("SchedulerPriorities [Serial]", func() { } }) - It("Pod should perfer to scheduled to nodes pod can tolerate", func() { + It("Pod should be preferably scheduled to nodes pod can tolerate", func() { // make the nodes have balanced cpu,mem usage ratio err := createBalancedPodForNodes(f, cs, ns, nodeList.Items, podRequestedResource, 0.5) framework.ExpectNoError(err) @@ -256,49 +254,6 @@ var _ = SIGDescribe("SchedulerPriorities [Serial]", func() { Expect(err).NotTo(HaveOccurred()) Expect(tolePod.Spec.NodeName).To(Equal(nodeName)) }) - It("Pod should be preferably scheduled to nodes which satisfy its limits", func() { - var podwithLargeRequestedResource *v1.ResourceRequirements = &v1.ResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceMemory: resource.MustParse("100Mi"), - v1.ResourceCPU: resource.MustParse("100m"), - }, - Limits: v1.ResourceList{ - v1.ResourceMemory: resource.MustParse("3000Mi"), - v1.ResourceCPU: resource.MustParse("100m"), - }, - } - // Update one node to have large allocatable. - lastNode := nodeList.Items[len(nodeList.Items)-1] - nodeName := lastNode.Name - nodeOriginalMemory, found := lastNode.Status.Allocatable[v1.ResourceMemory] - Expect(found).To(Equal(true)) - nodeOriginalMemoryVal := nodeOriginalMemory.Value() - err := updateMemoryOfNode(cs, nodeName, int64(10000)) - Expect(err).NotTo(HaveOccurred()) - defer func() { - // Resize the node back to its original memory. - if err := updateMemoryOfNode(cs, nodeName, nodeOriginalMemoryVal); err != nil { - framework.Logf("Failed to revert node memory with %v", err) - } - }() - err = createBalancedPodForNodes(f, cs, ns, nodeList.Items, podRequestedResource, 0.5) - framework.ExpectNoError(err) - // After the above we should see 50% of node to be available which is 5000MiB for large node. - By("Create a pod with unusual large limits") - podWithLargeLimits := "with-large-limits" - - pod := createPausePod(f, pausePodConfig{ - Name: podWithLargeLimits, - Resources: podwithLargeRequestedResource, - }) - framework.ExpectNoError(f.WaitForPodRunning(pod.Name)) - - By("Pod should preferably scheduled to nodes which satisfy its limits") - // The pod should land onto large node(which has 5000MiB free) which satisfies the pod limits which is 3000MiB. - podHighLimits, err := cs.CoreV1().Pods(ns).Get(podWithLargeLimits, metav1.GetOptions{}) - Expect(err).NotTo(HaveOccurred()) - Expect(podHighLimits.Spec.NodeName).To(Equal(nodeName)) - }) }) // createBalancedPodForNodes creates a pod per node that asks for enough resources to make all nodes have the same mem/cpu usage ratio. @@ -444,24 +399,3 @@ func addRandomTaitToNode(cs clientset.Interface, nodeName string) *v1.Taint { framework.ExpectNodeHasTaint(cs, nodeName, &testTaint) return &testTaint } - -// updateMemoryOfNode updates the memory of given node with the given value -func updateMemoryOfNode(c clientset.Interface, nodeName string, memory int64) error { - node, err := c.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{}) - framework.ExpectNoError(err) - oldData, err := json.Marshal(node) - if err != nil { - return err - } - node.Status.Allocatable[v1.ResourceMemory] = *resource.NewQuantity(memory, resource.BinarySI) - newData, err := json.Marshal(node) - if err != nil { - return err - } - patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, v1.Node{}) - if err != nil { - return err - } - _, err = c.CoreV1().Nodes().Patch(string(node.Name), types.StrategicMergePatchType, patchBytes) - return err -} diff --git a/test/e2e/scheduling/taint_based_evictions.go b/test/e2e/scheduling/taint_based_evictions.go new file mode 100644 index 0000000000000..612a8a77d0cc3 --- /dev/null +++ b/test/e2e/scheduling/taint_based_evictions.go @@ -0,0 +1,193 @@ +/* +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 scheduling + +import ( + "errors" + "fmt" + "time" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + clientset "k8s.io/client-go/kubernetes" + schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" + "k8s.io/kubernetes/test/e2e/framework" + + . "github.com/onsi/ginkgo" +) + +func newUnreachableNoExecuteTaint() *v1.Taint { + return &v1.Taint{ + Key: schedulerapi.TaintNodeUnreachable, + Effect: v1.TaintEffectNoExecute, + } +} + +func getTolerationSeconds(tolerations []v1.Toleration) (int64, error) { + for _, t := range tolerations { + if t.Key == schedulerapi.TaintNodeUnreachable && t.Effect == v1.TaintEffectNoExecute && t.Operator == v1.TolerationOpExists { + return *t.TolerationSeconds, nil + } + } + return 0, errors.New("cannot find toleration") +} + +var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { + f := framework.NewDefaultFramework("sched-taint-based-evictions") + var cs clientset.Interface + var ns string + + BeforeEach(func() { + cs = f.ClientSet + ns = f.Namespace.Name + // skip if TaintBasedEvictions is not enabled + // TODO(Huang-Wei): remove this when TaintBasedEvictions is GAed + framework.SkipUnlessTaintBasedEvictionsEnabled() + // it's required to run on a cluster that has more than 1 node + // otherwise node lifecycle manager enters a fully disruption mode + framework.SkipUnlessNodeCountIsAtLeast(2) + }) + + // This test verifies that when a node becomes unreachable + // 1. node lifecycle manager generate a status change: [NodeReady=true, status=ConditionUnknown] + // 1. it's applied with node.kubernetes.io/unreachable=:NoExecute taint + // 2. pods without toleration are applied with toleration with tolerationSeconds=300 + // 3. pods with toleration and without tolerationSeconds won't be modifed, and won't be evicted + // 4. pods with toleration and with tolerationSeconds won't be modified, and will be evicted after tolerationSeconds + // When network issue recovers, it's expected to see: + // 5. node lifecycle manager generate a status change: [NodeReady=true, status=ConditionTrue] + // 6. node.kubernetes.io/unreachable=:NoExecute taint is taken off the node + It("Checks that the node becomes unreachable", func() { + // find an available node + nodeName := GetNodeThatCanRunPod(f) + By("Finding an available node " + nodeName) + + // pod0 is a pod with unschedulable=:NoExecute toleration, and tolerationSeconds=0s + // pod1 is a pod with unschedulable=:NoExecute toleration, and tolerationSeconds=200s + // pod2 is a pod without any toleration + base := "taint-based-eviction" + tolerationSeconds := []int64{0, 200} + numPods := len(tolerationSeconds) + 1 + By(fmt.Sprintf("Preparing %v pods", numPods)) + pods := make([]*v1.Pod, numPods) + zero := int64(0) + // build pod0, pod1 + for i := 0; i < numPods-1; i++ { + pods[i] = createPausePod(f, pausePodConfig{ + Name: fmt.Sprintf("%v-%v", base, i), + NodeName: nodeName, + Tolerations: []v1.Toleration{ + { + Key: schedulerapi.TaintNodeUnreachable, + Operator: v1.TolerationOpExists, + Effect: v1.TaintEffectNoExecute, + TolerationSeconds: &tolerationSeconds[i], + }, + }, + DeletionGracePeriodSeconds: &zero, + }) + } + // build pod2 + pods[numPods-1] = createPausePod(f, pausePodConfig{ + Name: fmt.Sprintf("%v-%v", base, numPods-1), + NodeName: nodeName, + }) + + By("Verifying all pods are running properly") + for _, pod := range pods { + framework.ExpectNoError(framework.WaitForPodRunningInNamespace(cs, pod)) + } + + // get the node API object + nodeSelector := fields.OneTermEqualSelector("metadata.name", nodeName) + nodeList, err := cs.CoreV1().Nodes().List(metav1.ListOptions{FieldSelector: nodeSelector.String()}) + if err != nil || len(nodeList.Items) != 1 { + framework.Failf("expected no err, got %v; expected len(nodes) = 1, got %v", err, len(nodeList.Items)) + } + node := nodeList.Items[0] + + By(fmt.Sprintf("Blocking traffic from node %s to the master", nodeName)) + host, err := framework.GetNodeExternalIP(&node) + // TODO(Huang-Wei): make this case work for local provider + // if err != nil { + // host, err = framework.GetNodeInternalIP(&node) + // } + framework.ExpectNoError(err) + masterAddresses := framework.GetAllMasterAddresses(cs) + taint := newUnreachableNoExecuteTaint() + + defer func() { + By(fmt.Sprintf("Unblocking traffic from node %s to the master", node.Name)) + for _, masterAddress := range masterAddresses { + framework.UnblockNetwork(host, masterAddress) + } + + if CurrentGinkgoTestDescription().Failed { + framework.Failf("Current e2e test has failed, so return from here.") + return + } + + By(fmt.Sprintf("Expecting to see node %q becomes Ready", nodeName)) + framework.WaitForNodeToBeReady(cs, nodeName, time.Minute*1) + By("Expecting to see unreachable=:NoExecute taint is taken off") + err := framework.WaitForNodeHasTaintOrNot(cs, nodeName, taint, false, time.Second*30) + framework.ExpectNoError(err) + }() + + for _, masterAddress := range masterAddresses { + framework.BlockNetwork(host, masterAddress) + } + + By(fmt.Sprintf("Expecting to see node %q becomes NotReady", nodeName)) + if !framework.WaitForNodeToBeNotReady(cs, nodeName, time.Minute*3) { + framework.Failf("node %q doesn't turn to NotReady after 3 minutes", nodeName) + } + By("Expecting to see unreachable=:NoExecute taint is applied") + err = framework.WaitForNodeHasTaintOrNot(cs, nodeName, taint, true, time.Second*30) + framework.ExpectNoError(err) + + By("Expecting pod0 to be evicted immediately") + err = framework.WaitForPodCondition(cs, ns, pods[0].Name, "pod0 terminating", time.Second*15, func(pod *v1.Pod) (bool, error) { + // as node is unreachable, pod0 is expected to be in Terminating status + // rather than getting deleted + if pod.DeletionTimestamp != nil { + return true, nil + } + return false, nil + }) + framework.ExpectNoError(err) + + By("Expecting pod2 to be updated with a toleration with tolerationSeconds=300") + err = framework.WaitForPodCondition(cs, ns, pods[2].Name, "pod2 updated with tolerationSeconds=300", time.Second*15, func(pod *v1.Pod) (bool, error) { + if seconds, err := getTolerationSeconds(pod.Spec.Tolerations); err == nil { + return seconds == 300, nil + } + return false, nil + }) + framework.ExpectNoError(err) + + By("Expecting pod1 to be unchanged") + livePod1, err := cs.CoreV1().Pods(pods[1].Namespace).Get(pods[1].Name, metav1.GetOptions{}) + framework.ExpectNoError(err) + seconds, err := getTolerationSeconds(livePod1.Spec.Tolerations) + framework.ExpectNoError(err) + if seconds != 200 { + framework.Failf("expect tolerationSeconds of pod1 is 200, but got %v", seconds) + } + }) +}) diff --git a/test/e2e/storage/BUILD b/test/e2e/storage/BUILD index abe4cfdbc4326..4a53af9741372 100644 --- a/test/e2e/storage/BUILD +++ b/test/e2e/storage/BUILD @@ -3,11 +3,12 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", srcs = [ - "csi_objects.go", "csi_volumes.go", "empty_dir_wrapper.go", "ephemeral_volume.go", "flexvolume.go", + "flexvolume_mounted_volume_resize.go", + "flexvolume_online_resize.go", "generic_persistent_volume-disruptive.go", "in_tree_volumes.go", "mounted_volume_resize.go", @@ -41,12 +42,9 @@ go_library( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1: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/api/rbac/v1beta1:go_default_library", "//staging/src/k8s.io/api/storage/v1:go_default_library", "//staging/src/k8s.io/api/storage/v1beta1:go_default_library", - "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", - "//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", @@ -58,6 +56,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/rand:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch: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", @@ -65,16 +64,15 @@ 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/rest:go_default_library", "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned:go_default_library", - "//staging/src/k8s.io/csi-api/pkg/crd:go_default_library", "//test/e2e/framework:go_default_library", "//test/e2e/framework/metrics:go_default_library", + "//test/e2e/framework/podlogs:go_default_library", "//test/e2e/framework/providers/gce:go_default_library", "//test/e2e/framework/testfiles:go_default_library", - "//test/e2e/manifest:go_default_library", "//test/e2e/storage/drivers:go_default_library", + "//test/e2e/storage/testpatterns:go_default_library", "//test/e2e/storage/testsuites:go_default_library", "//test/e2e/storage/utils:go_default_library", "//test/utils/image:go_default_library", diff --git a/test/e2e/storage/csi_objects.go b/test/e2e/storage/csi_objects.go deleted file mode 100644 index df5d1d43e2997..0000000000000 --- a/test/e2e/storage/csi_objects.go +++ /dev/null @@ -1,616 +0,0 @@ -/* -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. -*/ - -// This file is used to deploy the CSI hostPath plugin -// More Information: https://github.com/kubernetes-csi/drivers/tree/master/pkg/hostpath - -package storage - -import ( - "flag" - "fmt" - "io/ioutil" - "os" - "path" - "path/filepath" - "time" - - "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - apierrs "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/uuid" - "k8s.io/apimachinery/pkg/util/wait" - - clientset "k8s.io/client-go/kubernetes" - restclient "k8s.io/client-go/rest" - "k8s.io/kubernetes/test/e2e/framework" - "k8s.io/kubernetes/test/e2e/manifest" - - . "github.com/onsi/ginkgo" - - apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - csicrd "k8s.io/csi-api/pkg/crd" -) - -var ( - csiImageVersion = flag.String("storage.csi.image.version", "", "overrides the default tag used for hostpathplugin/csi-attacher/csi-provisioner/driver-registrar images") - csiImageRegistry = flag.String("storage.csi.image.registry", "quay.io/k8scsi", "overrides the default repository used for hostpathplugin/csi-attacher/csi-provisioner/driver-registrar images") - csiImageVersions = map[string]string{ - "hostpathplugin": "v0.4.0", - "csi-attacher": "v0.4.0", - "csi-provisioner": "v0.4.0", - "driver-registrar": "v0.4.0", - } -) - -func csiContainerImage(image string) string { - var fullName string - fullName += *csiImageRegistry + "/" + image + ":" - if *csiImageVersion != "" { - fullName += *csiImageVersion - } else { - fullName += csiImageVersions[image] - } - return fullName -} - -// Create the driver registrar cluster role if it doesn't exist, no teardown so that tests -// are parallelizable. This role will be shared with many of the CSI tests. -func csiDriverRegistrarClusterRole( - config framework.VolumeTestConfig, -) *rbacv1.ClusterRole { - // TODO(Issue: #62237) Remove impersonation workaround and cluster role when issue resolved - By("Creating an impersonating superuser kubernetes clientset to define cluster role") - rc, err := framework.LoadConfig() - framework.ExpectNoError(err) - rc.Impersonate = restclient.ImpersonationConfig{ - UserName: "superuser", - Groups: []string{"system:masters"}, - } - superuserClientset, err := clientset.NewForConfig(rc) - framework.ExpectNoError(err, "Failed to create superuser clientset: %v", err) - By("Creating the CSI driver registrar cluster role") - clusterRoleClient := superuserClientset.RbacV1().ClusterRoles() - role := &rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: csiDriverRegistrarClusterRoleName, - }, - Rules: []rbacv1.PolicyRule{ - - { - APIGroups: []string{""}, - Resources: []string{"events"}, - Verbs: []string{"get", "list", "watch", "create", "update", "patch"}, - }, - { - APIGroups: []string{""}, - Resources: []string{"nodes"}, - Verbs: []string{"get", "update", "patch"}, - }, - }, - } - - ret, err := clusterRoleClient.Create(role) - if err != nil { - if apierrs.IsAlreadyExists(err) { - return ret - } - framework.ExpectNoError(err, "Failed to create %s cluster role: %v", role.GetName(), err) - } - - return ret -} - -func csiServiceAccount( - client clientset.Interface, - config framework.VolumeTestConfig, - componentName string, - teardown bool, -) *v1.ServiceAccount { - creatingString := "Creating" - if teardown { - creatingString = "Deleting" - } - By(fmt.Sprintf("%v a CSI service account for %v", creatingString, componentName)) - serviceAccountName := config.Prefix + "-" + componentName + "-service-account" - serviceAccountClient := client.CoreV1().ServiceAccounts(config.Namespace) - sa := &v1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: serviceAccountName, - Namespace: config.Namespace, - }, - } - - serviceAccountClient.Delete(sa.GetName(), &metav1.DeleteOptions{}) - err := wait.Poll(2*time.Second, 10*time.Minute, func() (bool, error) { - _, err := serviceAccountClient.Get(sa.GetName(), metav1.GetOptions{}) - return apierrs.IsNotFound(err), nil - }) - framework.ExpectNoError(err, "Timed out waiting for deletion: %v", err) - - if teardown { - return nil - } - - ret, err := serviceAccountClient.Create(sa) - if err != nil { - framework.ExpectNoError(err, "Failed to create %s service account: %v", sa.GetName(), err) - } - - return ret -} - -func csiClusterRoleBindings( - client clientset.Interface, - config framework.VolumeTestConfig, - teardown bool, - sa *v1.ServiceAccount, - clusterRolesNames []string, -) { - bindingString := "Binding" - if teardown { - bindingString = "Unbinding" - } - By(fmt.Sprintf("%v cluster roles %v to the CSI service account %v", bindingString, clusterRolesNames, sa.GetName())) - clusterRoleBindingClient := client.RbacV1().ClusterRoleBindings() - for _, clusterRoleName := range clusterRolesNames { - binding := &rbacv1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: clusterRoleName + "-" + config.Namespace + "-" + string(uuid.NewUUID()), - }, - Subjects: []rbacv1.Subject{ - { - Kind: rbacv1.ServiceAccountKind, - Name: sa.GetName(), - Namespace: sa.GetNamespace(), - }, - }, - RoleRef: rbacv1.RoleRef{ - Kind: "ClusterRole", - Name: clusterRoleName, - APIGroup: "rbac.authorization.k8s.io", - }, - } - - clusterRoleBindingClient.Delete(binding.GetName(), &metav1.DeleteOptions{}) - err := wait.Poll(2*time.Second, 10*time.Minute, func() (bool, error) { - _, err := clusterRoleBindingClient.Get(binding.GetName(), metav1.GetOptions{}) - return apierrs.IsNotFound(err), nil - }) - framework.ExpectNoError(err, "Timed out waiting for deletion: %v", err) - - if teardown { - return - } - - _, err = clusterRoleBindingClient.Create(binding) - if err != nil { - framework.ExpectNoError(err, "Failed to create %s role binding: %v", binding.GetName(), err) - } - } -} - -func csiControllerRole( - client clientset.Interface, - config framework.VolumeTestConfig, - teardown bool, -) string { - action := "Creating" - if teardown { - action = "Deleting" - } - - By(fmt.Sprintf("%v CSI controller role", action)) - - role, err := manifest.RoleFromManifest("test/e2e/testing-manifests/storage-csi/controller-role.yaml", config.Namespace) - framework.ExpectNoError(err, "Failed to create Role from manifest") - - client.RbacV1().Roles(role.Namespace).Delete(role.Name, nil) - err = wait.Poll(2*time.Second, 10*time.Minute, func() (bool, error) { - _, err := client.RbacV1().Roles(role.Namespace).Get(role.Name, metav1.GetOptions{}) - return apierrs.IsNotFound(err), nil - }) - framework.ExpectNoError(err, "Timed out waiting for deletion: %v", err) - - if teardown { - return role.Name - } - - _, err = client.RbacV1().Roles(role.Namespace).Create(role) - if err != nil { - framework.ExpectNoError(err, "Failed to create %s role binding: %v", role.Name, err) - } - return role.Name -} - -func csiControllerRoleBinding( - client clientset.Interface, - config framework.VolumeTestConfig, - teardown bool, - roleName string, - sa *v1.ServiceAccount, -) { - bindingString := "Binding" - if teardown { - bindingString = "Unbinding" - } - By(fmt.Sprintf("%v roles %v to the CSI service account %v", bindingString, roleName, sa.GetName())) - roleBindingClient := client.RbacV1().RoleBindings(config.Namespace) - binding := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: config.Prefix + "-" + roleName + "-" + config.Namespace + "-role-binding", - }, - Subjects: []rbacv1.Subject{ - { - Kind: "ServiceAccount", - Name: sa.GetName(), - Namespace: sa.GetNamespace(), - }, - }, - RoleRef: rbacv1.RoleRef{ - Kind: "Role", - Name: roleName, - APIGroup: "rbac.authorization.k8s.io", - }, - } - - roleBindingClient.Delete(binding.GetName(), &metav1.DeleteOptions{}) - err := wait.Poll(2*time.Second, 10*time.Minute, func() (bool, error) { - _, err := roleBindingClient.Get(binding.GetName(), metav1.GetOptions{}) - return apierrs.IsNotFound(err), nil - }) - framework.ExpectNoError(err, "Timed out waiting for deletion: %v", err) - - if teardown { - return - } - - _, err = roleBindingClient.Create(binding) - if err != nil { - framework.ExpectNoError(err, "Failed to create %s role binding: %v", binding.GetName(), err) - } -} - -func csiHostPathPod( - client clientset.Interface, - config framework.VolumeTestConfig, - teardown bool, - f *framework.Framework, - sa *v1.ServiceAccount, -) *v1.Pod { - priv := true - mountPropagation := v1.MountPropagationBidirectional - hostPathType := v1.HostPathDirectoryOrCreate - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: config.Prefix + "-pod", - Namespace: config.Namespace, - Labels: map[string]string{ - "app": "hostpath-driver", - }, - }, - Spec: v1.PodSpec{ - ServiceAccountName: sa.GetName(), - NodeName: config.ServerNodeName, - RestartPolicy: v1.RestartPolicyNever, - Containers: []v1.Container{ - { - Name: "external-provisioner", - Image: csiContainerImage("csi-provisioner"), - ImagePullPolicy: v1.PullAlways, - SecurityContext: &v1.SecurityContext{ - Privileged: &priv, - }, - Args: []string{ - "--v=5", - "--provisioner=csi-hostpath", - "--csi-address=/csi/csi.sock", - }, - VolumeMounts: []v1.VolumeMount{ - { - Name: "socket-dir", - MountPath: "/csi", - }, - }, - }, - { - Name: "driver-registrar", - Image: csiContainerImage("driver-registrar"), - ImagePullPolicy: v1.PullAlways, - SecurityContext: &v1.SecurityContext{ - Privileged: &priv, - }, - Args: []string{ - "--v=5", - "--csi-address=/csi/csi.sock", - "--kubelet-registration-path=/var/lib/kubelet/plugins/csi-hostpath/csi.sock", - }, - Env: []v1.EnvVar{ - { - Name: "KUBE_NODE_NAME", - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "spec.nodeName", - }, - }, - }, - }, - VolumeMounts: []v1.VolumeMount{ - { - Name: "socket-dir", - MountPath: "/csi", - }, - { - Name: "registration-dir", - MountPath: "/registration", - }, - }, - }, - { - Name: "external-attacher", - Image: csiContainerImage("csi-attacher"), - ImagePullPolicy: v1.PullAlways, - SecurityContext: &v1.SecurityContext{ - Privileged: &priv, - }, - Args: []string{ - "--v=5", - "--csi-address=$(ADDRESS)", - }, - Env: []v1.EnvVar{ - { - Name: "ADDRESS", - Value: "/csi/csi.sock", - }, - }, - VolumeMounts: []v1.VolumeMount{ - { - Name: "socket-dir", - MountPath: "/csi", - }, - }, - }, - { - Name: "hostpath-driver", - Image: csiContainerImage("hostpathplugin"), - ImagePullPolicy: v1.PullAlways, - SecurityContext: &v1.SecurityContext{ - Privileged: &priv, - }, - Args: []string{ - "--v=5", - "--endpoint=$(CSI_ENDPOINT)", - "--nodeid=$(KUBE_NODE_NAME)", - }, - Env: []v1.EnvVar{ - { - Name: "CSI_ENDPOINT", - Value: "unix://" + "/csi/csi.sock", - }, - { - Name: "KUBE_NODE_NAME", - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "spec.nodeName", - }, - }, - }, - }, - VolumeMounts: []v1.VolumeMount{ - { - Name: "socket-dir", - MountPath: "/csi", - }, - { - Name: "mountpoint-dir", - MountPath: "/var/lib/kubelet/pods", - MountPropagation: &mountPropagation, - }, - }, - }, - }, - Volumes: []v1.Volume{ - { - Name: "socket-dir", - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{ - Path: "/var/lib/kubelet/plugins/csi-hostpath", - Type: &hostPathType, - }, - }, - }, - { - Name: "registration-dir", - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{ - Path: "/var/lib/kubelet/plugins", - Type: &hostPathType, - }, - }, - }, - { - Name: "mountpoint-dir", - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{ - Path: "/var/lib/kubelet/pods", - Type: &hostPathType, - }, - }, - }, - }, - }, - } - - err := framework.DeletePodWithWait(f, client, pod) - framework.ExpectNoError(err, "Failed to delete pod %s/%s: %v", - pod.GetNamespace(), pod.GetName(), err) - - if teardown { - return nil - } - - // Creating the pod can fail initially while the service - // account's secret isn't provisioned yet ('No API token found - // for service account "csi-service-account", retry after the - // token is automatically created and added to the service - // account', see https://github.com/kubernetes/kubernetes/issues/68776). - // We could use a DaemonSet, but then the name of the csi-pod changes - // during each test run. It's simpler to just try for a while here. - podClient := f.PodClient() - ret := podClient.CreateEventually(pod) - - // Wait for pod to come up - framework.ExpectNoError(framework.WaitForPodRunningInNamespace(client, ret)) - return ret -} - -func deployGCEPDCSIDriver( - client clientset.Interface, - config framework.VolumeTestConfig, - teardown bool, - f *framework.Framework, - nodeSA *v1.ServiceAccount, - controllerSA *v1.ServiceAccount, -) { - // Get API Objects from manifests - nodeds, err := manifest.DaemonSetFromManifest("test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml", config.Namespace) - framework.ExpectNoError(err, "Failed to create DaemonSet from manifest") - nodeds.Spec.Template.Spec.ServiceAccountName = nodeSA.GetName() - - controllerss, err := manifest.StatefulSetFromManifest("test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml", config.Namespace) - framework.ExpectNoError(err, "Failed to create StatefulSet from manifest") - controllerss.Spec.Template.Spec.ServiceAccountName = controllerSA.GetName() - - controllerservice, err := manifest.SvcFromManifest("test/e2e/testing-manifests/storage-csi/gce-pd/controller_service.yaml") - framework.ExpectNoError(err, "Failed to create Service from manifest") - - // Got all objects from manifests now try to delete objects - err = client.CoreV1().Services(config.Namespace).Delete(controllerservice.GetName(), nil) - if err != nil { - if !apierrs.IsNotFound(err) { - framework.ExpectNoError(err, "Failed to delete Service: %v", controllerservice.GetName()) - } - } - - err = client.AppsV1().StatefulSets(config.Namespace).Delete(controllerss.Name, nil) - if err != nil { - if !apierrs.IsNotFound(err) { - framework.ExpectNoError(err, "Failed to delete StatefulSet: %v", controllerss.GetName()) - } - } - err = client.AppsV1().DaemonSets(config.Namespace).Delete(nodeds.Name, nil) - if err != nil { - if !apierrs.IsNotFound(err) { - framework.ExpectNoError(err, "Failed to delete DaemonSet: %v", nodeds.GetName()) - } - } - if teardown { - return - } - - // Create new API Objects through client - _, err = client.CoreV1().Services(config.Namespace).Create(controllerservice) - framework.ExpectNoError(err, "Failed to create Service: %v", controllerservice.Name) - - _, err = client.AppsV1().StatefulSets(config.Namespace).Create(controllerss) - framework.ExpectNoError(err, "Failed to create StatefulSet: %v", controllerss.Name) - - _, err = client.AppsV1().DaemonSets(config.Namespace).Create(nodeds) - framework.ExpectNoError(err, "Failed to create DaemonSet: %v", nodeds.Name) - -} - -func createCSICRDs(c apiextensionsclient.Interface) { - By("Creating CSI CRDs") - crds := []*apiextensionsv1beta1.CustomResourceDefinition{ - csicrd.CSIDriverCRD(), - csicrd.CSINodeInfoCRD(), - } - - for _, crd := range crds { - _, err := c.ApiextensionsV1beta1().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{}) - if err == nil { - continue - } else if !apierrs.IsNotFound(err) { - framework.ExpectNoError(err, "Failed to check for existing of CSI CRD %q: %v", crd.Name, err) - } - _, err = c.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd) - framework.ExpectNoError(err, "Failed to create CSI CRD %q: %v", crd.Name, err) - } -} - -func shredFile(filePath string) { - if _, err := os.Stat(filePath); os.IsNotExist(err) { - framework.Logf("File %v was not found, skipping shredding", filePath) - return - } - framework.Logf("Shredding file %v", filePath) - _, _, err := framework.RunCmd("shred", "--remove", filePath) - if err != nil { - framework.Logf("Failed to shred file %v: %v", filePath, err) - } - if _, err := os.Stat(filePath); os.IsNotExist(err) { - framework.Logf("File %v successfully shredded", filePath) - return - } - // Shred failed Try to remove the file for good meausure - err = os.Remove(filePath) - framework.ExpectNoError(err, "Failed to remove service account file %s", filePath) - -} - -// createGCESecrets downloads the GCP IAM Key for the default compute service account -// and puts it in a secret for the GCE PD CSI Driver to consume -func createGCESecrets(client clientset.Interface, config framework.VolumeTestConfig) { - saEnv := "E2E_GOOGLE_APPLICATION_CREDENTIALS" - saFile := fmt.Sprintf("/tmp/%s/cloud-sa.json", string(uuid.NewUUID())) - - os.MkdirAll(path.Dir(saFile), 0750) - defer os.Remove(path.Dir(saFile)) - - premadeSAFile, ok := os.LookupEnv(saEnv) - if !ok { - framework.Logf("Could not find env var %v, please either create cloud-sa"+ - " secret manually or rerun test after setting %v to the filepath of"+ - " the GCP Service Account to give to the GCE Persistent Disk CSI Driver", saEnv, saEnv) - return - } - - framework.Logf("Found CI service account key at %v", premadeSAFile) - // Need to copy it saFile - stdout, stderr, err := framework.RunCmd("cp", premadeSAFile, saFile) - framework.ExpectNoError(err, "error copying service account key: %s\nstdout: %s\nstderr: %s", err, stdout, stderr) - defer shredFile(saFile) - // Create Secret with this Service Account - fileBytes, err := ioutil.ReadFile(saFile) - framework.ExpectNoError(err, "Failed to read file %v", saFile) - - s := &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "cloud-sa", - Namespace: config.Namespace, - }, - Type: v1.SecretTypeOpaque, - Data: map[string][]byte{ - filepath.Base(saFile): fileBytes, - }, - } - - _, err = client.CoreV1().Secrets(config.Namespace).Create(s) - framework.ExpectNoError(err, "Failed to create Secret %v", s.GetName()) -} diff --git a/test/e2e/storage/csi_volumes.go b/test/e2e/storage/csi_volumes.go index 9db126fdd1c99..7adcfc655c3d8 100644 --- a/test/e2e/storage/csi_volumes.go +++ b/test/e2e/storage/csi_volumes.go @@ -17,20 +17,21 @@ limitations under the License. package storage import ( + "context" "fmt" - "math/rand" - "time" + "regexp" "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" - apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientset "k8s.io/client-go/kubernetes" csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1" csiclient "k8s.io/csi-api/pkg/client/clientset/versioned" "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/e2e/framework/podlogs" + "k8s.io/kubernetes/test/e2e/storage/drivers" + "k8s.io/kubernetes/test/e2e/storage/testpatterns" "k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/utils" imageutils "k8s.io/kubernetes/test/utils/image" @@ -41,93 +42,125 @@ import ( . "github.com/onsi/gomega" ) -const ( - csiExternalProvisionerClusterRoleName string = "system:csi-external-provisioner" - csiExternalAttacherClusterRoleName string = "system:csi-external-attacher" - csiDriverRegistrarClusterRoleName string = "csi-driver-registrar" -) +// List of testDrivers to be executed in below loop +var csiTestDrivers = []func() drivers.TestDriver{ + drivers.InitHostPathCSIDriver, + drivers.InitGcePDCSIDriver, + drivers.InitGcePDExternalCSIDriver, +} -type csiTestDriver interface { - createCSIDriver() - cleanupCSIDriver() - createStorageClassTest(node v1.Node) testsuites.StorageClassTest +// List of testSuites to be executed in below loop +var csiTestSuites = []func() testsuites.TestSuite{ + testsuites.InitVolumesTestSuite, + testsuites.InitVolumeIOTestSuite, + testsuites.InitVolumeModeTestSuite, + testsuites.InitSubPathTestSuite, + testsuites.InitProvisioningTestSuite, } -var csiTestDrivers = map[string]func(f *framework.Framework, config framework.VolumeTestConfig) csiTestDriver{ - "hostPath": initCSIHostpath, - "gcePD": initCSIgcePD, +func csiTunePattern(patterns []testpatterns.TestPattern) []testpatterns.TestPattern { + tunedPatterns := []testpatterns.TestPattern{} + + for _, pattern := range patterns { + // Skip inline volume and pre-provsioned PV tests for csi drivers + if pattern.VolType == testpatterns.InlineVolume || pattern.VolType == testpatterns.PreprovisionedPV { + continue + } + tunedPatterns = append(tunedPatterns, pattern) + } + + return tunedPatterns } +// This executes testSuites for csi volumes. var _ = utils.SIGDescribe("CSI Volumes", func() { - f := framework.NewDefaultFramework("csi-mock-plugin") + f := framework.NewDefaultFramework("csi-volumes") var ( - cs clientset.Interface - crdclient apiextensionsclient.Interface - csics csiclient.Interface - ns *v1.Namespace - node v1.Node - config framework.VolumeTestConfig + cancel context.CancelFunc + cs clientset.Interface + ns *v1.Namespace + config framework.VolumeTestConfig ) BeforeEach(func() { + ctx, c := context.WithCancel(context.Background()) + cancel = c cs = f.ClientSet - crdclient = f.APIExtensionsClientSet - csics = f.CSIClientSet ns = f.Namespace - nodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet) - node = nodes.Items[rand.Intn(len(nodes.Items))] config = framework.VolumeTestConfig{ - Namespace: ns.Name, - Prefix: "csi", - ClientNodeName: node.Name, - ServerNodeName: node.Name, - WaitForCompletion: true, + Namespace: ns.Name, + Prefix: "csi", + } + // Debugging of the following tests heavily depends on the log output + // of the different containers. Therefore include all of that in log + // files (when using --report-dir, as in the CI) or the output stream + // (otherwise). + to := podlogs.LogOutput{ + StatusWriter: GinkgoWriter, + } + if framework.TestContext.ReportDir == "" { + to.LogWriter = GinkgoWriter + } else { + test := CurrentGinkgoTestDescription() + reg := regexp.MustCompile("[^a-zA-Z0-9_-]+") + // We end the prefix with a slash to ensure that all logs + // end up in a directory named after the current test. + to.LogPathPrefix = framework.TestContext.ReportDir + "/" + + reg.ReplaceAllString(test.FullTestText, "_") + "/" + } + podlogs.CopyAllLogs(ctx, cs, ns.Name, to) + + // pod events are something that the framework already collects itself + // after a failed test. Logging them live is only useful for interactive + // debugging, not when we collect reports. + if framework.TestContext.ReportDir == "" { + podlogs.WatchPods(ctx, cs, ns.Name, GinkgoWriter) } - csiDriverRegistrarClusterRole(config) - createCSICRDs(crdclient) }) - for driverName, initCSIDriver := range csiTestDrivers { - curDriverName := driverName - curInitCSIDriver := initCSIDriver + AfterEach(func() { + cancel() + }) - Context(fmt.Sprintf("CSI plugin test using CSI driver: %s", curDriverName), func() { - var ( - driver csiTestDriver - ) + for _, initDriver := range csiTestDrivers { + curDriver := initDriver() + Context(fmt.Sprintf(drivers.GetDriverNameWithFeatureTags(curDriver)), func() { + driver := curDriver BeforeEach(func() { - driver = curInitCSIDriver(f, config) - driver.createCSIDriver() + // setupDriver + drivers.SetCommonDriverParameters(driver, f, config) + driver.CreateDriver() }) AfterEach(func() { - driver.cleanupCSIDriver() + // Cleanup driver + driver.CleanupDriver() }) - It("should provision storage", func() { - t := driver.createStorageClassTest(node) - claim := newClaim(t, ns.GetName(), "") - class := newStorageClass(t, ns.GetName(), "") - claim.Spec.StorageClassName = &class.ObjectMeta.Name - testsuites.TestDynamicProvisioning(t, cs, claim, class) - }) + testsuites.RunTestSuite(f, config, driver, csiTestSuites, csiTunePattern) }) } - // Use [Serial], because there can be only one CSIDriver for csi-hostpath driver. - Context("CSI attach test using HostPath driver [Serial][Feature:CSISkipAttach]", func() { + // The CSIDriverRegistry feature gate is needed for this test in Kubernetes 1.12. + Context("CSI attach test using HostPath driver [Feature:CSISkipAttach]", func() { var ( - driver csiTestDriver + cs clientset.Interface + csics csiclient.Interface + driver drivers.TestDriver ) + BeforeEach(func() { - driver = initCSIHostpath(f, config) - driver.createCSIDriver() + cs = f.ClientSet + csics = f.CSIClientSet + driver = drivers.InitHostPathCSIDriver() + drivers.SetCommonDriverParameters(driver, f, config) + driver.CreateDriver() }) AfterEach(func() { - driver.cleanupCSIDriver() + driver.CleanupDriver() }) tests := []struct { @@ -159,15 +192,27 @@ var _ = utils.SIGDescribe("CSI Volumes", func() { test := t It(test.name, func() { if test.driverExists { - driver := createCSIDriver(csics, test.driverAttachable) - if driver != nil { - defer csics.CsiV1alpha1().CSIDrivers().Delete(driver.Name, nil) + csiDriver := createCSIDriver(csics, "csi-hostpath-"+f.UniqueName, test.driverAttachable) + if csiDriver != nil { + defer csics.CsiV1alpha1().CSIDrivers().Delete(csiDriver.Name, nil) } } By("Creating pod") - t := driver.createStorageClassTest(node) - class, claim, pod := startPausePod(cs, t, ns.Name) + var sc *storagev1.StorageClass + if dDriver, ok := driver.(drivers.DynamicPVTestDriver); ok { + sc = dDriver.GetDynamicProvisionStorageClass("") + } + nodeName := driver.GetDriverInfo().Config.ClientNodeName + scTest := testsuites.StorageClassTest{ + Name: driver.GetDriverInfo().Name, + Provisioner: sc.Provisioner, + Parameters: sc.Parameters, + ClaimSize: "1Gi", + ExpectedSize: "1Gi", + NodeName: nodeName, + } + class, claim, pod := startPausePod(cs, scTest, ns.Name) if class != nil { defer cs.StorageV1().StorageClasses().Delete(class.Name, nil) } @@ -188,7 +233,7 @@ var _ = utils.SIGDescribe("CSI Volumes", func() { By("Checking if VolumeAttachment was created for the pod") // Check that VolumeAttachment does not exist handle := getVolumeHandle(cs, claim) - attachmentHash := sha256.Sum256([]byte(fmt.Sprintf("%s%s%s", handle, t.Provisioner, node.Name))) + attachmentHash := sha256.Sum256([]byte(fmt.Sprintf("%s%s%s", handle, scTest.Provisioner, nodeName))) attachmentName := fmt.Sprintf("csi-%x", attachmentHash) _, err = cs.StorageV1beta1().VolumeAttachments().Get(attachmentName, metav1.GetOptions{}) if err != nil { @@ -208,11 +253,11 @@ var _ = utils.SIGDescribe("CSI Volumes", func() { }) }) -func createCSIDriver(csics csiclient.Interface, attachable bool) *csiv1alpha1.CSIDriver { +func createCSIDriver(csics csiclient.Interface, name string, attachable bool) *csiv1alpha1.CSIDriver { By("Creating CSIDriver instance") driver := &csiv1alpha1.CSIDriver{ ObjectMeta: metav1.ObjectMeta{ - Name: "csi-hostpath", + Name: name, }, Spec: csiv1alpha1.CSIDriverSpec{ AttachRequired: &attachable, @@ -291,134 +336,3 @@ func startPausePod(cs clientset.Interface, t testsuites.StorageClassTest, ns str framework.ExpectNoError(err, "Failed to create pod: %v", err) return class, claim, pod } - -type hostpathCSIDriver struct { - combinedClusterRoleNames []string - serviceAccount *v1.ServiceAccount - - f *framework.Framework - config framework.VolumeTestConfig -} - -func initCSIHostpath(f *framework.Framework, config framework.VolumeTestConfig) csiTestDriver { - return &hostpathCSIDriver{ - combinedClusterRoleNames: []string{ - csiExternalAttacherClusterRoleName, - csiExternalProvisionerClusterRoleName, - csiDriverRegistrarClusterRoleName, - }, - f: f, - config: config, - } -} - -func (h *hostpathCSIDriver) createStorageClassTest(node v1.Node) testsuites.StorageClassTest { - return testsuites.StorageClassTest{ - Name: "csi-hostpath", - Provisioner: "csi-hostpath", - Parameters: map[string]string{}, - ClaimSize: "1Gi", - ExpectedSize: "1Gi", - NodeName: node.Name, - } -} - -func (h *hostpathCSIDriver) createCSIDriver() { - By("deploying csi hostpath driver") - f := h.f - cs := f.ClientSet - config := h.config - h.serviceAccount = csiServiceAccount(cs, config, "hostpath", false) - csiClusterRoleBindings(cs, config, false, h.serviceAccount, h.combinedClusterRoleNames) - role := csiControllerRole(cs, config, false) - csiControllerRoleBinding(cs, config, false, role, h.serviceAccount) - csiHostPathPod(cs, config, false, f, h.serviceAccount) -} - -func (h *hostpathCSIDriver) cleanupCSIDriver() { - By("uninstalling csi hostpath driver") - f := h.f - cs := f.ClientSet - config := h.config - csiHostPathPod(cs, config, true, f, h.serviceAccount) - csiClusterRoleBindings(cs, config, true, h.serviceAccount, h.combinedClusterRoleNames) - role := csiControllerRole(cs, config, true) - csiControllerRoleBinding(cs, config, true, role, h.serviceAccount) - csiServiceAccount(cs, config, "hostpath", true) -} - -type gcePDCSIDriver struct { - controllerClusterRoles []string - nodeClusterRoles []string - controllerServiceAccount *v1.ServiceAccount - nodeServiceAccount *v1.ServiceAccount - - f *framework.Framework - config framework.VolumeTestConfig -} - -func initCSIgcePD(f *framework.Framework, config framework.VolumeTestConfig) csiTestDriver { - cs := f.ClientSet - framework.SkipUnlessProviderIs("gce", "gke") - framework.SkipIfMultizone(cs) - - // TODO(#62561): Use credentials through external pod identity when that goes GA instead of downloading keys. - createGCESecrets(cs, config) - - framework.SkipUnlessSecretExistsAfterWait(cs, "cloud-sa", config.Namespace, 3*time.Minute) - - return &gcePDCSIDriver{ - nodeClusterRoles: []string{ - csiDriverRegistrarClusterRoleName, - }, - controllerClusterRoles: []string{ - csiExternalAttacherClusterRoleName, - csiExternalProvisionerClusterRoleName, - }, - f: f, - config: config, - } -} - -func (g *gcePDCSIDriver) createStorageClassTest(node v1.Node) testsuites.StorageClassTest { - return testsuites.StorageClassTest{ - Name: "com.google.csi.gcepd", - Provisioner: "com.google.csi.gcepd", - Parameters: map[string]string{"type": "pd-standard"}, - ClaimSize: "5Gi", - ExpectedSize: "5Gi", - NodeName: node.Name, - } -} - -func (g *gcePDCSIDriver) createCSIDriver() { - By("deploying gce-pd driver") - f := g.f - cs := f.ClientSet - config := g.config - g.controllerServiceAccount = csiServiceAccount(cs, config, "gce-controller", false /* teardown */) - g.nodeServiceAccount = csiServiceAccount(cs, config, "gce-node", false /* teardown */) - csiClusterRoleBindings(cs, config, false /* teardown */, g.controllerServiceAccount, g.controllerClusterRoles) - csiClusterRoleBindings(cs, config, false /* teardown */, g.nodeServiceAccount, g.nodeClusterRoles) - utils.PrivilegedTestPSPClusterRoleBinding(cs, config.Namespace, false, /* teardown */ - []string{g.controllerServiceAccount.Name, g.nodeServiceAccount.Name}) - role := csiControllerRole(cs, config, false) - csiControllerRoleBinding(cs, config, false, role, g.controllerServiceAccount) - deployGCEPDCSIDriver(cs, config, false /* teardown */, f, g.nodeServiceAccount, g.controllerServiceAccount) -} - -func (g *gcePDCSIDriver) cleanupCSIDriver() { - By("uninstalling gce-pd driver") - f := g.f - cs := f.ClientSet - config := g.config - deployGCEPDCSIDriver(cs, config, true /* teardown */, f, g.nodeServiceAccount, g.controllerServiceAccount) - csiClusterRoleBindings(cs, config, true /* teardown */, g.controllerServiceAccount, g.controllerClusterRoles) - csiClusterRoleBindings(cs, config, true /* teardown */, g.nodeServiceAccount, g.nodeClusterRoles) - utils.PrivilegedTestPSPClusterRoleBinding(cs, config.Namespace, true, /* teardown */ - []string{g.controllerServiceAccount.Name, g.nodeServiceAccount.Name}) - role := csiControllerRole(cs, config, true) - csiControllerRoleBinding(cs, config, true, role, g.controllerServiceAccount) - csiServiceAccount(cs, config, "gce-controller", true /* teardown */) - csiServiceAccount(cs, config, "gce-node", true /* teardown */) -} diff --git a/test/e2e/storage/drivers/BUILD b/test/e2e/storage/drivers/BUILD index 72beb967aaeea..487e0f218665b 100644 --- a/test/e2e/storage/drivers/BUILD +++ b/test/e2e/storage/drivers/BUILD @@ -4,6 +4,8 @@ go_library( name = "go_default_library", srcs = [ "base.go", + "csi.go", + "csi_objects.go", "in_tree.go", ], importpath = "k8s.io/kubernetes/test/e2e/storage/drivers", @@ -17,7 +19,9 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema: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/apiserver/pkg/authentication/serviceaccount:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//test/e2e/framework:go_default_library", "//test/e2e/storage/testpatterns:go_default_library", "//test/e2e/storage/utils:go_default_library", diff --git a/test/e2e/storage/drivers/csi.go b/test/e2e/storage/drivers/csi.go new file mode 100644 index 0000000000000..d32dee75a2c9f --- /dev/null +++ b/test/e2e/storage/drivers/csi.go @@ -0,0 +1,281 @@ +/* +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. +*/ + +/* + * This file defines various csi volume test drivers for TestSuites. + * + * There are two ways, how to prepare test drivers: + * 1) With containerized server (NFS, Ceph, Gluster, iSCSI, ...) + * It creates a server pod which defines one volume for the tests. + * These tests work only when privileged containers are allowed, exporting + * various filesystems (NFS, GlusterFS, ...) usually needs some mounting or + * other privileged magic in the server pod. + * + * Note that the server containers are for testing purposes only and should not + * be used in production. + * + * 2) With server or cloud provider outside of Kubernetes (Cinder, GCE, AWS, Azure, ...) + * Appropriate server or cloud provider must exist somewhere outside + * the tested Kubernetes cluster. CreateVolume will create a new volume to be + * used in the TestSuites for inlineVolume or DynamicPV tests. + */ + +package drivers + +import ( + "fmt" + "math/rand" + "time" + + . "github.com/onsi/ginkgo" + storagev1 "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/e2e/storage/testpatterns" + "k8s.io/kubernetes/test/e2e/storage/utils" +) + +// hostpathCSI +type hostpathCSIDriver struct { + cleanup func() + driverInfo DriverInfo +} + +var _ TestDriver = &hostpathCSIDriver{} +var _ DynamicPVTestDriver = &hostpathCSIDriver{} + +// InitHostPathCSIDriver returns hostpathCSIDriver that implements TestDriver interface +func InitHostPathCSIDriver() TestDriver { + return &hostpathCSIDriver{ + driverInfo: DriverInfo{ + Name: "csi-hostpath", + FeatureTag: "", + MaxFileSize: testpatterns.FileSizeMedium, + SupportedFsType: sets.NewString( + "", // Default fsType + ), + IsPersistent: true, + IsFsGroupSupported: false, + IsBlockSupported: false, + }, + } +} + +func (h *hostpathCSIDriver) GetDriverInfo() *DriverInfo { + return &h.driverInfo +} + +func (h *hostpathCSIDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { +} + +func (h *hostpathCSIDriver) GetDynamicProvisionStorageClass(fsType string) *storagev1.StorageClass { + provisioner := h.driverInfo.Name + h.driverInfo.Framework.UniqueName + parameters := map[string]string{} + ns := h.driverInfo.Framework.Namespace.Name + suffix := fmt.Sprintf("%s-sc", provisioner) + + return getStorageClass(provisioner, parameters, nil, ns, suffix) +} + +func (h *hostpathCSIDriver) CreateDriver() { + By("deploying csi hostpath driver") + f := h.driverInfo.Framework + cs := f.ClientSet + + // pods should be scheduled on the node + nodes := framework.GetReadySchedulableNodesOrDie(cs) + node := nodes.Items[rand.Intn(len(nodes.Items))] + h.driverInfo.Config.ClientNodeName = node.Name + h.driverInfo.Config.ServerNodeName = node.Name + + // TODO (?): the storage.csi.image.version and storage.csi.image.registry + // settings are ignored for this test. We could patch the image definitions. + o := utils.PatchCSIOptions{ + OldDriverName: h.driverInfo.Name, + NewDriverName: h.driverInfo.Name + h.driverInfo.Framework.UniqueName, + DriverContainerName: "hostpath", + ProvisionerContainerName: "csi-provisioner", + NodeName: h.driverInfo.Config.ServerNodeName, + } + cleanup, err := h.driverInfo.Framework.CreateFromManifests(func(item interface{}) error { + return utils.PatchCSIDeployment(h.driverInfo.Framework, o, item) + }, + "test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml", + "test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml", + "test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml", + "test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-attacher.yaml", + "test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-provisioner.yaml", + "test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpathplugin.yaml", + "test/e2e/testing-manifests/storage-csi/hostpath/hostpath/e2e-test-rbac.yaml", + ) + h.cleanup = cleanup + if err != nil { + framework.Failf("deploying csi hostpath driver: %v", err) + } +} + +func (h *hostpathCSIDriver) CleanupDriver() { + if h.cleanup != nil { + By("uninstalling csi hostpath driver") + h.cleanup() + } +} + +// gce-pd +type gcePDCSIDriver struct { + cleanup func() + driverInfo DriverInfo +} + +var _ TestDriver = &gcePDCSIDriver{} +var _ DynamicPVTestDriver = &gcePDCSIDriver{} + +// InitGcePDCSIDriver returns gcePDCSIDriver that implements TestDriver interface +func InitGcePDCSIDriver() TestDriver { + return &gcePDCSIDriver{ + driverInfo: DriverInfo{ + Name: "com.google.csi.gcepd", + FeatureTag: "[Serial]", + MaxFileSize: testpatterns.FileSizeMedium, + SupportedFsType: sets.NewString( + "", // Default fsType + "ext2", + "ext3", + "ext4", + "xfs", + ), + IsPersistent: true, + IsFsGroupSupported: true, + IsBlockSupported: false, + }, + } +} + +func (g *gcePDCSIDriver) GetDriverInfo() *DriverInfo { + return &g.driverInfo +} + +func (g *gcePDCSIDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { + f := g.driverInfo.Framework + cs := f.ClientSet + config := g.driverInfo.Config + framework.SkipUnlessProviderIs("gce", "gke") + framework.SkipIfMultizone(cs) + + // TODO(#62561): Use credentials through external pod identity when that goes GA instead of downloading keys. + createGCESecrets(cs, config) + framework.SkipUnlessSecretExistsAfterWait(cs, "cloud-sa", config.Namespace, 3*time.Minute) +} + +func (g *gcePDCSIDriver) GetDynamicProvisionStorageClass(fsType string) *storagev1.StorageClass { + ns := g.driverInfo.Framework.Namespace.Name + provisioner := g.driverInfo.Name + suffix := fmt.Sprintf("%s-sc", g.driverInfo.Name) + + parameters := map[string]string{"type": "pd-standard"} + + return getStorageClass(provisioner, parameters, nil, ns, suffix) +} + +func (g *gcePDCSIDriver) CreateDriver() { + By("deploying csi gce-pd driver") + // It would be safer to rename the gcePD driver, but that + // hasn't been done before either and attempts to do so now led to + // errors during driver registration, therefore it is disabled + // by passing a nil function below. + // + // These are the options which would have to be used: + // o := utils.PatchCSIOptions{ + // OldDriverName: "com.google.csi.gcepd", + // NewDriverName: "com.google.csi.gcepd-" + g.f.UniqueName, + // DriverContainerName: "gce-driver", + // ProvisionerContainerName: "csi-external-provisioner", + // } + cleanup, err := g.driverInfo.Framework.CreateFromManifests(nil, + "test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml", + "test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml", + "test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml", + "test/e2e/testing-manifests/storage-csi/gce-pd/csi-controller-rbac.yaml", + "test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml", + "test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml", + ) + g.cleanup = cleanup + if err != nil { + framework.Failf("deploying csi gce-pd driver: %v", err) + } +} + +func (g *gcePDCSIDriver) CleanupDriver() { + By("uninstalling gce-pd driver") + if g.cleanup != nil { + g.cleanup() + } +} + +// gcePd-external +type gcePDExternalCSIDriver struct { + driverInfo DriverInfo +} + +var _ TestDriver = &gcePDExternalCSIDriver{} +var _ DynamicPVTestDriver = &gcePDExternalCSIDriver{} + +// InitGcePDExternalCSIDriver returns gcePDExternalCSIDriver that implements TestDriver interface +func InitGcePDExternalCSIDriver() TestDriver { + return &gcePDExternalCSIDriver{ + driverInfo: DriverInfo{ + Name: "com.google.csi.gcepd", + // TODO(#70258): this is temporary until we can figure out how to make e2e tests a library + FeatureTag: "[Serial][Feature: gcePD-external]", + MaxFileSize: testpatterns.FileSizeMedium, + SupportedFsType: sets.NewString( + "", // Default fsType + "ext2", + "ext3", + "ext4", + "xfs", + ), + IsPersistent: true, + IsFsGroupSupported: true, + IsBlockSupported: false, + }, + } +} + +func (g *gcePDExternalCSIDriver) GetDriverInfo() *DriverInfo { + return &g.driverInfo +} + +func (g *gcePDExternalCSIDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { + framework.SkipUnlessProviderIs("gce", "gke") + framework.SkipIfMultizone(g.driverInfo.Framework.ClientSet) +} + +func (g *gcePDExternalCSIDriver) GetDynamicProvisionStorageClass(fsType string) *storagev1.StorageClass { + ns := g.driverInfo.Framework.Namespace.Name + provisioner := g.driverInfo.Name + suffix := fmt.Sprintf("%s-sc", g.driverInfo.Name) + + parameters := map[string]string{"type": "pd-standard"} + + return getStorageClass(provisioner, parameters, nil, ns, suffix) +} + +func (g *gcePDExternalCSIDriver) CreateDriver() { +} + +func (g *gcePDExternalCSIDriver) CleanupDriver() { +} diff --git a/test/e2e/storage/drivers/csi_objects.go b/test/e2e/storage/drivers/csi_objects.go new file mode 100644 index 0000000000000..cd3de2fce4003 --- /dev/null +++ b/test/e2e/storage/drivers/csi_objects.go @@ -0,0 +1,119 @@ +/* +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. +*/ + +// This file is used to deploy the CSI hostPath plugin +// More Information: https://github.com/kubernetes-csi/drivers/tree/master/pkg/hostpath + +package drivers + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/uuid" + + clientset "k8s.io/client-go/kubernetes" + "k8s.io/kubernetes/test/e2e/framework" +) + +var ( + csiImageVersion = flag.String("storage.csi.image.version", "", "overrides the default tag used for hostpathplugin/csi-attacher/csi-provisioner/driver-registrar images") + csiImageRegistry = flag.String("storage.csi.image.registry", "quay.io/k8scsi", "overrides the default repository used for hostpathplugin/csi-attacher/csi-provisioner/driver-registrar images") + csiImageVersions = map[string]string{ + "hostpathplugin": "v0.4.0", + "csi-attacher": "v0.4.0", + "csi-provisioner": "v0.4.0", + "driver-registrar": "v0.4.0", + } +) + +func csiContainerImage(image string) string { + var fullName string + fullName += *csiImageRegistry + "/" + image + ":" + if *csiImageVersion != "" { + fullName += *csiImageVersion + } else { + fullName += csiImageVersions[image] + } + return fullName +} + +func shredFile(filePath string) { + if _, err := os.Stat(filePath); os.IsNotExist(err) { + framework.Logf("File %v was not found, skipping shredding", filePath) + return + } + framework.Logf("Shredding file %v", filePath) + _, _, err := framework.RunCmd("shred", "--remove", filePath) + if err != nil { + framework.Logf("Failed to shred file %v: %v", filePath, err) + } + if _, err := os.Stat(filePath); os.IsNotExist(err) { + framework.Logf("File %v successfully shredded", filePath) + return + } + // Shred failed Try to remove the file for good meausure + err = os.Remove(filePath) + framework.ExpectNoError(err, "Failed to remove service account file %s", filePath) + +} + +// createGCESecrets downloads the GCP IAM Key for the default compute service account +// and puts it in a secret for the GCE PD CSI Driver to consume +func createGCESecrets(client clientset.Interface, config framework.VolumeTestConfig) { + saEnv := "E2E_GOOGLE_APPLICATION_CREDENTIALS" + saFile := fmt.Sprintf("/tmp/%s/cloud-sa.json", string(uuid.NewUUID())) + + os.MkdirAll(path.Dir(saFile), 0750) + defer os.Remove(path.Dir(saFile)) + + premadeSAFile, ok := os.LookupEnv(saEnv) + if !ok { + framework.Logf("Could not find env var %v, please either create cloud-sa"+ + " secret manually or rerun test after setting %v to the filepath of"+ + " the GCP Service Account to give to the GCE Persistent Disk CSI Driver", saEnv, saEnv) + return + } + + framework.Logf("Found CI service account key at %v", premadeSAFile) + // Need to copy it saFile + stdout, stderr, err := framework.RunCmd("cp", premadeSAFile, saFile) + framework.ExpectNoError(err, "error copying service account key: %s\nstdout: %s\nstderr: %s", err, stdout, stderr) + defer shredFile(saFile) + // Create Secret with this Service Account + fileBytes, err := ioutil.ReadFile(saFile) + framework.ExpectNoError(err, "Failed to read file %v", saFile) + + s := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cloud-sa", + Namespace: config.Namespace, + }, + Type: v1.SecretTypeOpaque, + Data: map[string][]byte{ + filepath.Base(saFile): fileBytes, + }, + } + + _, err = client.CoreV1().Secrets(config.Namespace).Create(s) + framework.ExpectNoError(err, "Failed to create Secret %v", s.GetName()) +} diff --git a/test/e2e/storage/drivers/in_tree.go b/test/e2e/storage/drivers/in_tree.go index da0da68039d0f..553581a806723 100644 --- a/test/e2e/storage/drivers/in_tree.go +++ b/test/e2e/storage/drivers/in_tree.go @@ -88,7 +88,7 @@ func InitNFSDriver() TestDriver { SupportedFsType: sets.NewString( "", // Default fsType ), - SupportedMountOption: sets.NewString("proto=tcp", "nosuid"), + SupportedMountOption: sets.NewString("proto=tcp", "relatime"), RequiredMountOption: sets.NewString("vers=4.1"), IsPersistent: true, IsFsGroupSupported: false, diff --git a/test/e2e/storage/flexvolume_mounted_volume_resize.go b/test/e2e/storage/flexvolume_mounted_volume_resize.go new file mode 100644 index 0000000000000..34e222547209d --- /dev/null +++ b/test/e2e/storage/flexvolume_mounted_volume_resize.go @@ -0,0 +1,171 @@ +/* +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 storage + +import ( + "fmt" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/api/core/v1" + storage "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + clientset "k8s.io/client-go/kubernetes" + "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/e2e/storage/utils" + "path" +) + +var _ = utils.SIGDescribe("Mounted flexvolume expand[Slow]", func() { + var ( + c clientset.Interface + ns string + err error + pvc *v1.PersistentVolumeClaim + resizableSc *storage.StorageClass + nodeName string + isNodeLabeled bool + nodeKeyValueLabel map[string]string + nodeLabelValue string + nodeKey string + ) + + f := framework.NewDefaultFramework("mounted-flexvolume-expand") + BeforeEach(func() { + framework.SkipUnlessProviderIs("aws", "gce", "local") + c = f.ClientSet + ns = f.Namespace.Name + framework.ExpectNoError(framework.WaitForAllNodesSchedulable(c, framework.TestContext.NodeSchedulableTimeout)) + + nodeList := framework.GetReadySchedulableNodesOrDie(f.ClientSet) + if len(nodeList.Items) != 0 { + nodeName = nodeList.Items[0].Name + } else { + framework.Failf("Unable to find ready and schedulable Node") + } + + nodeKey = "mounted_flexvolume_expand" + + if !isNodeLabeled { + nodeLabelValue = ns + nodeKeyValueLabel = make(map[string]string) + nodeKeyValueLabel[nodeKey] = nodeLabelValue + framework.AddOrUpdateLabelOnNode(c, nodeName, nodeKey, nodeLabelValue) + isNodeLabeled = true + } + + resizableSc, err = createStorageClass(ns, c) + if err != nil { + fmt.Printf("storage class creation error: %v\n", err) + } + Expect(err).NotTo(HaveOccurred(), "Error creating resizable storage class") + Expect(*resizableSc.AllowVolumeExpansion).To(BeTrue()) + + pvc = getClaim("2Gi", ns) + pvc.Spec.StorageClassName = &resizableSc.Name + pvc, err = c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Create(pvc) + Expect(err).NotTo(HaveOccurred(), "Error creating pvc") + }) + + framework.AddCleanupAction(func() { + if len(nodeLabelValue) > 0 { + framework.RemoveLabelOffNode(c, nodeName, nodeKey) + } + }) + + AfterEach(func() { + framework.Logf("AfterEach: Cleaning up resources for mounted volume resize") + + if c != nil { + if errs := framework.PVPVCCleanup(c, ns, nil, pvc); len(errs) > 0 { + framework.Failf("AfterEach: Failed to delete PVC and/or PV. Errors: %v", utilerrors.NewAggregate(errs)) + } + pvc, nodeName, isNodeLabeled, nodeLabelValue = nil, "", false, "" + nodeKeyValueLabel = make(map[string]string) + } + }) + + It("Should verify mounted flex volumes can be resized", func() { + driver := "dummy-attachable" + nodeList := framework.GetReadySchedulableNodesOrDie(f.ClientSet) + node := nodeList.Items[0] + By(fmt.Sprintf("installing flexvolume %s on node %s as %s", path.Join(driverDir, driver), node.Name, driver)) + installFlex(c, &node, "k8s", driver, path.Join(driverDir, driver)) + + pv := framework.MakePersistentVolume(framework.PersistentVolumeConfig{ + PVSource: v1.PersistentVolumeSource{ + FlexVolume: &v1.FlexPersistentVolumeSource{ + Driver: "k8s/" + driver, + }}, + NamePrefix: "pv-", + StorageClassName: resizableSc.Name, + VolumeMode: pvc.Spec.VolumeMode, + }) + + pv, err = framework.CreatePV(c, pv) + Expect(err).NotTo(HaveOccurred(), "Error creating pv %v", err) + + By("Waiting for PVC to be in bound phase") + pvcClaims := []*v1.PersistentVolumeClaim{pvc} + var pvs []*v1.PersistentVolume + + pvs, err = framework.WaitForPVClaimBoundPhase(c, pvcClaims, framework.ClaimProvisionTimeout) + Expect(err).NotTo(HaveOccurred(), "Failed waiting for PVC to be bound %v", err) + Expect(len(pvs)).To(Equal(1)) + + By("Creating a deployment with the provisioned volume") + deployment, err := framework.CreateDeployment(c, int32(1), map[string]string{"test": "app"}, nodeKeyValueLabel, ns, pvcClaims, "") + Expect(err).NotTo(HaveOccurred(), "Failed creating deployment %v", err) + defer c.AppsV1().Deployments(ns).Delete(deployment.Name, &metav1.DeleteOptions{}) + + By("Expanding current pvc") + newSize := resource.MustParse("6Gi") + pvc, err = expandPVCSize(pvc, newSize, c) + Expect(err).NotTo(HaveOccurred(), "While updating pvc for more size") + Expect(pvc).NotTo(BeNil()) + + pvcSize := pvc.Spec.Resources.Requests[v1.ResourceStorage] + if pvcSize.Cmp(newSize) != 0 { + framework.Failf("error updating pvc size %q", pvc.Name) + } + + By("Waiting for cloudprovider resize to finish") + err = waitForControllerVolumeResize(pvc, c) + Expect(err).NotTo(HaveOccurred(), "While waiting for pvc resize to finish") + + By("Getting a pod from deployment") + podList, err := framework.GetPodsForDeployment(c, deployment) + Expect(podList.Items).NotTo(BeEmpty()) + pod := podList.Items[0] + + By("Deleting the pod from deployment") + err = framework.DeletePodWithWait(f, c, &pod) + Expect(err).NotTo(HaveOccurred(), "while deleting pod for resizing") + + By("Waiting for deployment to create new pod") + pod, err = waitForDeploymentToRecreatePod(c, deployment) + Expect(err).NotTo(HaveOccurred(), "While waiting for pod to be recreated") + + By("Waiting for file system resize to finish") + pvc, err = waitForFSResize(pvc, c) + Expect(err).NotTo(HaveOccurred(), "while waiting for fs resize to finish") + + pvcConditions := pvc.Status.Conditions + Expect(len(pvcConditions)).To(Equal(0), "pvc should not have conditions") + }) +}) diff --git a/test/e2e/storage/flexvolume_online_resize.go b/test/e2e/storage/flexvolume_online_resize.go new file mode 100644 index 0000000000000..4157f1646327e --- /dev/null +++ b/test/e2e/storage/flexvolume_online_resize.go @@ -0,0 +1,174 @@ +/* +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 storage + +import ( + "fmt" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/api/core/v1" + storage "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/resource" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + clientset "k8s.io/client-go/kubernetes" + "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/e2e/storage/utils" + "path" +) + +func createStorageClass(ns string, c clientset.Interface) (*storage.StorageClass, error) { + bindingMode := storage.VolumeBindingImmediate + stKlass := getStorageClass("flex-expand", map[string]string{}, &bindingMode, ns, "resizing") + allowExpansion := true + stKlass.AllowVolumeExpansion = &allowExpansion + + var err error + stKlass, err = c.StorageV1().StorageClasses().Create(stKlass) + return stKlass, err +} + +var _ = utils.SIGDescribe("Mounted flexvolume volume expand [Slow] [Feature:ExpandInUsePersistentVolumes]", func() { + var ( + c clientset.Interface + ns string + err error + pvc *v1.PersistentVolumeClaim + resizableSc *storage.StorageClass + nodeName string + isNodeLabeled bool + nodeKeyValueLabel map[string]string + nodeLabelValue string + nodeKey string + nodeList *v1.NodeList + ) + + f := framework.NewDefaultFramework("mounted-flexvolume-expand") + BeforeEach(func() { + framework.SkipUnlessProviderIs("aws", "gce", "local") + c = f.ClientSet + ns = f.Namespace.Name + framework.ExpectNoError(framework.WaitForAllNodesSchedulable(c, framework.TestContext.NodeSchedulableTimeout)) + + nodeList = framework.GetReadySchedulableNodesOrDie(f.ClientSet) + if len(nodeList.Items) == 0 { + framework.Failf("unable to find ready and schedulable Node") + } + nodeName = nodeList.Items[0].Name + + nodeKey = "mounted_flexvolume_expand" + + if !isNodeLabeled { + nodeLabelValue = ns + nodeKeyValueLabel = make(map[string]string) + nodeKeyValueLabel[nodeKey] = nodeLabelValue + framework.AddOrUpdateLabelOnNode(c, nodeName, nodeKey, nodeLabelValue) + isNodeLabeled = true + } + + resizableSc, err = createStorageClass(ns, c) + if err != nil { + fmt.Printf("storage class creation error: %v\n", err) + } + Expect(err).NotTo(HaveOccurred(), "Error creating resizable storage class: %v", err) + Expect(*resizableSc.AllowVolumeExpansion).To(BeTrue()) + + pvc = getClaim("2Gi", ns) + pvc.Spec.StorageClassName = &resizableSc.Name + pvc, err = c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Create(pvc) + Expect(err).NotTo(HaveOccurred(), "Error creating pvc: %v", err) + + }) + + framework.AddCleanupAction(func() { + if len(nodeLabelValue) > 0 { + framework.RemoveLabelOffNode(c, nodeName, nodeKey) + } + }) + + AfterEach(func() { + framework.Logf("AfterEach: Cleaning up resources for mounted volume resize") + + if c != nil { + if errs := framework.PVPVCCleanup(c, ns, nil, pvc); len(errs) > 0 { + framework.Failf("AfterEach: Failed to delete PVC and/or PV. Errors: %v", utilerrors.NewAggregate(errs)) + } + pvc, nodeName, isNodeLabeled, nodeLabelValue = nil, "", false, "" + nodeKeyValueLabel = make(map[string]string) + } + }) + + It("should be resizable when mounted", func() { + driver := "dummy-attachable" + + node := nodeList.Items[0] + By(fmt.Sprintf("installing flexvolume %s on node %s as %s", path.Join(driverDir, driver), node.Name, driver)) + installFlex(c, &node, "k8s", driver, path.Join(driverDir, driver)) + + pv := framework.MakePersistentVolume(framework.PersistentVolumeConfig{ + PVSource: v1.PersistentVolumeSource{ + FlexVolume: &v1.FlexPersistentVolumeSource{ + Driver: "k8s/" + driver, + }}, + NamePrefix: "pv-", + StorageClassName: resizableSc.Name, + VolumeMode: pvc.Spec.VolumeMode, + }) + + pv, err = framework.CreatePV(c, pv) + Expect(err).NotTo(HaveOccurred(), "Error creating pv %v", err) + + By("Waiting for PVC to be in bound phase") + pvcClaims := []*v1.PersistentVolumeClaim{pvc} + var pvs []*v1.PersistentVolume + + pvs, err = framework.WaitForPVClaimBoundPhase(c, pvcClaims, framework.ClaimProvisionTimeout) + Expect(err).NotTo(HaveOccurred(), "Failed waiting for PVC to be bound %v", err) + Expect(len(pvs)).To(Equal(1)) + + var pod *v1.Pod + By("Creating pod") + pod, err = framework.CreateNginxPod(c, ns, nodeKeyValueLabel, pvcClaims) + Expect(err).NotTo(HaveOccurred(), "Failed to create pod %v", err) + defer framework.DeletePodWithWait(f, c, pod) + + By("Waiting for pod to go to 'running' state") + err = f.WaitForPodRunning(pod.ObjectMeta.Name) + Expect(err).NotTo(HaveOccurred(), "Pod didn't go to 'running' state %v", err) + + By("Expanding current pvc") + newSize := resource.MustParse("6Gi") + pvc, err = expandPVCSize(pvc, newSize, c) + Expect(err).NotTo(HaveOccurred(), "While updating pvc for more size") + Expect(pvc).NotTo(BeNil()) + + pvcSize := pvc.Spec.Resources.Requests[v1.ResourceStorage] + if pvcSize.Cmp(newSize) != 0 { + framework.Failf("error updating pvc size %q", pvc.Name) + } + + By("Waiting for cloudprovider resize to finish") + err = waitForControllerVolumeResize(pvc, c) + Expect(err).NotTo(HaveOccurred(), "While waiting for pvc resize to finish") + + By("Waiting for file system resize to finish") + pvc, err = waitForFSResize(pvc, c) + Expect(err).NotTo(HaveOccurred(), "while waiting for fs resize to finish") + + pvcConditions := pvc.Status.Conditions + Expect(len(pvcConditions)).To(Equal(0), "pvc should not have conditions") + }) +}) diff --git a/test/e2e/storage/in_tree_volumes.go b/test/e2e/storage/in_tree_volumes.go index 2906a17cecc72..6c6ea61368623 100644 --- a/test/e2e/storage/in_tree_volumes.go +++ b/test/e2e/storage/in_tree_volumes.go @@ -23,6 +23,7 @@ import ( "k8s.io/api/core/v1" "k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/storage/drivers" + "k8s.io/kubernetes/test/e2e/storage/testpatterns" "k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/utils" ) @@ -53,6 +54,10 @@ var testSuites = []func() testsuites.TestSuite{ testsuites.InitProvisioningTestSuite, } +func intreeTunePattern(patterns []testpatterns.TestPattern) []testpatterns.TestPattern { + return patterns +} + // This executes testSuites for in-tree volumes. var _ = utils.SIGDescribe("In-tree Volumes", func() { f := framework.NewDefaultFramework("volumes") @@ -86,7 +91,7 @@ var _ = utils.SIGDescribe("In-tree Volumes", func() { driver.CleanupDriver() }) - testsuites.RunTestSuite(f, config, driver, testSuites) + testsuites.RunTestSuite(f, config, driver, testSuites, intreeTunePattern) }) } }) diff --git a/test/e2e/storage/persistent_volumes-local.go b/test/e2e/storage/persistent_volumes-local.go index f4d066319ae47..e65089f614aec 100644 --- a/test/e2e/storage/persistent_volumes-local.go +++ b/test/e2e/storage/persistent_volumes-local.go @@ -1290,7 +1290,7 @@ func makeLocalPod(config *localTestConfig, volume *localTestVolume, cmd string) return pod } if volume.localVolumeType == BlockLocalVolumeType { - // Block e2e tests require utilities for writing to block devices (e.g. dd), and nginx has this utilites. + // Block e2e tests require utilities for writing to block devices (e.g. dd), and nginx has this utilities. pod.Spec.Containers[0].Image = imageutils.GetE2EImage(imageutils.Nginx) } return pod diff --git a/test/e2e/storage/regional_pd.go b/test/e2e/storage/regional_pd.go index 4c3a517721da5..bbd196b105109 100644 --- a/test/e2e/storage/regional_pd.go +++ b/test/e2e/storage/regional_pd.go @@ -24,20 +24,24 @@ import ( "strings" "time" + "encoding/json" + appsv1 "k8s.io/api/apps/v1" "k8s.io/api/core/v1" storage "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/strategicpatch" + "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/kubelet/apis" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" "k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/test/e2e/framework" - "k8s.io/kubernetes/test/e2e/framework/providers/gce" "k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/utils" imageutils "k8s.io/kubernetes/test/utils/image" @@ -46,6 +50,7 @@ import ( const ( pvDeletionTimeout = 3 * time.Minute statefulSetReadyTimeout = 3 * time.Minute + taintKeyPrefix = "zoneTaint_" ) var _ = utils.SIGDescribe("Regional PD", func() { @@ -144,9 +149,6 @@ func testVolumeProvisioning(c clientset.Interface, ns string) { } func testZonalFailover(c clientset.Interface, ns string) { - nodes := framework.GetReadySchedulableNodesOrDie(c) - nodeCount := len(nodes.Items) - cloudZones := getTwoRandomZones(c) class := newRegionalStorageClass(ns, cloudZones) claimTemplate := newClaimTemplate(ns) @@ -203,41 +205,40 @@ func testZonalFailover(c clientset.Interface, ns string) { Expect(err).ToNot(HaveOccurred()) podZone := node.Labels[apis.LabelZoneFailureDomain] - // TODO (verult) Consider using node taints to simulate zonal failure instead. - By("deleting instance group belonging to pod's zone") - - // Asynchronously detect a pod reschedule is triggered during/after instance group deletion. - waitStatus := make(chan error) - go func() { - waitStatus <- waitForStatefulSetReplicasNotReady(statefulSet.Name, ns, c) - }() - - cloud, err := gce.GetGCECloud() - if err != nil { - Expect(err).NotTo(HaveOccurred()) - } - instanceGroupName := framework.TestContext.CloudConfig.NodeInstanceGroup - instanceGroup, err := cloud.GetInstanceGroup(instanceGroupName, podZone) - Expect(err).NotTo(HaveOccurred(), - "Error getting instance group %s in zone %s", instanceGroupName, podZone) - templateName, err := framework.GetManagedInstanceGroupTemplateName(podZone) - Expect(err).NotTo(HaveOccurred(), - "Error getting instance group template in zone %s", podZone) - err = framework.DeleteManagedInstanceGroup(podZone) - Expect(err).NotTo(HaveOccurred(), - "Error deleting instance group in zone %s", podZone) + By("tainting nodes in the zone the pod is scheduled in") + selector := labels.SelectorFromSet(labels.Set(map[string]string{apis.LabelZoneFailureDomain: podZone})) + nodesInZone, err := c.CoreV1().Nodes().List(metav1.ListOptions{LabelSelector: selector.String()}) + Expect(err).ToNot(HaveOccurred()) + removeTaintFunc := addTaint(c, ns, nodesInZone.Items, podZone) defer func() { - framework.Logf("recreating instance group %s", instanceGroup.Name) - - framework.ExpectNoError(framework.CreateManagedInstanceGroup(instanceGroup.Size, podZone, templateName), - "Error recreating instance group %s in zone %s", instanceGroup.Name, podZone) - framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount, framework.RestartNodeReadyAgainTimeout), - "Error waiting for nodes from the new instance group to become ready.") + framework.Logf("removing previously added node taints") + removeTaintFunc() }() - err = <-waitStatus - Expect(err).ToNot(HaveOccurred(), "Error waiting for replica to be deleted during failover: %v", err) + By("deleting StatefulSet pod") + err = c.CoreV1().Pods(ns).Delete(pod.Name, &metav1.DeleteOptions{}) + + // Verify the pod is scheduled in the other zone. + By("verifying the pod is scheduled in a different zone.") + var otherZone string + if cloudZones[0] == podZone { + otherZone = cloudZones[1] + } else { + otherZone = cloudZones[0] + } + err = wait.PollImmediate(framework.Poll, statefulSetReadyTimeout, func() (bool, error) { + framework.Logf("checking whether new pod is scheduled in zone %q", otherZone) + pod = getPod(c, ns, regionalPDLabels) + nodeName = pod.Spec.NodeName + node, err = c.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{}) + if err != nil { + return false, nil + } + newPodZone := node.Labels[apis.LabelZoneFailureDomain] + return newPodZone == otherZone, nil + }) + Expect(err).NotTo(HaveOccurred(), "Error waiting for pod to be scheduled in a different zone (%q): %v", otherZone, err) err = framework.WaitForStatefulSetReplicasReady(statefulSet.Name, ns, c, 3*time.Second, framework.RestartPodReadyAgainTimeout) if err != nil { @@ -252,7 +253,6 @@ func testZonalFailover(c clientset.Interface, ns string) { "The same PVC should be used after failover.") By("verifying the container output has 2 lines, indicating the pod has been created twice using the same regional PD.") - pod = getPod(c, ns, regionalPDLabels) logs, err := framework.GetPodLogs(c, ns, pod.Name, "") Expect(err).NotTo(HaveOccurred(), "Error getting logs from pod %s in namespace %s", pod.Name, ns) @@ -261,21 +261,40 @@ func testZonalFailover(c clientset.Interface, ns string) { Expect(lineCount).To(Equal(expectedLineCount), "Line count of the written file should be %d.", expectedLineCount) - // Verify the pod is scheduled in the other zone. - By("verifying the pod is scheduled in a different zone.") - var otherZone string - if cloudZones[0] == podZone { - otherZone = cloudZones[1] - } else { - otherZone = cloudZones[0] +} + +func addTaint(c clientset.Interface, ns string, nodes []v1.Node, podZone string) (removeTaint func()) { + reversePatches := make(map[string][]byte) + for _, node := range nodes { + oldData, err := json.Marshal(node) + Expect(err).NotTo(HaveOccurred()) + + node.Spec.Taints = append(node.Spec.Taints, v1.Taint{ + Key: taintKeyPrefix + ns, + Value: podZone, + Effect: v1.TaintEffectNoSchedule, + }) + + newData, err := json.Marshal(node) + Expect(err).NotTo(HaveOccurred()) + + patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, v1.Node{}) + Expect(err).NotTo(HaveOccurred()) + + reversePatchBytes, err := strategicpatch.CreateTwoWayMergePatch(newData, oldData, v1.Node{}) + Expect(err).NotTo(HaveOccurred()) + reversePatches[node.Name] = reversePatchBytes + + _, err = c.CoreV1().Nodes().Patch(node.Name, types.StrategicMergePatchType, patchBytes) + Expect(err).ToNot(HaveOccurred()) } - nodeName = pod.Spec.NodeName - node, err = c.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{}) - Expect(err).ToNot(HaveOccurred()) - newPodZone := node.Labels[apis.LabelZoneFailureDomain] - Expect(newPodZone).To(Equal(otherZone), - "The pod should be scheduled in zone %s after all nodes in zone %s have been deleted", otherZone, podZone) + return func() { + for nodeName, reversePatch := range reversePatches { + _, err := c.CoreV1().Nodes().Patch(nodeName, types.StrategicMergePatchType, reversePatch) + Expect(err).ToNot(HaveOccurred()) + } + } } func testRegionalDelayedBinding(c clientset.Interface, ns string) { diff --git a/test/e2e/storage/testsuites/base.go b/test/e2e/storage/testsuites/base.go index fb8bde814f5e3..8d4f084989fd7 100644 --- a/test/e2e/storage/testsuites/base.go +++ b/test/e2e/storage/testsuites/base.go @@ -66,12 +66,12 @@ func getTestNameStr(suite TestSuite, pattern testpatterns.TestPattern) string { } // RunTestSuite runs all testpatterns of all testSuites for a driver -func RunTestSuite(f *framework.Framework, config framework.VolumeTestConfig, driver drivers.TestDriver, tsInits []func() TestSuite) { +func RunTestSuite(f *framework.Framework, config framework.VolumeTestConfig, driver drivers.TestDriver, tsInits []func() TestSuite, tunePatternFunc func([]testpatterns.TestPattern) []testpatterns.TestPattern) { for _, testSuiteInit := range tsInits { suite := testSuiteInit() - tsInfo := suite.getTestSuiteInfo() + patterns := tunePatternFunc(suite.getTestSuiteInfo().testPatterns) - for _, pattern := range tsInfo.testPatterns { + for _, pattern := range patterns { suite.execTest(driver, pattern) } } @@ -164,7 +164,7 @@ func (r *genericVolumeTestResource) setupResource(driver drivers.TestDriver, pat case testpatterns.DynamicPV: framework.Logf("Creating resource for dynamic PV") if dDriver, ok := driver.(drivers.DynamicPVTestDriver); ok { - claimSize := "2Gi" + claimSize := "5Gi" r.sc = dDriver.GetDynamicProvisionStorageClass(fsType) By("creating a StorageClass " + r.sc.Name) diff --git a/test/e2e/storage/testsuites/provisioning.go b/test/e2e/storage/testsuites/provisioning.go index 2047b4d846aa0..f897f54beb402 100644 --- a/test/e2e/storage/testsuites/provisioning.go +++ b/test/e2e/storage/testsuites/provisioning.go @@ -41,6 +41,7 @@ type StorageClassTest struct { Name string CloudProviders []string Provisioner string + StorageClassName string Parameters map[string]string DelayBinding bool ClaimSize string @@ -150,7 +151,7 @@ func (p *provisioningTestResource) setupResource(driver drivers.TestDriver, patt framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", driver.GetDriverInfo().Name) } p.driver = driver - p.claimSize = "2Gi" + p.claimSize = "5Gi" p.pvc = getClaim(p.claimSize, driver.GetDriverInfo().Framework.Namespace.Name) p.pvc.Spec.StorageClassName = &p.sc.Name framework.Logf("In creating storage class object and pvc object for driver - sc: %v, pvc: %v", p.sc, p.pvc) @@ -185,19 +186,6 @@ func testProvisioning(input *provisioningTestInput) { TestDynamicProvisioning(input.testCase, input.cs, input.pvc, input.sc) }) - It("should provision storage with non-default reclaim policy Retain", func() { - retain := v1.PersistentVolumeReclaimRetain - input.sc.ReclaimPolicy = &retain - pv := TestDynamicProvisioning(input.testCase, input.cs, input.pvc, input.sc) - - By(fmt.Sprintf("waiting for the provisioned PV %q to enter phase %s", pv.Name, v1.VolumeReleased)) - framework.ExpectNoError(framework.WaitForPersistentVolumePhase(v1.VolumeReleased, input.cs, pv.Name, 1*time.Second, 30*time.Second)) - - By(fmt.Sprintf("deleting the PV %q", pv.Name)) - framework.ExpectNoError(framework.DeletePersistentVolume(input.cs, pv.Name), "Failed to delete PV ", pv.Name) - framework.ExpectNoError(framework.WaitForPersistentVolumeDeleted(input.cs, pv.Name, 1*time.Second, 30*time.Second)) - }) - It("should create and delete block persistent volumes [Feature:BlockVolume]", func() { if !input.dInfo.IsBlockSupported { framework.Skipf("Driver %q does not support BlockVolume - skipping", input.dInfo.Name) @@ -292,6 +280,7 @@ func TestDynamicProvisioning(t StorageClassTest, client clientset.Interface, cla // Get entry, get mount options at 6th word, replace brackets with commas command += fmt.Sprintf(" && ( mount | grep 'on /mnt/test' | awk '{print $6}' | sed 's/^(/,/; s/)$/,/' | grep -q ,%s, )", option) } + command += " || (mount | grep 'on /mnt/test'; false)" runInPodWithVolume(client, claim.Namespace, claim.Name, t.NodeName, command) By("checking the created volume is readable and retains data") @@ -361,6 +350,12 @@ func runInPodWithVolume(c clientset.Interface, ns, claimName, nodeName, command pod, err := c.CoreV1().Pods(ns).Create(pod) framework.ExpectNoError(err, "Failed to create pod: %v", err) defer func() { + body, err := c.CoreV1().Pods(ns).GetLogs(pod.Name, &v1.PodLogOptions{}).Do().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.DeletePodOrFail(c, ns, pod.Name) }() framework.ExpectNoError(framework.WaitForPodSuccessInNamespaceSlow(c, pod.Name, pod.Namespace)) diff --git a/test/e2e/storage/testsuites/subpath.go b/test/e2e/storage/testsuites/subpath.go index b2ccfa29a75b1..619b1d545a0bf 100644 --- a/test/e2e/storage/testsuites/subpath.go +++ b/test/e2e/storage/testsuites/subpath.go @@ -19,6 +19,7 @@ package testsuites import ( "fmt" "path/filepath" + "regexp" "strings" "k8s.io/api/core/v1" @@ -315,7 +316,8 @@ func testSubPath(input *subPathTestInput) { }) It("should unmount if pod is force deleted while kubelet is down [Disruptive][Slow]", func() { - if input.volType == "hostPath" || input.volType == "hostPathSymlink" { + if strings.HasPrefix(input.volType, "hostPath") || strings.HasPrefix(input.volType, "csi-hostpath") { + // TODO: This skip should be removed once #61446 is fixed framework.Skipf("%s volume type does not support reconstruction, skipping", input.volType) } testSubpathReconstruction(input.f, input.pod, true) @@ -360,20 +362,6 @@ func testSubPath(input *subPathTestInput) { testReadFile(input.f, input.filePathInSubpath, input.pod, 0) }) - It("should fail for new directories when readOnly specified in the volumeSource [Slow]", func() { - if input.roVol == nil { - framework.Skipf("Volume type %v doesn't support readOnly source", input.volType) - } - - // Format the volume while it's writable - formatVolume(input.f, input.formatPod) - - // Set volume source to read only - input.pod.Spec.Volumes[0].VolumeSource = *input.roVol - // Pod should fail - testPodFailSubpathError(input.f, input.pod, "") - }) - // TODO: add a test case for the same disk with two partitions } @@ -394,10 +382,23 @@ func TestBasicSubpathFile(f *framework.Framework, contents string, pod *v1.Pod, Expect(err).NotTo(HaveOccurred(), "while deleting pod") } +func generateSuffixForPodName(s string) string { + // Pod name must: + // 1. consist of lower case alphanumeric characters or '-', + // 2. start and end with an alphanumeric character. + // (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?') + // Therefore, suffix is generated by following steps: + // 1. all strings other than [A-Za-z0-9] is replaced with "-", + // 2. add lower case alphanumeric characters at the end ('-[a-z0-9]{4}' is added), + // 3. convert the entire strings to lower case. + re := regexp.MustCompile("[^A-Za-z0-9]") + return strings.ToLower(fmt.Sprintf("%s-%s", re.ReplaceAllString(s, "-"), rand.String(4))) +} + // SubpathTestPod returns a pod spec for subpath tests func SubpathTestPod(f *framework.Framework, subpath, volumeType string, source *v1.VolumeSource, privilegedSecurityContext bool) *v1.Pod { var ( - suffix = strings.ToLower(fmt.Sprintf("%s-%s", volumeType, rand.String(4))) + suffix = generateSuffixForPodName(volumeType) gracePeriod = int64(1) probeVolumeName = "liveness-probe-volume" ) diff --git a/test/e2e/storage/testsuites/volumemode.go b/test/e2e/storage/testsuites/volumemode.go index cd9992fe1532b..360097b66f2bd 100644 --- a/test/e2e/storage/testsuites/volumemode.go +++ b/test/e2e/storage/testsuites/volumemode.go @@ -197,7 +197,7 @@ func (s *volumeModeTestResource) setupResource(driver drivers.TestDriver, patter } s.sc.VolumeBindingMode = &volBindMode - claimSize := "2Gi" + claimSize := "5Gi" s.pvc = getClaim(claimSize, ns.Name) s.pvc.Spec.StorageClassName = &s.sc.Name s.pvc.Spec.VolumeMode = &volMode diff --git a/test/e2e/storage/utils/BUILD b/test/e2e/storage/utils/BUILD index ffcca6254eb48..fe99be305f30e 100644 --- a/test/e2e/storage/utils/BUILD +++ b/test/e2e/storage/utils/BUILD @@ -8,13 +8,16 @@ load( go_library( name = "go_default_library", srcs = [ + "deployment.go", "framework.go", "utils.go", ], importpath = "k8s.io/kubernetes/test/e2e/storage/utils", deps = [ + "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/rbac/v1:go_default_library", + "//staging/src/k8s.io/api/storage/v1: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/util/wait:go_default_library", diff --git a/test/e2e/storage/utils/deployment.go b/test/e2e/storage/utils/deployment.go new file mode 100644 index 0000000000000..49d0f2ea6eb51 --- /dev/null +++ b/test/e2e/storage/utils/deployment.go @@ -0,0 +1,147 @@ +/* +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 utils + +import ( + "path" + "strings" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" + storagev1 "k8s.io/api/storage/v1" + "k8s.io/kubernetes/test/e2e/framework" +) + +// PatchCSIDeployment modifies the CSI driver deployment: +// - replaces the provisioner name +// - forces pods onto a specific host +// +// All of that is optional, see PatchCSIOptions. Just beware +// that not renaming the CSI driver deployment can be problematic: +// - when multiple tests deploy the driver, they need +// to run sequentially +// - might conflict with manual deployments +// +// This function is written so that it works for CSI driver deployments +// that follow these conventions: +// - driver and provisioner names are identical +// - the driver binary accepts a --drivername parameter +// - the provisioner binary accepts a --provisioner parameter +// - the paths inside the container are either fixed +// and don't need to be patch (for example, --csi-address=/csi/csi.sock is +// okay) or are specified directly in a parameter (for example, +// --kubelet-registration-path=/var/lib/kubelet/plugins/csi-hostpath/csi.sock) +// +// Driver deployments that are different will have to do the patching +// without this function, or skip patching entirely. +// +// TODO (?): the storage.csi.image.version and storage.csi.image.registry +// settings are ignored. We could patch the image definitions or deprecate +// those options. +func PatchCSIDeployment(f *framework.Framework, o PatchCSIOptions, object interface{}) error { + rename := o.OldDriverName != "" && o.NewDriverName != "" && + o.OldDriverName != o.NewDriverName + + patchVolumes := func(volumes []v1.Volume) { + if !rename { + return + } + for i := range volumes { + volume := &volumes[i] + if volume.HostPath != nil { + // Update paths like /var/lib/kubelet/plugins/. + p := &volume.HostPath.Path + dir, file := path.Split(*p) + if file == o.OldDriverName { + *p = path.Join(dir, o.NewDriverName) + } + } + } + } + + patchContainers := func(containers []v1.Container) { + for i := range containers { + container := &containers[i] + if rename { + for e := range container.Args { + // Inject test-specific provider name into paths like this one: + // --kubelet-registration-path=/var/lib/kubelet/plugins/csi-hostpath/csi.sock + container.Args[e] = strings.Replace(container.Args[e], "/"+o.OldDriverName+"/", "/"+o.NewDriverName+"/", 1) + } + } + // Overwrite driver name resp. provider name + // by appending a parameter with the right + // value. + switch container.Name { + case o.DriverContainerName: + container.Args = append(container.Args, "--drivername="+o.NewDriverName) + case o.ProvisionerContainerName: + // Driver name is expected to be the same + // as the provisioner here. + container.Args = append(container.Args, "--provisioner="+o.NewDriverName) + } + } + } + + patchPodSpec := func(spec *v1.PodSpec) { + patchContainers(spec.Containers) + patchVolumes(spec.Volumes) + if o.NodeName != "" { + spec.NodeName = o.NodeName + } + } + + switch object := object.(type) { + case *appsv1.ReplicaSet: + patchPodSpec(&object.Spec.Template.Spec) + case *appsv1.DaemonSet: + patchPodSpec(&object.Spec.Template.Spec) + case *appsv1.StatefulSet: + patchPodSpec(&object.Spec.Template.Spec) + case *appsv1.Deployment: + patchPodSpec(&object.Spec.Template.Spec) + case *storagev1.StorageClass: + if o.NewDriverName != "" { + // Driver name is expected to be the same + // as the provisioner name here. + object.Provisioner = o.NewDriverName + } + } + + return nil +} + +// PatchCSIOptions controls how PatchCSIDeployment patches the objects. +type PatchCSIOptions struct { + // The original driver name. + OldDriverName string + // The driver name that replaces the original name. + // Can be empty (not used at all) or equal to OldDriverName + // (then it will be added were appropriate without renaming + // in existing fields). + NewDriverName string + // The name of the container which has the CSI driver binary. + // If non-empty, --drivername with the new name will be + // appended to the argument list. + DriverContainerName string + // The name of the container which has the provisioner binary. + // If non-empty, --provisioner with new name will be appended + // to the argument list. + ProvisionerContainerName string + // If non-empty, all pods are forced to run on this node. + NodeName string +} diff --git a/test/e2e/storage/volume_provisioning.go b/test/e2e/storage/volume_provisioning.go index 53079e5ea7fc9..cde6712dc5c25 100644 --- a/test/e2e/storage/volume_provisioning.go +++ b/test/e2e/storage/volume_provisioning.go @@ -427,6 +427,40 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() { } }) + It("should provision storage with non-default reclaim policy Retain", func() { + framework.SkipUnlessProviderIs("gce", "gke") + + test := testsuites.StorageClassTest{ + Name: "HDD PD on GCE/GKE", + CloudProviders: []string{"gce", "gke"}, + Provisioner: "kubernetes.io/gce-pd", + Parameters: map[string]string{ + "type": "pd-standard", + }, + ClaimSize: "1Gi", + ExpectedSize: "1Gi", + PvCheck: func(volume *v1.PersistentVolume) error { + return checkGCEPD(volume, "pd-standard") + }, + } + class := newStorageClass(test, ns, "reclaimpolicy") + retain := v1.PersistentVolumeReclaimRetain + class.ReclaimPolicy = &retain + claim := newClaim(test, ns, "reclaimpolicy") + claim.Spec.StorageClassName = &class.Name + pv := testsuites.TestDynamicProvisioning(test, c, claim, class) + + By(fmt.Sprintf("waiting for the provisioned PV %q to enter phase %s", pv.Name, v1.VolumeReleased)) + framework.ExpectNoError(framework.WaitForPersistentVolumePhase(v1.VolumeReleased, c, pv.Name, 1*time.Second, 30*time.Second)) + + By(fmt.Sprintf("deleting the storage asset backing the PV %q", pv.Name)) + framework.ExpectNoError(framework.DeletePDWithRetry(pv.Spec.GCEPersistentDisk.PDName)) + + By(fmt.Sprintf("deleting the PV %q", pv.Name)) + framework.ExpectNoError(framework.DeletePersistentVolume(c, pv.Name), "Failed to delete PV ", pv.Name) + framework.ExpectNoError(framework.WaitForPersistentVolumeDeleted(c, pv.Name, 1*time.Second, 30*time.Second)) + }) + It("should not provision a volume in an unmanaged GCE zone.", func() { framework.SkipUnlessProviderIs("gce", "gke") var suffix string = "unmananged" diff --git a/test/e2e/testing-manifests/flexvolume/dummy-attachable b/test/e2e/testing-manifests/flexvolume/dummy-attachable index 07cb995db2b42..2c47faaf3fe35 100755 --- a/test/e2e/testing-manifests/flexvolume/dummy-attachable +++ b/test/e2e/testing-manifests/flexvolume/dummy-attachable @@ -90,11 +90,23 @@ unmountdevice() { exit 0 } +expandvolume() { + debug "expandvolume $@" + log "{\"status\":\"Success\"}" + exit 0 +} + +expandfs() { + debug "expandfs $@" + log "{\"status\":\"Success\"}" + exit 0 +} + op=$1 if [ "$op" = "init" ]; then debug "init $@" - log "{\"status\":\"Success\",\"capabilities\":{\"attach\":true}}" + log "{\"status\":\"Success\",\"capabilities\":{\"attach\":true, \"requiresFSResize\":true}}" exit 0 fi @@ -119,6 +131,12 @@ case "$op" in unmountdevice) unmountdevice $* ;; + expandvolume) + expandvolume $* + ;; + expandfs) + expandfs $* + ;; *) log "{\"status\":\"Not supported\"}" exit 0 diff --git a/test/e2e/testing-manifests/statefulset/redis/service.yaml b/test/e2e/testing-manifests/statefulset/redis/service.yaml index bfdc346557562..528ef6dad5724 100644 --- a/test/e2e/testing-manifests/statefulset/redis/service.yaml +++ b/test/e2e/testing-manifests/statefulset/redis/service.yaml @@ -13,3 +13,4 @@ spec: clusterIP: None selector: app: redis + publishNotReadyAddresses: true diff --git a/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml b/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml index b2ca79d7990c4..b099b9c087802 100644 --- a/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml +++ b/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml @@ -15,7 +15,7 @@ spec: spec: initContainers: - name: install - image: gcr.io/kubernetes-e2e-test-images/pets/redis-installer:1.1 + image: gcr.io/kubernetes-e2e-test-images/pets/redis-installer:1.2 imagePullPolicy: Always args: - "--install-into=/opt" diff --git a/test/e2e/testing-manifests/statefulset/zookeeper/statefulset.yaml b/test/e2e/testing-manifests/statefulset/zookeeper/statefulset.yaml index 90398e772f734..3dd19fc51d503 100644 --- a/test/e2e/testing-manifests/statefulset/zookeeper/statefulset.yaml +++ b/test/e2e/testing-manifests/statefulset/zookeeper/statefulset.yaml @@ -15,7 +15,7 @@ spec: spec: initContainers: - name: install - image: gcr.io/kubernetes-e2e-test-images/pets/zookeeper-installer:1.1 + image: gcr.io/kubernetes-e2e-test-images/pets/zookeeper-installer:1.2 imagePullPolicy: Always args: - "--install-into=/opt" diff --git a/test/e2e/testing-manifests/storage-csi/controller-role.yaml b/test/e2e/testing-manifests/storage-csi/controller-role.yaml index 765ddab708dee..4efd6bc98deec 100644 --- a/test/e2e/testing-manifests/storage-csi/controller-role.yaml +++ b/test/e2e/testing-manifests/storage-csi/controller-role.yaml @@ -1,11 +1,3 @@ -# Role for external CSI provisioner and attacher. -# They need to modify Endpoints and ConfigMap for leader election. - -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-controller -rules: -- apiGroups: [""] - resources: ["configmaps", "endpoints"] - verbs: ["get", "watch", "list", "delete", "update", "create"] +# Replaced by individual roles for external-attacher and external-provisioner: +# - https://github.com/kubernetes-csi/external-attacher/blob/master/deploy/kubernetes/rbac.yaml +# - https://github.com/kubernetes-csi/external-provisioner/blob/master/deploy/kubernetes/rbac.yaml diff --git a/test/e2e/testing-manifests/storage-csi/driver-registrar/README.md b/test/e2e/testing-manifests/storage-csi/driver-registrar/README.md new file mode 100644 index 0000000000000..f6566a99a5026 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/driver-registrar/README.md @@ -0,0 +1 @@ +The original file is (or will be) https://github.com/kubernetes-csi/driver-registrar/blob/master/deploy/kubernetes/rbac.yaml diff --git a/test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml b/test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml new file mode 100644 index 0000000000000..a4f4f1aaceff5 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml @@ -0,0 +1,51 @@ +# This YAML file contains all RBAC objects that are necessary to run external +# CSI provisioner. +# +# In production, each CSI driver deployment has to be customized: +# - to avoid conflicts, use non-default namespace and different names +# for non-namespaced entities like the ClusterRole +# - decide whether the deployment replicates the external CSI +# provisioner, in which case leadership election must be enabled; +# this influences the RBAC setup, see below + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-driver-registrar + # replace with non-default namespace name + namespace: default + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: driver-registrar-runner +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + # The following permissions are only needed when running + # driver-registrar without the --kubelet-registration-path + # parameter, i.e. when using driver-registrar instead of + # kubelet to update the csi.volume.kubernetes.io/nodeid + # annotation. That mode of operation is going to be deprecated + # and should not be used anymore, but is needed on older + # Kubernetes versions. + # - apiGroups: [""] + # resources: ["nodes"] + # verbs: ["get", "update", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-driver-registrar-role +subjects: + - kind: ServiceAccount + name: csi-driver-registrar + # replace with non-default namespace name + namespace: default +roleRef: + kind: ClusterRole + name: driver-registrar-runner + apiGroup: rbac.authorization.k8s.io diff --git a/test/e2e/testing-manifests/storage-csi/external-attacher/README.md b/test/e2e/testing-manifests/storage-csi/external-attacher/README.md new file mode 100644 index 0000000000000..705533f591415 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/external-attacher/README.md @@ -0,0 +1 @@ +The original file is (or will be) https://github.com/kubernetes-csi/external-attacher/blob/master/deploy/kubernetes/rbac.yaml diff --git a/test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml b/test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml new file mode 100644 index 0000000000000..18f1eff454fa6 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml @@ -0,0 +1,82 @@ +# This YAML file contains all RBAC objects that are necessary to run external +# CSI attacher. +# +# In production, each CSI driver deployment has to be customized: +# - to avoid conflicts, use non-default namespace and different names +# for non-namespaced entities like the ClusterRole +# - decide whether the deployment replicates the external CSI +# attacher, in which case leadership election must be enabled; +# this influences the RBAC setup, see below + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-attacher + # replace with non-default namespace name + namespace: default + +--- +# Attacher must be able to work with PVs, nodes and VolumeAttachments +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: external-attacher-runner +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["csi.storage.k8s.io"] + resources: ["csinodeinfos"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-attacher-role +subjects: + - kind: ServiceAccount + name: csi-attacher + # replace with non-default namespace name + namespace: default +roleRef: + kind: ClusterRole + name: external-attacher-runner + apiGroup: rbac.authorization.k8s.io + +--- +# Attacher must be able to work with config map in current namespace +# if (and only if) leadership election is enabled +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + # replace with non-default namespace name + namespace: default + name: external-attacher-cfg +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-attacher-role-cfg + # replace with non-default namespace name + namespace: default +subjects: + - kind: ServiceAccount + name: csi-attacher + # replace with non-default namespace name + namespace: default +roleRef: + kind: Role + name: external-attacher-cfg + apiGroup: rbac.authorization.k8s.io diff --git a/test/e2e/testing-manifests/storage-csi/external-provisioner/README.md b/test/e2e/testing-manifests/storage-csi/external-provisioner/README.md new file mode 100644 index 0000000000000..adc2091df06a8 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/external-provisioner/README.md @@ -0,0 +1 @@ +The original file is (or will be) https://github.com/kubernetes-csi/external-provisioner/blob/master/deploy/kubernetes/rbac.yaml diff --git a/test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml b/test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml new file mode 100644 index 0000000000000..65bd2e42e9703 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml @@ -0,0 +1,90 @@ +# This YAML file contains all RBAC objects that are necessary to run external +# CSI provisioner. +# +# In production, each CSI driver deployment has to be customized: +# - to avoid conflicts, use non-default namespace and different names +# for non-namespaced entities like the ClusterRole +# - decide whether the deployment replicates the external CSI +# provisioner, in which case leadership election must be enabled; +# this influences the RBAC setup, see below + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-provisioner + # replace with non-default namespace name + namespace: default + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: external-provisioner-runner +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-provisioner-role +subjects: + - kind: ServiceAccount + name: csi-provisioner + # replace with non-default namespace name + namespace: default +roleRef: + kind: ClusterRole + name: external-provisioner-runner + apiGroup: rbac.authorization.k8s.io + +--- +# Provisioner must be able to work with endpoints in current namespace +# if (and only if) leadership election is enabled +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + # replace with non-default namespace name + namespace: default + name: external-provisioner-cfg +rules: +- apiGroups: [""] + resources: ["endpoints"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-provisioner-role-cfg + # replace with non-default namespace name + namespace: default +subjects: + - kind: ServiceAccount + name: csi-provisioner + # replace with non-default namespace name + namespace: default +roleRef: + kind: Role + name: external-provisioner-cfg + apiGroup: rbac.authorization.k8s.io diff --git a/test/e2e/testing-manifests/storage-csi/gce-pd/controller_service.yaml b/test/e2e/testing-manifests/storage-csi/gce-pd/controller_service.yaml deleted file mode 100644 index 6c509b2fd08ae..0000000000000 --- a/test/e2e/testing-manifests/storage-csi/gce-pd/controller_service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - name: csi-gce-pd - labels: - app: csi-gce-pd -spec: - selector: - app: csi-gce-pd - ports: - - name: dummy - port: 12345 diff --git a/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml b/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml index 82c153f5a1a82..0cb4476d4bef6 100644 --- a/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml +++ b/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml @@ -1,5 +1,5 @@ kind: StatefulSet -apiVersion: apps/v1beta1 +apiVersion: apps/v1 metadata: name: csi-gce-controller spec: @@ -13,46 +13,34 @@ spec: labels: app: csi-gce-pd-driver spec: + serviceAccountName: csi-controller containers: - name: csi-external-provisioner imagePullPolicy: Always - image: quay.io/k8scsi/csi-provisioner:v0.2.0 + image: gcr.io/gke-release/csi-provisioner:v0.4.1-gke.0 args: - "--v=5" - "--provisioner=com.google.csi.gcepd" - - "--csi-address=$(ADDRESS)" - env: - - name: ADDRESS - value: /csi/csi.sock + - "--csi-address=/csi/csi.sock" volumeMounts: - name: socket-dir mountPath: /csi - name: csi-attacher imagePullPolicy: Always - image: quay.io/k8scsi/csi-attacher:v0.2.0 + image: gcr.io/gke-release/csi-attacher:v0.4.1-gke.0 args: - "--v=5" - - "--csi-address=$(ADDRESS)" - env: - - name: ADDRESS - value: /csi/csi.sock + - "--csi-address=/csi/csi.sock" volumeMounts: - name: socket-dir mountPath: /csi - name: gce-driver imagePullPolicy: Always - image: gcr.io/google-containers/volume-csi/gcp-compute-persistent-disk-csi-driver:v0.1.0.alpha + image: gcr.io/gke-release/gcp-compute-persistent-disk-csi-driver:v0.2.0-gke.0 args: - "--v=5" - - "--endpoint=$(CSI_ENDPOINT)" - - "--nodeid=$(KUBE_NODE_NAME)" + - "--endpoint=unix:///csi/csi.sock" env: - - name: CSI_ENDPOINT - value: unix:///csi/csi.sock - - name: KUBE_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - name: GOOGLE_APPLICATION_CREDENTIALS value: "/etc/service-account/cloud-sa.json" volumeMounts: diff --git a/test/e2e/testing-manifests/storage-csi/gce-pd/csi-controller-rbac.yaml b/test/e2e/testing-manifests/storage-csi/gce-pd/csi-controller-rbac.yaml new file mode 100644 index 0000000000000..2e143302f9ec7 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/gce-pd/csi-controller-rbac.yaml @@ -0,0 +1,78 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-controller + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-controller-attacher-role +subjects: + - kind: ServiceAccount + name: csi-controller + namespace: default +roleRef: + kind: ClusterRole + name: external-attacher-runner + apiGroup: rbac.authorization.k8s.io + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-controller-attacher-role-cfg + namespace: default +subjects: + - kind: ServiceAccount + name: csi-controller + namespace: default +roleRef: + kind: Role + name: external-attacher-cfg + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-controller-provisioner-role +subjects: + - kind: ServiceAccount + name: csi-controller + namespace: default +roleRef: + kind: ClusterRole + name: external-provisioner-runner + apiGroup: rbac.authorization.k8s.io + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-controller-provisioner-role-cfg + namespace: default +subjects: + - kind: ServiceAccount + name: csi-controller + namespace: default +roleRef: + kind: Role + name: external-provisioner-cfg + +--- +# priviledged Pod Security Policy, previously defined via PrivilegedTestPSPClusterRoleBinding() +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: psp-csi-controller-driver-registrar-role +subjects: + - kind: ServiceAccount + name: csi-controller + namespace: default + - kind: ServiceAccount + name: csi-driver-registrar + namespace: default +roleRef: + kind: ClusterRole + name: e2e-test-privileged-psp + apiGroup: rbac.authorization.k8s.io diff --git a/test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml b/test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml index 85be59f7a1159..9c0a8b8d3f0fe 100644 --- a/test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml +++ b/test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml @@ -12,19 +12,16 @@ spec: labels: app: csi-gce-driver spec: + serviceAccountName: csi-driver-registrar containers: - name: csi-driver-registrar imagePullPolicy: Always - image: quay.io/k8scsi/driver-registrar:v0.3.0 + image: gcr.io/gke-release/csi-driver-registrar:v0.4.1-gke.0 args: - "--v=5" - - "--csi-address=$(ADDRESS)" - - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + - "--csi-address=/csi/csi.sock" + - "--kubelet-registration-path=/var/lib/kubelet/plugins/com.google.csi.gcepd/csi.sock" env: - - name: ADDRESS - value: /csi/csi.sock - - name: DRIVER_REG_SOCK_PATH - value: /var/lib/kubelet/plugins/com.google.csi.gcepd/csi.sock - name: KUBE_NODE_NAME valueFrom: fieldRef: @@ -38,18 +35,10 @@ spec: securityContext: privileged: true imagePullPolicy: Always - image: gcr.io/google-containers/volume-csi/gcp-compute-persistent-disk-csi-driver:v0.1.0.alpha + image: gcr.io/gke-release/gcp-compute-persistent-disk-csi-driver:v0.2.0-gke.0 args: - "--v=5" - - "--endpoint=$(CSI_ENDPOINT)" - - "--nodeid=$(KUBE_NODE_NAME)" - env: - - name: CSI_ENDPOINT - value: unix:///csi/csi.sock - - name: KUBE_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName + - "--endpoint=unix:///csi/csi.sock" volumeMounts: - name: kubelet-dir mountPath: /var/lib/kubelet @@ -57,8 +46,21 @@ spec: - name: plugin-dir mountPath: /csi - name: device-dir - mountPath: /host/dev + mountPath: /dev + # The following mounts are required to trigger host udevadm from container + - name: udev-rules-etc + mountPath: /etc/udev + - name: udev-rules-lib + mountPath: /lib/udev + - name: udev-socket + mountPath: /run/udev + - name: sys + mountPath: /sys volumes: + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins/ + type: Directory - name: kubelet-dir hostPath: path: /var/lib/kubelet @@ -67,11 +69,25 @@ spec: hostPath: path: /var/lib/kubelet/plugins/com.google.csi.gcepd/ type: DirectoryOrCreate - - name: registration-dir - hostPath: - path: /var/lib/kubelet/plugins/ - type: Directory - name: device-dir hostPath: path: /dev type: Directory + # The following mounts are required to trigger host udevadm from container + - name: udev-rules-etc + hostPath: + path: /etc/udev + type: Directory + - name: udev-rules-lib + hostPath: + path: /lib/udev + type: Directory + - name: udev-socket + hostPath: + path: /run/udev + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + diff --git a/test/e2e/testing-manifests/storage-csi/hostpath/README.md b/test/e2e/testing-manifests/storage-csi/hostpath/README.md new file mode 100644 index 0000000000000..6a46c1177dfa3 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/hostpath/README.md @@ -0,0 +1,5 @@ +A partial copy of https://github.com/kubernetes-csi/docs/tree/master/book/src/example, +with some modifications: +- serviceAccountName is used instead of the deprecated serviceAccount +- the RBAC roles from driver-registrar, external-attacher and external-provisioner + are used diff --git a/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-attacher.yaml b/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-attacher.yaml new file mode 100644 index 0000000000000..6fe198bd3abcc --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-attacher.yaml @@ -0,0 +1,48 @@ +kind: Service +apiVersion: v1 +metadata: + name: csi-hostpath-attacher + labels: + app: csi-hostpath-attacher +spec: + selector: + app: csi-hostpath-attacher + ports: + - name: dummy + port: 12345 + +--- +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: csi-hostpath-attacher +spec: + serviceName: "csi-hostpath-attacher" + replicas: 1 + selector: + matchLabels: + app: csi-hostpath-attacher + template: + metadata: + labels: + app: csi-hostpath-attacher + spec: + serviceAccountName: csi-attacher + containers: + - name: csi-attacher + image: quay.io/k8scsi/csi-attacher:v0.4.1 + args: + - --v=5 + - --csi-address=$(ADDRESS) + env: + - name: ADDRESS + value: /csi/csi.sock + imagePullPolicy: Always + volumeMounts: + - mountPath: /csi + name: socket-dir + volumes: + - hostPath: + path: /var/lib/kubelet/plugins/csi-hostpath + type: DirectoryOrCreate + name: socket-dir diff --git a/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-provisioner.yaml b/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-provisioner.yaml new file mode 100644 index 0000000000000..84b2c05baadb7 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-provisioner.yaml @@ -0,0 +1,49 @@ +kind: Service +apiVersion: v1 +metadata: + name: csi-hostpath-provisioner + labels: + app: csi-hostpath-provisioner +spec: + selector: + app: csi-hostpath-provisioner + ports: + - name: dummy + port: 12345 + +--- +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: csi-hostpath-provisioner +spec: + serviceName: "csi-hostpath-provisioner" + replicas: 1 + selector: + matchLabels: + app: csi-hostpath-provisioner + template: + metadata: + labels: + app: csi-hostpath-provisioner + spec: + serviceAccountName: csi-provisioner + containers: + - name: csi-provisioner + image: quay.io/k8scsi/csi-provisioner:v0.4.1 + args: + - "--provisioner=csi-hostpath" + - "--csi-address=$(ADDRESS)" + - "--connection-timeout=15s" + env: + - name: ADDRESS + value: /csi/csi.sock + imagePullPolicy: Always + volumeMounts: + - mountPath: /csi + name: socket-dir + volumes: + - hostPath: + path: /var/lib/kubelet/plugins/csi-hostpath + type: DirectoryOrCreate + name: socket-dir diff --git a/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpathplugin.yaml b/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpathplugin.yaml new file mode 100644 index 0000000000000..f7c326b4a87b7 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpathplugin.yaml @@ -0,0 +1,70 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-hostpathplugin +spec: + selector: + matchLabels: + app: csi-hostpathplugin + template: + metadata: + labels: + app: csi-hostpathplugin + spec: + serviceAccountName: csi-driver-registrar + hostNetwork: true + containers: + - name: driver-registrar + image: quay.io/k8scsi/driver-registrar:v0.4.1 + args: + - --v=5 + - --csi-address=/csi/csi.sock + - --kubelet-registration-path=/var/lib/kubelet/plugins/csi-hostpath/csi.sock + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + imagePullPolicy: Always + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /registration + name: registration-dir + - name: hostpath + image: quay.io/k8scsi/hostpathplugin:v0.4.1 + args: + - "--v=5" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + env: + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + imagePullPolicy: Always + securityContext: + privileged: true + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /var/lib/kubelet/pods + mountPropagation: Bidirectional + name: mountpoint-dir + volumes: + - hostPath: + path: /var/lib/kubelet/plugins/csi-hostpath + type: DirectoryOrCreate + name: socket-dir + - hostPath: + path: /var/lib/kubelet/pods + type: DirectoryOrCreate + name: mountpoint-dir + - hostPath: + path: /var/lib/kubelet/plugins + type: Directory + name: registration-dir diff --git a/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/e2e-test-rbac.yaml b/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/e2e-test-rbac.yaml new file mode 100644 index 0000000000000..1628db1b58822 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/e2e-test-rbac.yaml @@ -0,0 +1,19 @@ +# priviledged Pod Security Policy, previously defined just for gcePD via PrivilegedTestPSPClusterRoleBinding() +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: psp-csi-hostpath-role +subjects: + - kind: ServiceAccount + name: csi-attacher + namespace: default + - kind: ServiceAccount + name: csi-driver-registrar + namespace: default + - kind: ServiceAccount + name: csi-provisioner + namespace: default +roleRef: + kind: ClusterRole + name: e2e-test-privileged-psp + apiGroup: rbac.authorization.k8s.io diff --git a/test/e2e/testing-manifests/storage-csi/hostpath/usage/csi-storageclass.yaml b/test/e2e/testing-manifests/storage-csi/hostpath/usage/csi-storageclass.yaml new file mode 100644 index 0000000000000..c92797167e686 --- /dev/null +++ b/test/e2e/testing-manifests/storage-csi/hostpath/usage/csi-storageclass.yaml @@ -0,0 +1,7 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: csi-hostpath-sc +provisioner: csi-hostpath +reclaimPolicy: Delete +volumeBindingMode: Immediate diff --git a/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta1deployment-no-selectors.yaml b/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta1deployment-no-selectors.yaml new file mode 100644 index 0000000000000..b721f0b611002 --- /dev/null +++ b/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta1deployment-no-selectors.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: expose-test-deployment + labels: + name: expose-test-deployment +spec: + replicas: 3 + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta1deployment.yaml b/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta1deployment.yaml new file mode 100644 index 0000000000000..dc4f01892901d --- /dev/null +++ b/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta1deployment.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: expose-test-deployment + labels: + name: expose-test-deployment +spec: + replicas: 3 + selector: + matchLabels: + name: nginx + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta2deployment-no-selectors.yaml b/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta2deployment-no-selectors.yaml new file mode 100644 index 0000000000000..321d8414e4667 --- /dev/null +++ b/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta2deployment-no-selectors.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: expose-test-deployment + labels: + name: expose-test-deployment +spec: + replicas: 3 + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta2deployment.yaml b/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta2deployment.yaml new file mode 100644 index 0000000000000..9ed0aec22616c --- /dev/null +++ b/test/fixtures/pkg/kubectl/cmd/expose/appsv1beta2deployment.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: expose-test-deployment + labels: + name: expose-test-deployment +spec: + replicas: 3 + selector: + matchLabels: + name: nginx + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/test/fixtures/pkg/kubectl/cmd/expose/appsv1deployment-no-selectors.yaml b/test/fixtures/pkg/kubectl/cmd/expose/appsv1deployment-no-selectors.yaml new file mode 100644 index 0000000000000..5b0c84423bce0 --- /dev/null +++ b/test/fixtures/pkg/kubectl/cmd/expose/appsv1deployment-no-selectors.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: expose-test-deployment + labels: + name: expose-test-deployment +spec: + replicas: 3 + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/test/fixtures/pkg/kubectl/cmd/expose/appsv1deployment.yaml b/test/fixtures/pkg/kubectl/cmd/expose/appsv1deployment.yaml new file mode 100644 index 0000000000000..8852cfe1bb42d --- /dev/null +++ b/test/fixtures/pkg/kubectl/cmd/expose/appsv1deployment.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: expose-test-deployment + labels: + name: expose-test-deployment +spec: + replicas: 3 + selector: + matchLabels: + name: nginx + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/test/images/Makefile b/test/images/Makefile index 9418f1a9dd2ee..089c2696de978 100644 --- a/test/images/Makefile +++ b/test/images/Makefile @@ -17,7 +17,7 @@ include ../../hack/make-rules/Makefile.manifest REGISTRY ?= gcr.io/kubernetes-e2e-test-images GOARM=7 QEMUVERSION=v2.9.1 -GOLANG_VERSION=1.11.1 +GOLANG_VERSION=1.11.2 export ifndef WHAT diff --git a/test/images/metadata-concealment/VERSION b/test/images/metadata-concealment/VERSION index d3827e75a5cad..524cb55242b53 100644 --- a/test/images/metadata-concealment/VERSION +++ b/test/images/metadata-concealment/VERSION @@ -1 +1 @@ -1.0 +1.1.1 diff --git a/test/images/metadata-concealment/check_metadata_concealment.go b/test/images/metadata-concealment/check_metadata_concealment.go index c79b8a00cc755..4749e907ddd69 100644 --- a/test/images/metadata-concealment/check_metadata_concealment.go +++ b/test/images/metadata-concealment/check_metadata_concealment.go @@ -32,6 +32,8 @@ var ( "http://metadata.google.internal", "http://169.254.169.254/", "http://metadata.google.internal/", + "http://metadata.google.internal/0.1", + "http://metadata.google.internal/0.1/", "http://metadata.google.internal/computeMetadata", "http://metadata.google.internal/computeMetadata/v1", // Allowed API versions. @@ -44,8 +46,6 @@ var ( } legacySuccessEndpoints = []string{ // Discovery - "http://metadata.google.internal/0.1", - "http://metadata.google.internal/0.1/", "http://metadata.google.internal/0.1/meta-data", "http://metadata.google.internal/computeMetadata/v1beta1", // Allowed API versions. diff --git a/test/images/pets/zookeeper-installer/Dockerfile b/test/images/pets/zookeeper-installer/Dockerfile index 0843b858af8b3..020de082feecb 100644 --- a/test/images/pets/zookeeper-installer/Dockerfile +++ b/test/images/pets/zookeeper-installer/Dockerfile @@ -25,7 +25,7 @@ ADD on-start.sh / COPY peer-finder / # See README.md -RUN wget -q -O /zookeeper-3.5.0-alpha.tar.gz http://apache.mirrors.pair.com/zookeeper/zookeeper-3.5.0-alpha/zookeeper-3.5.0-alpha.tar.gz && \ +RUN wget -q -O /zookeeper-3.5.0-alpha.tar.gz http://archive.apache.org/dist/zookeeper/zookeeper-3.5.0-alpha/zookeeper-3.5.0-alpha.tar.gz && \ tar -xzf /zookeeper-3.5.0-alpha.tar.gz -C /tmp/ && mv /tmp/zookeeper-3.5.0-alpha /zookeeper && rm /zookeeper-3.5.0-alpha.tar.gz ADD install.sh / diff --git a/test/images/resource-consumer/README.md b/test/images/resource-consumer/README.md index 0b78bca10b3dc..298836ab675e3 100644 --- a/test/images/resource-consumer/README.md +++ b/test/images/resource-consumer/README.md @@ -48,7 +48,7 @@ Custom metrics in Prometheus format are exposed on "/metrics" endpoint. ### CURL example ```console -$ kubectl run resource-consumer --image=gcr.io/kubernetes-e2e-test-images/resource-consumer:1.3 --expose --service-overrides='{ "spec": { "type": "LoadBalancer" } }' --port 8080 --requests='cpu=500m,memory=256Mi' +$ kubectl run resource-consumer --image=gcr.io/kubernetes-e2e-test-images/resource-consumer:1.4 --expose --service-overrides='{ "spec": { "type": "LoadBalancer" } }' --port 8080 --requests='cpu=500m,memory=256Mi' $ kubectl get services resource-consumer ``` @@ -62,7 +62,7 @@ $ curl --data "millicores=300&durationSec=600" http://:8080/Consume ## Image -Docker image of Resource Consumer can be found in Google Container Registry as gcr.io/kubernetes-e2e-test-images/resource-consumer:1.3 +Docker image of Resource Consumer can be found in Google Container Registry as gcr.io/kubernetes-e2e-test-images/resource-consumer:1.4 ## Use cases diff --git a/test/integration/auth/BUILD b/test/integration/auth/BUILD index 6d4d735bdab89..bd7254767aef2 100644 --- a/test/integration/auth/BUILD +++ b/test/integration/auth/BUILD @@ -17,6 +17,9 @@ go_test( "rbac_test.go", "svcaccttoken_test.go", ], + data = [ + "//staging/src/k8s.io/csi-api/pkg/crd:csi-manifests", + ], tags = ["integration"], deps = [ "//cmd/kube-apiserver/app/testing:go_default_library", @@ -55,6 +58,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", @@ -63,6 +67,7 @@ go_test( "//staging/src/k8s.io/apiserver/pkg/authentication/group:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/authentication/token/cache:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/token/tokenfile:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", @@ -81,9 +86,9 @@ go_test( "//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library", "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned:go_default_library", - "//staging/src/k8s.io/csi-api/pkg/crd:go_default_library", "//test/e2e/lifecycle/bootstrap:go_default_library", "//test/integration:go_default_library", + "//test/integration/etcd:go_default_library", "//test/integration/framework:go_default_library", "//vendor/github.com/golang/glog:go_default_library", "//vendor/gopkg.in/square/go-jose.v2/jwt:go_default_library", diff --git a/test/integration/auth/auth_test.go b/test/integration/auth/auth_test.go index 067fb0b6ebec1..89ece409cf81e 100644 --- a/test/integration/auth/auth_test.go +++ b/test/integration/auth/auth_test.go @@ -40,6 +40,7 @@ import ( "k8s.io/apiserver/pkg/authentication/group" "k8s.io/apiserver/pkg/authentication/request/bearertoken" "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/apiserver/pkg/authentication/token/cache" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizerfactory" @@ -84,11 +85,11 @@ func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) { if err := json.NewEncoder(kubecfgFile).Encode(config); err != nil { return nil, err } - webhookTokenAuth, err := webhook.New(kubecfgFile.Name(), 2*time.Minute) + webhookTokenAuth, err := webhook.New(kubecfgFile.Name()) if err != nil { return nil, err } - return bearertoken.New(webhookTokenAuth), nil + return bearertoken.New(cache.New(webhookTokenAuth, false, 2*time.Minute, 2*time.Minute)), nil } func path(resource, namespace, name string) string { diff --git a/test/integration/auth/bootstraptoken_test.go b/test/integration/auth/bootstraptoken_test.go index aeeb72bd81d44..89f2a9d46d65f 100644 --- a/test/integration/auth/bootstraptoken_test.go +++ b/test/integration/auth/bootstraptoken_test.go @@ -24,24 +24,24 @@ import ( "testing" "time" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apiserver/pkg/authentication/request/bearertoken" bootstrapapi "k8s.io/cluster-bootstrap/token/api" - api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap" bootstraputil "k8s.io/kubernetes/test/e2e/lifecycle/bootstrap" "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) -type bootstrapSecrets []*api.Secret +type bootstrapSecrets []*corev1.Secret -func (b bootstrapSecrets) List(selector labels.Selector) (ret []*api.Secret, err error) { +func (b bootstrapSecrets) List(selector labels.Selector) (ret []*corev1.Secret, err error) { return b, nil } -func (b bootstrapSecrets) Get(name string) (*api.Secret, error) { +func (b bootstrapSecrets) Get(name string) (*corev1.Secret, error) { return b[0], nil } @@ -55,36 +55,36 @@ func TestBootstrapTokenAuth(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v", err) } - var bootstrapSecretValid = &api.Secret{ + var bootstrapSecretValid = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: metav1.NamespaceSystem, Name: bootstrapapi.BootstrapTokenSecretPrefix, }, - Type: api.SecretTypeBootstrapToken, + Type: corev1.SecretTypeBootstrapToken, Data: map[string][]byte{ bootstrapapi.BootstrapTokenIDKey: []byte(tokenId), bootstrapapi.BootstrapTokenSecretKey: []byte(secret), bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"), }, } - var bootstrapSecretInvalid = &api.Secret{ + var bootstrapSecretInvalid = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: metav1.NamespaceSystem, Name: bootstrapapi.BootstrapTokenSecretPrefix, }, - Type: api.SecretTypeBootstrapToken, + Type: corev1.SecretTypeBootstrapToken, Data: map[string][]byte{ bootstrapapi.BootstrapTokenIDKey: []byte(tokenId), bootstrapapi.BootstrapTokenSecretKey: []byte("invalid"), bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"), }, } - var expiredBootstrapToken = &api.Secret{ + var expiredBootstrapToken = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: metav1.NamespaceSystem, Name: bootstrapapi.BootstrapTokenSecretPrefix, }, - Type: api.SecretTypeBootstrapToken, + Type: corev1.SecretTypeBootstrapToken, Data: map[string][]byte{ bootstrapapi.BootstrapTokenIDKey: []byte(tokenId), bootstrapapi.BootstrapTokenSecretKey: []byte("invalid"), @@ -101,7 +101,7 @@ func TestBootstrapTokenAuth(t *testing.T) { tests := []struct { name string request request - secret *api.Secret + secret *corev1.Secret }{ { name: "valid token", diff --git a/test/integration/auth/node_test.go b/test/integration/auth/node_test.go index db871d6d37b64..3d4038efb6f1d 100644 --- a/test/integration/auth/node_test.go +++ b/test/integration/auth/node_test.go @@ -18,6 +18,8 @@ package auth import ( "fmt" + "io/ioutil" + "strings" "testing" "time" @@ -26,27 +28,25 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" externalclientset "k8s.io/client-go/kubernetes" csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1" + csiclientset "k8s.io/csi-api/pkg/client/clientset/versioned" + kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/coordination" + "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/policy" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/features" + "k8s.io/kubernetes/test/integration/etcd" "k8s.io/kubernetes/test/integration/framework" "k8s.io/utils/pointer" - - "io/ioutil" - apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - csiclientset "k8s.io/csi-api/pkg/client/clientset/versioned" - csicrd "k8s.io/csi-api/pkg/crd" - kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" - "k8s.io/kubernetes/pkg/apis/core" - "strings" ) func TestNodeAuthorizer(t *testing.T) { @@ -158,13 +158,12 @@ func TestNodeAuthorizer(t *testing.T) { t.Fatal(err) } - crd, err := superuserCRDClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(csicrd.CSINodeInfoCRD()) + csiNodeInfoCRD, err := crdFromManifest("../../../staging/src/k8s.io/csi-api/pkg/crd/manifests/csinodeinfo.yaml") if err != nil { t.Fatal(err) } - if err := waitForEstablishedCRD(superuserCRDClient, crd.Name); err != nil { - t.Fatalf("Failed to establish CSINodeInfo CRD: %v", err) - } + + etcd.CreateTestCRDs(t, superuserCRDClient, false, csiNodeInfoCRD) getSecret := func(client clientset.Interface) func() error { return func() error { @@ -673,24 +672,16 @@ func expectAllowed(t *testing.T, f func() error) { } } -func waitForEstablishedCRD(client apiextensionsclientset.Interface, name string) error { - return wait.PollImmediate(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) { - crd, err := client.ApiextensionsV1beta1().CustomResourceDefinitions().Get(name, metav1.GetOptions{}) - if err != nil { - return false, err - } - for _, cond := range crd.Status.Conditions { - switch cond.Type { - case apiextensionsv1beta1.Established: - if cond.Status == apiextensionsv1beta1.ConditionTrue { - return true, err - } - case apiextensionsv1beta1.NamesAccepted: - if cond.Status == apiextensionsv1beta1.ConditionFalse { - fmt.Printf("Name conflict: %v\n", cond.Reason) - } - } - } - return false, nil - }) +// crdFromManifest reads a .json/yaml file and returns the CRD in it. +func crdFromManifest(filename string) (*apiextensionsv1beta1.CustomResourceDefinition, error) { + var crd apiextensionsv1beta1.CustomResourceDefinition + data, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + + if err := runtime.DecodeInto(legacyscheme.Codecs.UniversalDecoder(), data, &crd); err != nil { + return nil, err + } + return &crd, nil } diff --git a/test/integration/deployment/deployment_test.go b/test/integration/deployment/deployment_test.go index aa09be918e7ee..6d0190e3f13cf 100644 --- a/test/integration/deployment/deployment_test.go +++ b/test/integration/deployment/deployment_test.go @@ -1269,9 +1269,7 @@ func testScalingUsingScaleSubresource(t *testing.T, tester *deploymentTester, re if err != nil { t.Fatalf("Failed to obtain deployment %q: %v", deploymentName, err) } - kind := "Deployment" - scaleClient := tester.c.ExtensionsV1beta1().Scales(ns) - scale, err := scaleClient.Get(kind, deploymentName) + scale, err := tester.c.AppsV1().Deployments(ns).GetScale(deploymentName, metav1.GetOptions{}) if err != nil { t.Fatalf("Failed to obtain scale subresource for deployment %q: %v", deploymentName, err) } @@ -1280,12 +1278,12 @@ func testScalingUsingScaleSubresource(t *testing.T, tester *deploymentTester, re } if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - scale, err := scaleClient.Get(kind, deploymentName) + scale, err := tester.c.AppsV1().Deployments(ns).GetScale(deploymentName, metav1.GetOptions{}) if err != nil { return err } scale.Spec.Replicas = replicas - _, err = scaleClient.Update(kind, scale) + _, err = tester.c.AppsV1().Deployments(ns).UpdateScale(deploymentName, scale) return err }); err != nil { t.Fatalf("Failed to set .Spec.Replicas of scale subresource for deployment %q: %v", deploymentName, err) diff --git a/test/integration/etcd/BUILD b/test/integration/etcd/BUILD index d17427684fafe..d86e89cc42df6 100644 --- a/test/integration/etcd/BUILD +++ b/test/integration/etcd/BUILD @@ -53,6 +53,8 @@ go_library( "//cmd/kube-apiserver/app:go_default_library", "//cmd/kube-apiserver/app/options:go_default_library", "//pkg/master:go_default_library", + "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", + "//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", diff --git a/test/integration/etcd/data.go b/test/integration/etcd/data.go index ab495b9dae1b8..d5cf04d7a6e93 100644 --- a/test/integration/etcd/data.go +++ b/test/integration/etcd/data.go @@ -16,7 +16,11 @@ limitations under the License. package etcd -import "k8s.io/apimachinery/pkg/runtime/schema" +import ( + apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) // GetEtcdStorageData returns etcd data for all persisted objects. // It is exported so that it can be reused across multiple tests. @@ -427,6 +431,23 @@ func GetEtcdStorageData() map[schema.GroupVersionResource]StorageData { Stub: `{"metadata": {"name": "openshiftwebconsoleconfigs.webconsole.operator.openshift.io"},"spec": {"scope": "Cluster","group": "webconsole.operator.openshift.io","version": "v1alpha1","names": {"kind": "OpenShiftWebConsoleConfig","plural": "openshiftwebconsoleconfigs","singular": "openshiftwebconsoleconfig"}}}`, ExpectedEtcdPath: "/registry/apiextensions.k8s.io/customresourcedefinitions/openshiftwebconsoleconfigs.webconsole.operator.openshift.io", }, + gvr("cr.bar.com", "v1", "foos"): { + Stub: `{"kind": "Foo", "apiVersion": "cr.bar.com/v1", "metadata": {"name": "cr1foo"}, "color": "blue"}`, // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper + ExpectedEtcdPath: "/registry/cr.bar.com/foos/etcdstoragepathtestnamespace/cr1foo", + }, + gvr("custom.fancy.com", "v2", "pants"): { + Stub: `{"kind": "Pant", "apiVersion": "custom.fancy.com/v2", "metadata": {"name": "cr2pant"}, "isFancy": true}`, // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper + ExpectedEtcdPath: "/registry/custom.fancy.com/pants/cr2pant", + }, + gvr("awesome.bears.com", "v1", "pandas"): { + Stub: `{"kind": "Panda", "apiVersion": "awesome.bears.com/v1", "metadata": {"name": "cr3panda"}, "weight": 100}`, // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper + ExpectedEtcdPath: "/registry/awesome.bears.com/pandas/cr3panda", + }, + gvr("awesome.bears.com", "v3", "pandas"): { + Stub: `{"kind": "Panda", "apiVersion": "awesome.bears.com/v3", "metadata": {"name": "cr4panda"}, "weight": 300}`, // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper + ExpectedEtcdPath: "/registry/awesome.bears.com/pandas/cr4panda", + ExpectedGVK: gvkP("awesome.bears.com", "v1", "Panda"), + }, // -- } } @@ -446,6 +467,74 @@ type Prerequisite struct { Stub string } +// GetCustomResourceDefinitionData returns the resource definitions that back the custom resources +// included in GetEtcdStorageData. They should be created using CreateTestCRDs before running any tests. +func GetCustomResourceDefinitionData() []*apiextensionsv1beta1.CustomResourceDefinition { + return []*apiextensionsv1beta1.CustomResourceDefinition{ + // namespaced with legacy version field + { + ObjectMeta: metav1.ObjectMeta{ + Name: "foos.cr.bar.com", + }, + Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ + Group: "cr.bar.com", + Version: "v1", + Scope: apiextensionsv1beta1.NamespaceScoped, + Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ + Plural: "foos", + Kind: "Foo", + }, + }, + }, + // cluster scoped with legacy version field + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pants.custom.fancy.com", + }, + Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ + Group: "custom.fancy.com", + Version: "v2", + Scope: apiextensionsv1beta1.ClusterScoped, + Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ + Plural: "pants", + Kind: "Pant", + }, + }, + }, + // cluster scoped with versions field + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pandas.awesome.bears.com", + }, + Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ + Group: "awesome.bears.com", + Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Served: true, + Storage: true, + }, + { + Name: "v2", + Served: false, + Storage: false, + }, + { + Name: "v3", + Served: true, + Storage: false, + }, + }, + Scope: apiextensionsv1beta1.ClusterScoped, + Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ + Plural: "pandas", + Kind: "Panda", + }, + }, + }, + } +} + func gvr(g, v, r string) schema.GroupVersionResource { return schema.GroupVersionResource{Group: g, Version: v, Resource: r} } diff --git a/test/integration/etcd/etcd_storage_path_test.go b/test/integration/etcd/etcd_storage_path_test.go index 1ec75a315f786..0335a5030c261 100644 --- a/test/integration/etcd/etcd_storage_path_test.go +++ b/test/integration/etcd/etcd_storage_path_test.go @@ -99,6 +99,10 @@ func TestEtcdStoragePath(t *testing.T) { if input, err = jsonToMetaObject([]byte(testData.Stub)); err != nil || input.isEmpty() { t.Fatalf("invalid test data for %s: %v", gvResource, err) } + // unset type meta fields - we only set these in the CRD test data and it makes + // any CRD test with an expectedGVK override fail the DeepDerivative test + input.Kind = "" + input.APIVersion = "" } all := &[]cleanupData{} diff --git a/test/integration/etcd/server.go b/test/integration/etcd/server.go index d47465d4ea0b0..d86534ba29293 100644 --- a/test/integration/etcd/server.go +++ b/test/integration/etcd/server.go @@ -30,6 +30,8 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3/concurrency" + apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -153,6 +155,9 @@ func StartRealMasterOrDie(t *testing.T) *Master { t.Fatal(err) } + // create CRDs so we can make sure that custom resources do not get lost + CreateTestCRDs(t, apiextensionsclientset.NewForConfigOrDie(kubeClientConfig), false, GetCustomResourceDefinitionData()...) + // force cached discovery reset discoveryClient := cacheddiscovery.NewMemCacheClient(kubeClient.Discovery()) restMapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient) @@ -169,6 +174,9 @@ func StartRealMasterOrDie(t *testing.T) *Master { } close(stopCh) lock.Unlock() + if err := session.Close(); err != nil { + t.Log(err) + } } return &Master{ @@ -281,3 +289,79 @@ func JSONToUnstructured(stub, namespace string, mapping *meta.RESTMapping, dynam return dynamicClient.Resource(mapping.Resource).Namespace(namespace), &unstructured.Unstructured{Object: typeMetaAdder}, nil } + +// CreateTestCRDs creates the given CRDs, any failure causes the test to Fatal. +// If skipCrdExistsInDiscovery is true, the CRDs are only checked for the Established condition via their Status. +// If skipCrdExistsInDiscovery is false, the CRDs are checked via discovery, see CrdExistsInDiscovery. +func CreateTestCRDs(t *testing.T, client apiextensionsclientset.Interface, skipCrdExistsInDiscovery bool, crds ...*apiextensionsv1beta1.CustomResourceDefinition) { + for _, crd := range crds { + createTestCRD(t, client, skipCrdExistsInDiscovery, crd) + } +} + +func createTestCRD(t *testing.T, client apiextensionsclientset.Interface, skipCrdExistsInDiscovery bool, crd *apiextensionsv1beta1.CustomResourceDefinition) { + if _, err := client.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd); err != nil { + t.Fatalf("Failed to create %s CRD; %v", crd.Name, err) + } + if skipCrdExistsInDiscovery { + if err := waitForEstablishedCRD(client, crd.Name); err != nil { + t.Fatalf("Failed to establish %s CRD; %v", crd.Name, err) + } + return + } + if err := wait.PollImmediate(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) { + return CrdExistsInDiscovery(client, crd), nil + }); err != nil { + t.Fatalf("Failed to see %s in discovery: %v", crd.Name, err) + } +} + +func waitForEstablishedCRD(client apiextensionsclientset.Interface, name string) error { + return wait.PollImmediate(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) { + crd, err := client.ApiextensionsV1beta1().CustomResourceDefinitions().Get(name, metav1.GetOptions{}) + if err != nil { + return false, err + } + for _, cond := range crd.Status.Conditions { + switch cond.Type { + case apiextensionsv1beta1.Established: + if cond.Status == apiextensionsv1beta1.ConditionTrue { + return true, nil + } + } + } + return false, nil + }) +} + +// CrdExistsInDiscovery checks to see if the given CRD exists in discovery at all served versions. +func CrdExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiextensionsv1beta1.CustomResourceDefinition) bool { + var versions []string + if len(crd.Spec.Version) != 0 { + versions = append(versions, crd.Spec.Version) + } + for _, v := range crd.Spec.Versions { + if v.Served { + versions = append(versions, v.Name) + } + } + for _, v := range versions { + if !crdVersionExistsInDiscovery(client, crd, v) { + return false + } + } + return true +} + +func crdVersionExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiextensionsv1beta1.CustomResourceDefinition, version string) bool { + resourceList, err := client.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + version) + if err != nil { + return false + } + for _, resource := range resourceList.APIResources { + if resource.Name == crd.Spec.Names.Plural { + return true + } + } + return false +} diff --git a/test/integration/master/BUILD b/test/integration/master/BUILD index fa012cd25adf4..4575d2667c47f 100644 --- a/test/integration/master/BUILD +++ b/test/integration/master/BUILD @@ -62,6 +62,7 @@ go_test( "//staging/src/k8s.io/client-go/rest:go_default_library", "//staging/src/k8s.io/kube-aggregator/pkg/apis/apiregistration:go_default_library", "//test/integration:go_default_library", + "//test/integration/etcd:go_default_library", "//test/integration/framework:go_default_library", "//test/utils:go_default_library", "//vendor/github.com/evanphx/json-patch:go_default_library", diff --git a/test/integration/master/crd_test.go b/test/integration/master/crd_test.go index 61c11c6a6d4d9..ac28b037c301b 100644 --- a/test/integration/master/crd_test.go +++ b/test/integration/master/crd_test.go @@ -18,7 +18,6 @@ package master import ( "encoding/json" - "fmt" "testing" "time" @@ -37,6 +36,7 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" + "k8s.io/kubernetes/test/integration/etcd" "k8s.io/kubernetes/test/integration/framework" ) @@ -81,12 +81,8 @@ func TestCRDShadowGroup(t *testing.T) { }, }, } - if _, err = apiextensionsclient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd); err != nil { - t.Fatalf("Failed to create networking group CRD: %v", err) - } - if err := waitForEstablishedCRD(apiextensionsclient, crd.Name); err != nil { - t.Fatalf("Failed to establish networking group CRD: %v", err) - } + etcd.CreateTestCRDs(t, apiextensionsclient, true, crd) + // wait to give aggregator time to update time.Sleep(2 * time.Second) @@ -97,11 +93,7 @@ func TestCRDShadowGroup(t *testing.T) { } t.Logf("Checking that crd resource does not show up in networking group") - found, err := crdExistsInDiscovery(apiextensionsclient, crd) - if err != nil { - t.Fatalf("unexpected discovery error: %v", err) - } - if found { + if etcd.CrdExistsInDiscovery(apiextensionsclient, crd) { t.Errorf("CRD resource shows up in discovery, but shouldn't.") } } @@ -137,17 +129,7 @@ func TestCRD(t *testing.T) { }, }, } - if _, err = apiextensionsclient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd); err != nil { - t.Fatalf("Failed to create foos.cr.bar.com CRD; %v", err) - } - if err := waitForEstablishedCRD(apiextensionsclient, crd.Name); err != nil { - t.Fatalf("Failed to establish foos.cr.bar.com CRD: %v", err) - } - if err := wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) { - return crdExistsInDiscovery(apiextensionsclient, crd) - }); err != nil { - t.Fatalf("Failed to see foos.cr.bar.com in discovery: %v", err) - } + etcd.CreateTestCRDs(t, apiextensionsclient, false, crd) t.Logf("Trying to access foos.cr.bar.com with dynamic client") dynamicClient, err := dynamic.NewForConfig(result.ClientConfig) @@ -306,38 +288,3 @@ func unstructuredFoo(foo *Foo) (*unstructured.Unstructured, error) { } return ret, nil } - -func waitForEstablishedCRD(client apiextensionsclientset.Interface, name string) error { - return wait.PollImmediate(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) { - crd, err := client.ApiextensionsV1beta1().CustomResourceDefinitions().Get(name, metav1.GetOptions{}) - if err != nil { - return false, err - } - for _, cond := range crd.Status.Conditions { - switch cond.Type { - case apiextensionsv1beta1.Established: - if cond.Status == apiextensionsv1beta1.ConditionTrue { - return true, err - } - case apiextensionsv1beta1.NamesAccepted: - if cond.Status == apiextensionsv1beta1.ConditionFalse { - fmt.Printf("Name conflict: %v\n", cond.Reason) - } - } - } - return false, nil - }) -} - -func crdExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiextensionsv1beta1.CustomResourceDefinition) (bool, error) { - resourceList, err := client.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + crd.Spec.Version) - if err != nil { - return false, nil - } - for _, resource := range resourceList.APIResources { - if resource.Name == crd.Spec.Names.Plural { - return true, nil - } - } - return false, nil -} diff --git a/test/integration/master/kms_transformation_test.go b/test/integration/master/kms_transformation_test.go index 4a08d0408bfb8..df7a70bd3148d 100644 --- a/test/integration/master/kms_transformation_test.go +++ b/test/integration/master/kms_transformation_test.go @@ -72,7 +72,7 @@ func (r rawDEKKEKSecret) getPayload() []byte { return r[r.getStartOfPayload():] } -// TestKMSProvider is an integration test between KubAPI, ETCD and KMS Plugin +// TestKMSProvider is an integration test between KubeAPI, ETCD and KMS Plugin // Concretely, this test verifies the following integration contracts: // 1. Raw records in ETCD that were processed by KMS Provider should be prefixed with k8s:enc:kms:v1:grpc-kms-provider-name: // 2. Data Encryption Key (DEK) should be generated by envelopeTransformer and passed to KMS gRPC Plugin diff --git a/test/integration/master/synthetic_master_test.go b/test/integration/master/synthetic_master_test.go index d0190830dffdb..a4ef671983a36 100644 --- a/test/integration/master/synthetic_master_test.go +++ b/test/integration/master/synthetic_master_test.go @@ -175,7 +175,7 @@ func TestStatus(t *testing.T) { statusCode: http.StatusForbidden, reqPath: "/apis", reason: "Forbidden", - message: `forbidden: User "" cannot get path "/apis"`, + message: `forbidden: User "" cannot get path "/apis": Everything is forbidden.`, }, { name: "401", diff --git a/test/integration/replicaset/replicaset_test.go b/test/integration/replicaset/replicaset_test.go index d19180ea62a2d..53854ec0fe152 100644 --- a/test/integration/replicaset/replicaset_test.go +++ b/test/integration/replicaset/replicaset_test.go @@ -340,9 +340,7 @@ func testScalingUsingScaleSubresource(t *testing.T, c clientset.Interface, rs *a if err != nil { t.Fatalf("Failed to obtain rs %s: %v", rs.Name, err) } - kind := "ReplicaSet" - scaleClient := c.ExtensionsV1beta1().Scales(ns) - scale, err := scaleClient.Get(kind, rs.Name) + scale, err := c.AppsV1().ReplicaSets(ns).GetScale(rs.Name, metav1.GetOptions{}) if err != nil { t.Fatalf("Failed to obtain scale subresource for rs %s: %v", rs.Name, err) } @@ -351,12 +349,12 @@ func testScalingUsingScaleSubresource(t *testing.T, c clientset.Interface, rs *a } if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - scale, err := scaleClient.Get(kind, rs.Name) + scale, err := c.AppsV1().ReplicaSets(ns).GetScale(rs.Name, metav1.GetOptions{}) if err != nil { return err } scale.Spec.Replicas = replicas - _, err = scaleClient.Update(kind, scale) + _, err = c.AppsV1().ReplicaSets(ns).UpdateScale(rs.Name, scale) return err }); err != nil { t.Fatalf("Failed to set .Spec.Replicas of scale subresource for rs %s: %v", rs.Name, err) diff --git a/test/integration/replicationcontroller/replicationcontroller_test.go b/test/integration/replicationcontroller/replicationcontroller_test.go index 7f30945dfc665..e20c3d2b7bded 100644 --- a/test/integration/replicationcontroller/replicationcontroller_test.go +++ b/test/integration/replicationcontroller/replicationcontroller_test.go @@ -340,9 +340,7 @@ func testScalingUsingScaleSubresource(t *testing.T, c clientset.Interface, rc *v if err != nil { t.Fatalf("Failed to obtain rc %s: %v", rc.Name, err) } - kind := "ReplicationController" - scaleClient := c.ExtensionsV1beta1().Scales(ns) - scale, err := scaleClient.Get(kind, rc.Name) + scale, err := c.CoreV1().ReplicationControllers(ns).GetScale(rc.Name, metav1.GetOptions{}) if err != nil { t.Fatalf("Failed to obtain scale subresource for rc %s: %v", rc.Name, err) } @@ -351,12 +349,12 @@ func testScalingUsingScaleSubresource(t *testing.T, c clientset.Interface, rc *v } if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - scale, err := scaleClient.Get(kind, rc.Name) + scale, err := c.CoreV1().ReplicationControllers(ns).GetScale(rc.Name, metav1.GetOptions{}) if err != nil { return err } scale.Spec.Replicas = replicas - _, err = scaleClient.Update(kind, scale) + _, err = c.CoreV1().ReplicationControllers(ns).UpdateScale(rc.Name, scale) return err }); err != nil { t.Fatalf("Failed to set .Spec.Replicas of scale subresource for rc %s: %v", rc.Name, err) diff --git a/test/integration/scheduler/BUILD b/test/integration/scheduler/BUILD index c78e0218e411c..0956657c99e69 100644 --- a/test/integration/scheduler/BUILD +++ b/test/integration/scheduler/BUILD @@ -25,13 +25,10 @@ go_test( "//cmd/kube-scheduler/app:go_default_library", "//cmd/kube-scheduler/app/config:go_default_library", "//pkg/api/legacyscheme:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/informers/informers_generated/internalversion:go_default_library", "//pkg/controller/nodelifecycle:go_default_library", "//pkg/controller/volume/persistentvolume:go_default_library", "//pkg/controller/volume/persistentvolume/options:go_default_library", "//pkg/features:go_default_library", - "//pkg/kubeapiserver/admission:go_default_library", "//pkg/scheduler:go_default_library", "//pkg/scheduler/algorithm:go_default_library", "//pkg/scheduler/algorithm/predicates:go_default_library", diff --git a/test/integration/scheduler/taint_test.go b/test/integration/scheduler/taint_test.go index 493c8e8544d4b..89189fc155546 100644 --- a/test/integration/scheduler/taint_test.go +++ b/test/integration/scheduler/taint_test.go @@ -28,11 +28,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - internalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" "k8s.io/kubernetes/pkg/controller/nodelifecycle" - kubeadmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" "k8s.io/kubernetes/pkg/scheduler/algorithmprovider" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction" @@ -77,14 +76,14 @@ func TestTaintNodeByCondition(t *testing.T) { context := initTestMaster(t, "default", admission) // Build clientset and informers for controllers. - internalClientset := internalclientset.NewForConfigOrDie(&restclient.Config{ + externalClientset := kubernetes.NewForConfigOrDie(&restclient.Config{ QPS: -1, Host: context.httpServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}) - internalInformers := internalinformers.NewSharedInformerFactory(internalClientset, time.Second) + externalInformers := informers.NewSharedInformerFactory(externalClientset, time.Second) - kubeadmission.WantsInternalKubeClientSet(admission).SetInternalKubeClientSet(internalClientset) - kubeadmission.WantsInternalKubeInformerFactory(admission).SetInternalKubeInformerFactory(internalInformers) + admission.SetExternalKubeClientSet(externalClientset) + admission.SetExternalKubeInformerFactory(externalInformers) controllerCh := make(chan struct{}) defer close(controllerCh) @@ -124,8 +123,8 @@ func TestTaintNodeByCondition(t *testing.T) { go nc.Run(controllerCh) // Waiting for all controller sync. - internalInformers.Start(controllerCh) - internalInformers.WaitForCacheSync(controllerCh) + externalInformers.Start(controllerCh) + externalInformers.WaitForCacheSync(controllerCh) informers.Start(controllerCh) informers.WaitForCacheSync(controllerCh) diff --git a/test/integration/scheduler/volume_binding_test.go b/test/integration/scheduler/volume_binding_test.go index 0608dc25ea2ad..e82b3562be2e7 100644 --- a/test/integration/scheduler/volume_binding_test.go +++ b/test/integration/scheduler/volume_binding_test.go @@ -715,12 +715,6 @@ func TestVolumeProvision(t *testing.T) { boundPvcs: []*testPVC{{"pvc-w-canbind", classWait, ""}}, provisionedPvcs: []*testPVC{{"pvc-canprovision", classWait, ""}}, }, - "one immediate pvc prebound, one wait provisioned": { - pod: makePod("pod-i-pvc-prebound-w-provisioned", config.ns, []string{"pvc-i-prebound", "pvc-canprovision"}), - pvs: []*testPV{{"pv-i-pvc-prebound", classImmediate, "", node1}}, - boundPvcs: []*testPVC{{"pvc-i-prebound", classImmediate, "pv-i-pvc-prebound"}}, - provisionedPvcs: []*testPVC{{"pvc-canprovision", classWait, ""}}, - }, "one immediate pv prebound, one wait provisioned": { pod: makePod("pod-i-pv-prebound-w-provisioned", config.ns, []string{"pvc-i-pv-prebound", "pvc-canprovision"}), pvs: []*testPV{{"pv-i-prebound", classImmediate, "pvc-i-pv-prebound", node1}}, diff --git a/test/integration/scheduler_perf/scheduler_bench_test.go b/test/integration/scheduler_perf/scheduler_bench_test.go index fb28da4ec6025..30403d14080c2 100644 --- a/test/integration/scheduler_perf/scheduler_bench_test.go +++ b/test/integration/scheduler_perf/scheduler_bench_test.go @@ -31,6 +31,10 @@ import ( "github.com/golang/glog" ) +var ( + defaultNodeStrategy = &testutils.TrivialNodePrepareStrategy{} +) + // BenchmarkScheduling benchmarks the scheduling rate when the cluster has // various quantities of nodes and scheduled pods. func BenchmarkScheduling(b *testing.B) { @@ -45,41 +49,90 @@ func BenchmarkScheduling(b *testing.B) { for _, test := range tests { name := fmt.Sprintf("%vNodes/%vPods", test.nodes, test.existingPods) b.Run(name, func(b *testing.B) { - benchmarkScheduling(test.nodes, test.existingPods, test.minPods, setupStrategy, testStrategy, b) + benchmarkScheduling(test.nodes, test.existingPods, test.minPods, defaultNodeStrategy, setupStrategy, testStrategy, b) }) } } -// BenchmarkSchedulingAntiAffinity benchmarks the scheduling rate of pods with +// BenchmarkSchedulingPodAntiAffinity benchmarks the scheduling rate of pods with // PodAntiAffinity rules when the cluster has various quantities of nodes and // scheduled pods. -func BenchmarkSchedulingAntiAffinity(b *testing.B) { +func BenchmarkSchedulingPodAntiAffinity(b *testing.B) { tests := []struct{ nodes, existingPods, minPods int }{ {nodes: 500, existingPods: 250, minPods: 250}, {nodes: 500, existingPods: 5000, minPods: 250}, + {nodes: 1000, existingPods: 1000, minPods: 500}, } // The setup strategy creates pods with no affinity rules. setupStrategy := testutils.NewSimpleWithControllerCreatePodStrategy("setup") - // The test strategy creates pods with anti-affinity for each other. - testBasePod := makeBasePodWithAntiAffinity( + testBasePod := makeBasePodWithPodAntiAffinity( map[string]string{"name": "test", "color": "green"}, map[string]string{"color": "green"}) + // The test strategy creates pods with anti-affinity for each other. + testStrategy := testutils.NewCustomCreatePodStrategy(testBasePod) + for _, test := range tests { + name := fmt.Sprintf("%vNodes/%vPods", test.nodes, test.existingPods) + b.Run(name, func(b *testing.B) { + benchmarkScheduling(test.nodes, test.existingPods, test.minPods, defaultNodeStrategy, setupStrategy, testStrategy, b) + }) + } +} + +// BenchmarkSchedulingPodAffinity benchmarks the scheduling rate of pods with +// PodAffinity rules when the cluster has various quantities of nodes and +// scheduled pods. +func BenchmarkSchedulingPodAffinity(b *testing.B) { + tests := []struct{ nodes, existingPods, minPods int }{ + {nodes: 500, existingPods: 250, minPods: 250}, + {nodes: 500, existingPods: 5000, minPods: 250}, + {nodes: 1000, existingPods: 1000, minPods: 500}, + } + // The setup strategy creates pods with no affinity rules. + setupStrategy := testutils.NewSimpleWithControllerCreatePodStrategy("setup") + testBasePod := makeBasePodWithPodAffinity( + map[string]string{"foo": ""}, + map[string]string{"foo": ""}, + ) + // The test strategy creates pods with affinity for each other. testStrategy := testutils.NewCustomCreatePodStrategy(testBasePod) + nodeStrategy := testutils.NewLabelNodePrepareStrategy(apis.LabelZoneFailureDomain, "zone1") for _, test := range tests { name := fmt.Sprintf("%vNodes/%vPods", test.nodes, test.existingPods) b.Run(name, func(b *testing.B) { - benchmarkScheduling(test.nodes, test.existingPods, test.minPods, setupStrategy, testStrategy, b) + benchmarkScheduling(test.nodes, test.existingPods, test.minPods, nodeStrategy, setupStrategy, testStrategy, b) }) } +} +// BenchmarkSchedulingNodeAffinity benchmarks the scheduling rate of pods with +// NodeAffinity rules when the cluster has various quantities of nodes and +// scheduled pods. +func BenchmarkSchedulingNodeAffinity(b *testing.B) { + tests := []struct{ nodes, existingPods, minPods int }{ + {nodes: 500, existingPods: 250, minPods: 250}, + {nodes: 500, existingPods: 5000, minPods: 250}, + {nodes: 1000, existingPods: 1000, minPods: 500}, + } + // The setup strategy creates pods with no affinity rules. + setupStrategy := testutils.NewSimpleWithControllerCreatePodStrategy("setup") + testBasePod := makeBasePodWithNodeAffinity(apis.LabelZoneFailureDomain, []string{"zone1", "zone2"}) + // The test strategy creates pods with node-affinity for each other. + testStrategy := testutils.NewCustomCreatePodStrategy(testBasePod) + nodeStrategy := testutils.NewLabelNodePrepareStrategy(apis.LabelZoneFailureDomain, "zone1") + for _, test := range tests { + name := fmt.Sprintf("%vNodes/%vPods", test.nodes, test.existingPods) + b.Run(name, func(b *testing.B) { + benchmarkScheduling(test.nodes, test.existingPods, test.minPods, nodeStrategy, setupStrategy, testStrategy, b) + }) + } } -// makeBasePodWithAntiAffinity creates a Pod object to be used as a template. +// makeBasePodWithPodAntiAffinity creates a Pod object to be used as a template. // The Pod has a PodAntiAffinity requirement against pods with the given labels. -func makeBasePodWithAntiAffinity(podLabels, affinityLabels map[string]string) *v1.Pod { +func makeBasePodWithPodAntiAffinity(podLabels, affinityLabels map[string]string) *v1.Pod { basePod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ - GenerateName: "affinity-pod-", + GenerateName: "anit-affinity-pod-", Labels: podLabels, }, Spec: testutils.MakePodSpec(), @@ -99,11 +152,66 @@ func makeBasePodWithAntiAffinity(podLabels, affinityLabels map[string]string) *v return basePod } +// makeBasePodWithPodAffinity creates a Pod object to be used as a template. +// The Pod has a PodAffinity requirement against pods with the given labels. +func makeBasePodWithPodAffinity(podLabels, affinityZoneLabels map[string]string) *v1.Pod { + basePod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "affinity-pod-", + Labels: podLabels, + }, + Spec: testutils.MakePodSpec(), + } + basePod.Spec.Affinity = &v1.Affinity{ + PodAffinity: &v1.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: affinityZoneLabels, + }, + TopologyKey: apis.LabelZoneFailureDomain, + }, + }, + }, + } + return basePod +} + +// makeBasePodWithNodeAffinity creates a Pod object to be used as a template. +// The Pod has a NodeAffinity requirement against nodes with the given expressions. +func makeBasePodWithNodeAffinity(key string, vals []string) *v1.Pod { + basePod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "node-affinity-", + }, + Spec: testutils.MakePodSpec(), + } + basePod.Spec.Affinity = &v1.Affinity{ + NodeAffinity: &v1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{ + NodeSelectorTerms: []v1.NodeSelectorTerm{ + { + MatchExpressions: []v1.NodeSelectorRequirement{ + { + Key: key, + Operator: v1.NodeSelectorOpIn, + Values: vals, + }, + }, + }, + }, + }, + }, + } + return basePod +} + // benchmarkScheduling benchmarks scheduling rate with specific number of nodes // and specific number of pods already scheduled. // This will schedule numExistingPods pods before the benchmark starts, and at // least minPods pods during the benchmark. func benchmarkScheduling(numNodes, numExistingPods, minPods int, + nodeStrategy testutils.PrepareNodeStrategy, setupPodStrategy, testPodStrategy testutils.TestPodCreateStrategy, b *testing.B) { if b.N < minPods { @@ -115,7 +223,7 @@ func benchmarkScheduling(numNodes, numExistingPods, minPods int, nodePreparer := framework.NewIntegrationTestNodePreparer( c, - []testutils.CountToStrategy{{Count: numNodes, Strategy: &testutils.TrivialNodePrepareStrategy{}}}, + []testutils.CountToStrategy{{Count: numNodes, Strategy: nodeStrategy}}, "scheduler-perf-", ) if err := nodePreparer.PrepareNodes(); err != nil { diff --git a/test/integration/util/cloud.go b/test/integration/util/cloud.go index d5c758d4aa6dc..0d018a4e96f99 100644 --- a/test/integration/util/cloud.go +++ b/test/integration/util/cloud.go @@ -52,9 +52,9 @@ func (*mockTokenSource) Token() (*oauth2.Token, error) { }, nil } -// NewMockGCECloud returns a handle to a GCECloud instance that is +// NewMockGCECloud returns a handle to a Cloud instance that is // served by a mock http server -func NewMockGCECloud(cloud cloud.Cloud) (*gce.GCECloud, error) { +func NewMockGCECloud(cloud cloud.Cloud) (*gce.Cloud, error) { config := &gce.CloudConfig{ ProjectID: TestProjectID, NetworkProjectID: TestNetworkProjectID, diff --git a/test/kubemark/resources/manifests/kube-addon-manager.yaml b/test/kubemark/resources/manifests/kube-addon-manager.yaml index 6341235ed5788..e9bc87e1eb63d 100644 --- a/test/kubemark/resources/manifests/kube-addon-manager.yaml +++ b/test/kubemark/resources/manifests/kube-addon-manager.yaml @@ -9,7 +9,7 @@ spec: hostNetwork: true containers: - name: kube-addon-manager - image: {{kube_docker_registry}}/kube-addon-manager:v8.8 + image: {{kube_docker_registry}}/kube-addon-manager:v8.9 command: - /bin/bash - -c diff --git a/test/list/main.go b/test/list/main.go index b7b25e9d687ea..bc4904b4ce9a5 100644 --- a/test/list/main.go +++ b/test/list/main.go @@ -33,10 +33,11 @@ import ( var ( dumpTree = flag.Bool("dump", false, "print AST") - dumpJson = flag.Bool("json", false, "output test list as JSON") + dumpJSON = flag.Bool("json", false, "output test list as JSON") warn = flag.Bool("warn", false, "print warnings") ) +// Test holds test locations, package names, and test names. type Test struct { Loc string Name string @@ -262,7 +263,7 @@ func main() { log.Fatalf("Error walking: %v", err) } } - if *dumpJson { + if *dumpJSON { json, err := json.Marshal(tests.tests) if err != nil { log.Fatal(err) diff --git a/test/typecheck/BUILD b/test/typecheck/BUILD index 4b303e5a0501b..a7b35fd050dc7 100644 --- a/test/typecheck/BUILD +++ b/test/typecheck/BUILD @@ -17,8 +17,7 @@ go_library( srcs = ["main.go"], importpath = "k8s.io/kubernetes/test/typecheck", deps = [ - "//test/typecheck/srcimporter:go_default_library", - "//third_party/forked/golang/go/types:go_default_library", + "//third_party/go-srcimporter:go_default_library", "//vendor/golang.org/x/crypto/ssh/terminal:go_default_library", ], ) @@ -32,10 +31,7 @@ filegroup( filegroup( name = "all-srcs", - srcs = [ - ":package-srcs", - "//test/typecheck/srcimporter:all-srcs", - ], + srcs = [":package-srcs"], tags = ["automanaged"], ) diff --git a/test/typecheck/main.go b/test/typecheck/main.go index 2df32f41c8339..b6c55506af825 100644 --- a/test/typecheck/main.go +++ b/test/typecheck/main.go @@ -24,6 +24,7 @@ import ( "go/build" "go/parser" "go/token" + "go/types" "io" "log" "os" @@ -35,10 +36,8 @@ import ( "time" "golang.org/x/crypto/ssh/terminal" - // TODO(rmmh): remove this when golang/go#23712 is fixed, and the - // fix is the current minimum Go version to build Kubernetes. - "k8s.io/kubernetes/test/typecheck/srcimporter" - "k8s.io/kubernetes/third_party/forked/golang/go/types" + + srcimporter "k8s.io/kubernetes/third_party/go-srcimporter" ) var ( diff --git a/test/typecheck/main_test.go b/test/typecheck/main_test.go index 9b1fb830d561b..b03212c005039 100644 --- a/test/typecheck/main_test.go +++ b/test/typecheck/main_test.go @@ -43,7 +43,7 @@ var packageCases = []struct { if err != unix.ENXIO { panic("woops") } - }`, map[string]string{"linux/amd64": "", "windows/amd64": "test.go:4:13: ENXIO not declared by package unix"}}, + }`, map[string]string{"linux/amd64": "", "windows/amd64": "test.go:4:18: ENXIO not declared by package unix"}}, // Fixed in #51984 {`import "golang.org/x/sys/unix" const linuxHugetlbfsMagic = 0x958458f6 diff --git a/test/utils/BUILD b/test/utils/BUILD index 5a1023742f8d2..f594b7ba1448c 100644 --- a/test/utils/BUILD +++ b/test/utils/BUILD @@ -72,6 +72,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//test/utils/harness:all-srcs", "//test/utils/image:all-srcs", "//test/utils/junit:all-srcs", ], diff --git a/test/utils/harness/BUILD b/test/utils/harness/BUILD new file mode 100644 index 0000000000000..510a812713246 --- /dev/null +++ b/test/utils/harness/BUILD @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["harness.go"], + importpath = "k8s.io/kubernetes/test/utils/harness", + visibility = ["//visibility:public"], + deps = ["//vendor/github.com/golang/glog: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/test/utils/harness/harness.go b/test/utils/harness/harness.go new file mode 100644 index 0000000000000..a3c827318f327 --- /dev/null +++ b/test/utils/harness/harness.go @@ -0,0 +1,71 @@ +/* +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 harness + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/golang/glog" +) + +// Harness adds some functionality to testing.T, in particular resource cleanup. +// It embeds testing.T, so should have the same signature. +// +// Example usage: +// ``` +// func MyTest(tt *testing.T) { +// t := harness.For(tt) +// defer t.Close() +// ... +// } +// ``` +type Harness struct { + *testing.T + defers []func() error +} + +// For creates a Harness from a testing.T +// Callers must call Close on the Harness so that resources can be cleaned up +func For(t *testing.T) *Harness { + h := &Harness{T: t} + return h +} + +// Close cleans up any owned resources, and should be called in a defer block after For +func (h *Harness) Close() { + for _, d := range h.defers { + if err := d(); err != nil { + glog.Warningf("error closing harness: %v", err) + } + } +} + +// TempDir is a wrapper around ioutil.TempDir for tests. +// It automatically fails the test if we can't create a temp file, +// and deletes the temp directory when Close is called on the Harness +func (h *Harness) TempDir(baseDir string, prefix string) string { + tempDir, err := ioutil.TempDir(baseDir, prefix) + if err != nil { + h.Fatalf("unable to create tempdir: %v", err) + } + h.defers = append(h.defers, func() error { + return os.RemoveAll(tempDir) + }) + return tempDir +} diff --git a/test/utils/image/manifest.go b/test/utils/image/manifest.go index f4583d286b573..4e83ca47a0ec5 100644 --- a/test/utils/image/manifest.go +++ b/test/utils/image/manifest.go @@ -24,6 +24,7 @@ import ( yaml "gopkg.in/yaml.v2" ) +// RegistryList holds public and private image registries type RegistryList struct { DockerLibraryRegistry string `yaml:"dockerLibraryRegistry"` E2eRegistry string `yaml:"e2eRegistry"` @@ -31,21 +32,26 @@ type RegistryList struct { PrivateRegistry string `yaml:"privateRegistry"` SampleRegistry string `yaml:"sampleRegistry"` } -type ImageConfig struct { + +// Config holds an images registry, name, and version +type Config struct { registry string name string version string } -func (i *ImageConfig) SetRegistry(registry string) { +// SetRegistry sets an image registry in a Config struct +func (i *Config) SetRegistry(registry string) { i.registry = registry } -func (i *ImageConfig) SetName(name string) { +// SetName sets an image name in a Config struct +func (i *Config) SetName(name string) { i.name = name } -func (i *ImageConfig) SetVersion(version string) { +// SetVersion sets an image version in a Config struct +func (i *Config) SetVersion(version string) { i.version = version } @@ -79,55 +85,60 @@ var ( dockerLibraryRegistry = registry.DockerLibraryRegistry e2eRegistry = registry.E2eRegistry gcRegistry = registry.GcRegistry - PrivateRegistry = registry.PrivateRegistry - sampleRegistry = registry.SampleRegistry - - AdmissionWebhook = ImageConfig{e2eRegistry, "webhook", "1.13v1"} - APIServer = ImageConfig{e2eRegistry, "sample-apiserver", "1.10"} - AppArmorLoader = ImageConfig{e2eRegistry, "apparmor-loader", "1.0"} - BusyBox = ImageConfig{dockerLibraryRegistry, "busybox", "1.29"} - CheckMetadataConcealment = ImageConfig{e2eRegistry, "metadata-concealment", "1.0"} - CudaVectorAdd = ImageConfig{e2eRegistry, "cuda-vector-add", "1.0"} - Dnsutils = ImageConfig{e2eRegistry, "dnsutils", "1.1"} - EchoServer = ImageConfig{e2eRegistry, "echoserver", "2.2"} - EntrypointTester = ImageConfig{e2eRegistry, "entrypoint-tester", "1.0"} - Fakegitserver = ImageConfig{e2eRegistry, "fakegitserver", "1.0"} - GBFrontend = ImageConfig{sampleRegistry, "gb-frontend", "v6"} - GBRedisSlave = ImageConfig{sampleRegistry, "gb-redisslave", "v3"} - Hostexec = ImageConfig{e2eRegistry, "hostexec", "1.1"} - IpcUtils = ImageConfig{e2eRegistry, "ipc-utils", "1.0"} - Iperf = ImageConfig{e2eRegistry, "iperf", "1.0"} - JessieDnsutils = ImageConfig{e2eRegistry, "jessie-dnsutils", "1.0"} - Kitten = ImageConfig{e2eRegistry, "kitten", "1.0"} - Liveness = ImageConfig{e2eRegistry, "liveness", "1.0"} - LogsGenerator = ImageConfig{e2eRegistry, "logs-generator", "1.0"} - Mounttest = ImageConfig{e2eRegistry, "mounttest", "1.0"} - MounttestUser = ImageConfig{e2eRegistry, "mounttest-user", "1.0"} - Nautilus = ImageConfig{e2eRegistry, "nautilus", "1.0"} - Net = ImageConfig{e2eRegistry, "net", "1.0"} - Netexec = ImageConfig{e2eRegistry, "netexec", "1.1"} - Nettest = ImageConfig{e2eRegistry, "nettest", "1.0"} - Nginx = ImageConfig{dockerLibraryRegistry, "nginx", "1.14-alpine"} - NginxNew = ImageConfig{dockerLibraryRegistry, "nginx", "1.15-alpine"} - Nonewprivs = ImageConfig{e2eRegistry, "nonewprivs", "1.0"} - NoSnatTest = ImageConfig{e2eRegistry, "no-snat-test", "1.0"} - NoSnatTestProxy = ImageConfig{e2eRegistry, "no-snat-test-proxy", "1.0"} - // When these values are updated, also update cmd/kubelet/app/options/container_runtime.go - Pause = ImageConfig{gcRegistry, "pause", "3.1"} - Porter = ImageConfig{e2eRegistry, "porter", "1.0"} - PortForwardTester = ImageConfig{e2eRegistry, "port-forward-tester", "1.0"} - Redis = ImageConfig{e2eRegistry, "redis", "1.0"} - ResourceConsumer = ImageConfig{e2eRegistry, "resource-consumer", "1.3"} - ResourceController = ImageConfig{e2eRegistry, "resource-consumer/controller", "1.0"} - ServeHostname = ImageConfig{e2eRegistry, "serve-hostname", "1.1"} - TestWebserver = ImageConfig{e2eRegistry, "test-webserver", "1.0"} - VolumeNFSServer = ImageConfig{e2eRegistry, "volume/nfs", "1.0"} - VolumeISCSIServer = ImageConfig{e2eRegistry, "volume/iscsi", "1.0"} - VolumeGlusterServer = ImageConfig{e2eRegistry, "volume/gluster", "1.0"} - VolumeRBDServer = ImageConfig{e2eRegistry, "volume/rbd", "1.0.1"} + // PrivateRegistry is an image repository that requires authentication + PrivateRegistry = registry.PrivateRegistry + sampleRegistry = registry.SampleRegistry +) + +// Preconfigured image configs +var ( + AdmissionWebhook = Config{e2eRegistry, "webhook", "1.13v1"} + APIServer = Config{e2eRegistry, "sample-apiserver", "1.10"} + AppArmorLoader = Config{e2eRegistry, "apparmor-loader", "1.0"} + BusyBox = Config{dockerLibraryRegistry, "busybox", "1.29"} + CheckMetadataConcealment = Config{e2eRegistry, "metadata-concealment", "1.1.1"} + CudaVectorAdd = Config{e2eRegistry, "cuda-vector-add", "1.0"} + Dnsutils = Config{e2eRegistry, "dnsutils", "1.1"} + EchoServer = Config{e2eRegistry, "echoserver", "2.2"} + EntrypointTester = Config{e2eRegistry, "entrypoint-tester", "1.0"} + Fakegitserver = Config{e2eRegistry, "fakegitserver", "1.0"} + GBFrontend = Config{sampleRegistry, "gb-frontend", "v6"} + GBRedisSlave = Config{sampleRegistry, "gb-redisslave", "v3"} + Hostexec = Config{e2eRegistry, "hostexec", "1.1"} + IpcUtils = Config{e2eRegistry, "ipc-utils", "1.0"} + Iperf = Config{e2eRegistry, "iperf", "1.0"} + JessieDnsutils = Config{e2eRegistry, "jessie-dnsutils", "1.0"} + Kitten = Config{e2eRegistry, "kitten", "1.0"} + Liveness = Config{e2eRegistry, "liveness", "1.0"} + LogsGenerator = Config{e2eRegistry, "logs-generator", "1.0"} + Mounttest = Config{e2eRegistry, "mounttest", "1.0"} + MounttestUser = Config{e2eRegistry, "mounttest-user", "1.0"} + Nautilus = Config{e2eRegistry, "nautilus", "1.0"} + Net = Config{e2eRegistry, "net", "1.0"} + Netexec = Config{e2eRegistry, "netexec", "1.1"} + Nettest = Config{e2eRegistry, "nettest", "1.0"} + Nginx = Config{dockerLibraryRegistry, "nginx", "1.14-alpine"} + NginxNew = Config{dockerLibraryRegistry, "nginx", "1.15-alpine"} + Nonewprivs = Config{e2eRegistry, "nonewprivs", "1.0"} + NoSnatTest = Config{e2eRegistry, "no-snat-test", "1.0"} + NoSnatTestProxy = Config{e2eRegistry, "no-snat-test-proxy", "1.0"} + // Pause - when these values are updated, also update cmd/kubelet/app/options/container_runtime.go + Pause = Config{gcRegistry, "pause", "3.1"} + Porter = Config{e2eRegistry, "porter", "1.0"} + PortForwardTester = Config{e2eRegistry, "port-forward-tester", "1.0"} + Redis = Config{e2eRegistry, "redis", "1.0"} + ResourceConsumer = Config{e2eRegistry, "resource-consumer", "1.4"} + ResourceController = Config{e2eRegistry, "resource-consumer/controller", "1.0"} + ServeHostname = Config{e2eRegistry, "serve-hostname", "1.1"} + TestWebserver = Config{e2eRegistry, "test-webserver", "1.0"} + VolumeNFSServer = Config{e2eRegistry, "volume/nfs", "1.0"} + VolumeISCSIServer = Config{e2eRegistry, "volume/iscsi", "1.0"} + VolumeGlusterServer = Config{e2eRegistry, "volume/gluster", "1.0"} + VolumeRBDServer = Config{e2eRegistry, "volume/rbd", "1.0.1"} ) -func GetE2EImage(image ImageConfig) string { +// GetE2EImage returns the fully qualified URI to an image (including version) +func GetE2EImage(image Config) string { return fmt.Sprintf("%s/%s:%s", image.registry, image.name, image.version) } diff --git a/test/utils/runners.go b/test/utils/runners.go index 09da3be11e724..2cc6456b293f0 100644 --- a/test/utils/runners.go +++ b/test/utils/runners.go @@ -21,6 +21,7 @@ import ( "fmt" "math" "os" + "strings" "sync" "time" @@ -172,6 +173,8 @@ type RCConfig struct { // Names of the secrets and configmaps to mount. SecretNames []string ConfigMapNames []string + + ServiceAccountTokenProjections int } func (rc *RCConfig) RCConfigLog(fmt string, args ...interface{}) { @@ -240,6 +243,18 @@ func (p PodDiff) String(ignorePhases sets.String) string { return ret } +// DeletedPods returns a slice of pods that were present at the beginning +// and then disappeared. +func (p PodDiff) DeletedPods() []string { + var deletedPods []string + for podName, podInfo := range p { + if podInfo.hostname == nonExist { + deletedPods = append(deletedPods, podName) + } + } + return deletedPods +} + // Diff computes a PodDiff given 2 lists of pods. func Diff(oldPods []*v1.Pod, curPods []*v1.Pod) PodDiff { podInfoMap := PodDiff{} @@ -322,6 +337,10 @@ func (config *DeploymentConfig) create() error { attachConfigMaps(&deployment.Spec.Template, config.ConfigMapNames) } + for i := 0; i < config.ServiceAccountTokenProjections; i++ { + attachServiceAccountTokenProjection(&deployment.Spec.Template, fmt.Sprintf("tok-%d", i)) + } + config.applyTo(&deployment.Spec.Template) if err := CreateDeploymentWithRetries(config.Client, config.Namespace, deployment); err != nil { @@ -759,9 +778,8 @@ func (config *RCConfig) start() error { pods := ps.List() startupStatus := ComputeRCStartupStatus(pods, config.Replicas) - pods = startupStatus.Created if config.CreatedPods != nil { - *config.CreatedPods = pods + *config.CreatedPods = startupStatus.Created } if !config.Silent { config.RCConfigLog(startupStatus.String(config.Name)) @@ -781,16 +799,15 @@ func (config *RCConfig) start() error { } return fmt.Errorf("%d containers failed which is more than allowed %d", startupStatus.FailedContainers, maxContainerFailures) } - if len(pods) < len(oldPods) || len(pods) > config.Replicas { - // This failure mode includes: - // kubelet is dead, so node controller deleted pods and rc creates more - // - diagnose by noting the pod diff below. - // pod is unhealthy, so replication controller creates another to take its place - // - diagnose by comparing the previous "2 Pod states" lines for inactive pods - errorStr := fmt.Sprintf("Number of reported pods for %s changed: %d vs %d", config.Name, len(pods), len(oldPods)) - config.RCConfigLog("%v, pods that changed since the last iteration:", errorStr) - config.RCConfigLog(Diff(oldPods, pods).String(sets.NewString())) - return fmt.Errorf(errorStr) + + diff := Diff(oldPods, pods) + deletedPods := diff.DeletedPods() + if len(deletedPods) != 0 { + // There are some pods that have disappeared. + err := fmt.Errorf("%d pods disappeared for %s: %v", len(deletedPods), config.Name, strings.Join(deletedPods, ", ")) + config.RCConfigLog(err.Error()) + config.RCConfigLog(diff.String(sets.NewString())) + return err } if len(pods) > len(oldPods) || startupStatus.Running > oldRunning { @@ -1241,6 +1258,57 @@ func attachConfigMaps(template *v1.PodTemplateSpec, configMapNames []string) { template.Spec.Containers[0].VolumeMounts = mounts } +func attachServiceAccountTokenProjection(template *v1.PodTemplateSpec, name string) { + template.Spec.Containers[0].VolumeMounts = append(template.Spec.Containers[0].VolumeMounts, + v1.VolumeMount{ + Name: name, + MountPath: "/var/service-account-tokens/" + name, + }) + + template.Spec.Volumes = append(template.Spec.Volumes, + v1.Volume{ + Name: name, + VolumeSource: v1.VolumeSource{ + Projected: &v1.ProjectedVolumeSource{ + Sources: []v1.VolumeProjection{ + { + ServiceAccountToken: &v1.ServiceAccountTokenProjection{ + Path: "token", + Audience: name, + }, + }, + { + ConfigMap: &v1.ConfigMapProjection{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "kube-root-ca-crt", + }, + Items: []v1.KeyToPath{ + { + Key: "ca.crt", + Path: "ca.crt", + }, + }, + }, + }, + { + DownwardAPI: &v1.DownwardAPIProjection{ + Items: []v1.DownwardAPIVolumeFile{ + { + Path: "namespace", + FieldRef: &v1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.namespace", + }, + }, + }, + }, + }, + }, + }, + }, + }) +} + type DaemonConfig struct { Client clientset.Interface Name string diff --git a/third_party/BUILD b/third_party/BUILD index 2beec65ec667a..ce2dc0c079bf9 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -23,10 +23,10 @@ filegroup( "//third_party/forked/etcd237/pkg/fileutil:all-srcs", "//third_party/forked/etcd237/wal:all-srcs", "//third_party/forked/golang/expansion:all-srcs", - "//third_party/forked/golang/go/types:all-srcs", "//third_party/forked/golang/reflect:all-srcs", "//third_party/forked/golang/template:all-srcs", "//third_party/forked/gonum/graph:all-srcs", + "//third_party/go-srcimporter:all-srcs", ], tags = ["automanaged"], ) diff --git a/third_party/forked/golang/go/types/BUILD b/third_party/forked/golang/go/types/BUILD deleted file mode 100644 index df42eff853d25..0000000000000 --- a/third_party/forked/golang/go/types/BUILD +++ /dev/null @@ -1,56 +0,0 @@ -licenses(["notice"]) - -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "api.go", - "assignments.go", - "builtins.go", - "call.go", - "check.go", - "conversions.go", - "decl.go", - "errors.go", - "eval.go", - "expr.go", - "exprstring.go", - "initorder.go", - "labels.go", - "lookup.go", - "methodset.go", - "object.go", - "objset.go", - "operand.go", - "ordering.go", - "package.go", - "predicates.go", - "resolver.go", - "return.go", - "scope.go", - "selection.go", - "sizes.go", - "stmt.go", - "type.go", - "typestring.go", - "typexpr.go", - "universe.go", - ], - importpath = "k8s.io/kubernetes/third_party/forked/golang/go/types", - visibility = ["//visibility:public"], -) - -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/third_party/forked/golang/go/types/README b/third_party/forked/golang/go/types/README deleted file mode 100644 index c0c93fef360d0..0000000000000 --- a/third_party/forked/golang/go/types/README +++ /dev/null @@ -1,7 +0,0 @@ -This is go/types forked from go@236abdb46b (just after 1.10) and cherry-picked -1006f703ffc, which fixes https://github.com/golang/go/issues/23712. - -It can be removed when all builders are >= go1.11. - -Do *not* update this to newer code if https://github.com/golang/go/issues/23914 -has not been fixed! diff --git a/third_party/forked/golang/go/types/api.go b/third_party/forked/golang/go/types/api.go deleted file mode 100644 index 9908f5c9738b8..0000000000000 --- a/third_party/forked/golang/go/types/api.go +++ /dev/null @@ -1,376 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package types declares the data types and implements -// the algorithms for type-checking of Go packages. Use -// Config.Check to invoke the type checker for a package. -// Alternatively, create a new type checker with NewChecker -// and invoke it incrementally by calling Checker.Files. -// -// Type-checking consists of several interdependent phases: -// -// Name resolution maps each identifier (ast.Ident) in the program to the -// language object (Object) it denotes. -// Use Info.{Defs,Uses,Implicits} for the results of name resolution. -// -// Constant folding computes the exact constant value (constant.Value) -// for every expression (ast.Expr) that is a compile-time constant. -// Use Info.Types[expr].Value for the results of constant folding. -// -// Type inference computes the type (Type) of every expression (ast.Expr) -// and checks for compliance with the language specification. -// Use Info.Types[expr].Type for the results of type inference. -// -// For a tutorial, see https://golang.org/s/types-tutorial. -// -package types - -import ( - "bytes" - "fmt" - "go/ast" - "go/constant" - "go/token" -) - -// An Error describes a type-checking error; it implements the error interface. -// A "soft" error is an error that still permits a valid interpretation of a -// package (such as "unused variable"); "hard" errors may lead to unpredictable -// behavior if ignored. -type Error struct { - Fset *token.FileSet // file set for interpretation of Pos - Pos token.Pos // error position - Msg string // error message - Soft bool // if set, error is "soft" -} - -// Error returns an error string formatted as follows: -// filename:line:column: message -func (err Error) Error() string { - return fmt.Sprintf("%s: %s", err.Fset.Position(err.Pos), err.Msg) -} - -// An Importer resolves import paths to Packages. -// -// CAUTION: This interface does not support the import of locally -// vendored packages. See https://golang.org/s/go15vendor. -// If possible, external implementations should implement ImporterFrom. -type Importer interface { - // Import returns the imported package for the given import path. - // The semantics is like for ImporterFrom.ImportFrom except that - // dir and mode are ignored (since they are not present). - Import(path string) (*Package, error) -} - -// ImportMode is reserved for future use. -type ImportMode int - -// An ImporterFrom resolves import paths to packages; it -// supports vendoring per https://golang.org/s/go15vendor. -// Use go/importer to obtain an ImporterFrom implementation. -type ImporterFrom interface { - // Importer is present for backward-compatibility. Calling - // Import(path) is the same as calling ImportFrom(path, "", 0); - // i.e., locally vendored packages may not be found. - // The types package does not call Import if an ImporterFrom - // is present. - Importer - - // ImportFrom returns the imported package for the given import - // path when imported by a package file located in dir. - // If the import failed, besides returning an error, ImportFrom - // is encouraged to cache and return a package anyway, if one - // was created. This will reduce package inconsistencies and - // follow-on type checker errors due to the missing package. - // The mode value must be 0; it is reserved for future use. - // Two calls to ImportFrom with the same path and dir must - // return the same package. - ImportFrom(path, dir string, mode ImportMode) (*Package, error) -} - -// A Config specifies the configuration for type checking. -// The zero value for Config is a ready-to-use default configuration. -type Config struct { - // If IgnoreFuncBodies is set, function bodies are not - // type-checked. - IgnoreFuncBodies bool - - // If FakeImportC is set, `import "C"` (for packages requiring Cgo) - // declares an empty "C" package and errors are omitted for qualified - // identifiers referring to package C (which won't find an object). - // This feature is intended for the standard library cmd/api tool. - // - // Caution: Effects may be unpredictable due to follow-on errors. - // Do not use casually! - FakeImportC bool - - // If Error != nil, it is called with each error found - // during type checking; err has dynamic type Error. - // Secondary errors (for instance, to enumerate all types - // involved in an invalid recursive type declaration) have - // error strings that start with a '\t' character. - // If Error == nil, type-checking stops with the first - // error found. - Error func(err error) - - // An importer is used to import packages referred to from - // import declarations. - // If the installed importer implements ImporterFrom, the type - // checker calls ImportFrom instead of Import. - // The type checker reports an error if an importer is needed - // but none was installed. - Importer Importer - - // If Sizes != nil, it provides the sizing functions for package unsafe. - // Otherwise SizesFor("gc", "amd64") is used instead. - Sizes Sizes - - // If DisableUnusedImportCheck is set, packages are not checked - // for unused imports. - DisableUnusedImportCheck bool -} - -// Info holds result type information for a type-checked package. -// Only the information for which a map is provided is collected. -// If the package has type errors, the collected information may -// be incomplete. -type Info struct { - // Types maps expressions to their types, and for constant - // expressions, also their values. Invalid expressions are - // omitted. - // - // For (possibly parenthesized) identifiers denoting built-in - // functions, the recorded signatures are call-site specific: - // if the call result is not a constant, the recorded type is - // an argument-specific signature. Otherwise, the recorded type - // is invalid. - // - // The Types map does not record the type of every identifier, - // only those that appear where an arbitrary expression is - // permitted. For instance, the identifier f in a selector - // expression x.f is found only in the Selections map, the - // identifier z in a variable declaration 'var z int' is found - // only in the Defs map, and identifiers denoting packages in - // qualified identifiers are collected in the Uses map. - Types map[ast.Expr]TypeAndValue - - // Defs maps identifiers to the objects they define (including - // package names, dots "." of dot-imports, and blank "_" identifiers). - // For identifiers that do not denote objects (e.g., the package name - // in package clauses, or symbolic variables t in t := x.(type) of - // type switch headers), the corresponding objects are nil. - // - // For an anonymous field, Defs returns the field *Var it defines. - // - // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos() - Defs map[*ast.Ident]Object - - // Uses maps identifiers to the objects they denote. - // - // For an anonymous field, Uses returns the *TypeName it denotes. - // - // Invariant: Uses[id].Pos() != id.Pos() - Uses map[*ast.Ident]Object - - // Implicits maps nodes to their implicitly declared objects, if any. - // The following node and object types may appear: - // - // node declared object - // - // *ast.ImportSpec *PkgName for imports without renames - // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default) - // *ast.Field anonymous parameter *Var - // - Implicits map[ast.Node]Object - - // Selections maps selector expressions (excluding qualified identifiers) - // to their corresponding selections. - Selections map[*ast.SelectorExpr]*Selection - - // Scopes maps ast.Nodes to the scopes they define. Package scopes are not - // associated with a specific node but with all files belonging to a package. - // Thus, the package scope can be found in the type-checked Package object. - // Scopes nest, with the Universe scope being the outermost scope, enclosing - // the package scope, which contains (one or more) files scopes, which enclose - // function scopes which in turn enclose statement and function literal scopes. - // Note that even though package-level functions are declared in the package - // scope, the function scopes are embedded in the file scope of the file - // containing the function declaration. - // - // The following node types may appear in Scopes: - // - // *ast.File - // *ast.FuncType - // *ast.BlockStmt - // *ast.IfStmt - // *ast.SwitchStmt - // *ast.TypeSwitchStmt - // *ast.CaseClause - // *ast.CommClause - // *ast.ForStmt - // *ast.RangeStmt - // - Scopes map[ast.Node]*Scope - - // InitOrder is the list of package-level initializers in the order in which - // they must be executed. Initializers referring to variables related by an - // initialization dependency appear in topological order, the others appear - // in source order. Variables without an initialization expression do not - // appear in this list. - InitOrder []*Initializer -} - -// TypeOf returns the type of expression e, or nil if not found. -// Precondition: the Types, Uses and Defs maps are populated. -// -func (info *Info) TypeOf(e ast.Expr) Type { - if t, ok := info.Types[e]; ok { - return t.Type - } - if id, _ := e.(*ast.Ident); id != nil { - if obj := info.ObjectOf(id); obj != nil { - return obj.Type() - } - } - return nil -} - -// ObjectOf returns the object denoted by the specified id, -// or nil if not found. -// -// If id is an anonymous struct field, ObjectOf returns the field (*Var) -// it uses, not the type (*TypeName) it defines. -// -// Precondition: the Uses and Defs maps are populated. -// -func (info *Info) ObjectOf(id *ast.Ident) Object { - if obj := info.Defs[id]; obj != nil { - return obj - } - return info.Uses[id] -} - -// TypeAndValue reports the type and value (for constants) -// of the corresponding expression. -type TypeAndValue struct { - mode operandMode - Type Type - Value constant.Value -} - -// TODO(gri) Consider eliminating the IsVoid predicate. Instead, report -// "void" values as regular values but with the empty tuple type. - -// IsVoid reports whether the corresponding expression -// is a function call without results. -func (tv TypeAndValue) IsVoid() bool { - return tv.mode == novalue -} - -// IsType reports whether the corresponding expression specifies a type. -func (tv TypeAndValue) IsType() bool { - return tv.mode == typexpr -} - -// IsBuiltin reports whether the corresponding expression denotes -// a (possibly parenthesized) built-in function. -func (tv TypeAndValue) IsBuiltin() bool { - return tv.mode == builtin -} - -// IsValue reports whether the corresponding expression is a value. -// Builtins are not considered values. Constant values have a non- -// nil Value. -func (tv TypeAndValue) IsValue() bool { - switch tv.mode { - case constant_, variable, mapindex, value, commaok: - return true - } - return false -} - -// IsNil reports whether the corresponding expression denotes the -// predeclared value nil. -func (tv TypeAndValue) IsNil() bool { - return tv.mode == value && tv.Type == Typ[UntypedNil] -} - -// Addressable reports whether the corresponding expression -// is addressable (https://golang.org/ref/spec#Address_operators). -func (tv TypeAndValue) Addressable() bool { - return tv.mode == variable -} - -// Assignable reports whether the corresponding expression -// is assignable to (provided a value of the right type). -func (tv TypeAndValue) Assignable() bool { - return tv.mode == variable || tv.mode == mapindex -} - -// HasOk reports whether the corresponding expression may be -// used on the lhs of a comma-ok assignment. -func (tv TypeAndValue) HasOk() bool { - return tv.mode == commaok || tv.mode == mapindex -} - -// An Initializer describes a package-level variable, or a list of variables in case -// of a multi-valued initialization expression, and the corresponding initialization -// expression. -type Initializer struct { - Lhs []*Var // var Lhs = Rhs - Rhs ast.Expr -} - -func (init *Initializer) String() string { - var buf bytes.Buffer - for i, lhs := range init.Lhs { - if i > 0 { - buf.WriteString(", ") - } - buf.WriteString(lhs.Name()) - } - buf.WriteString(" = ") - WriteExpr(&buf, init.Rhs) - return buf.String() -} - -// Check type-checks a package and returns the resulting package object and -// the first error if any. Additionally, if info != nil, Check populates each -// of the non-nil maps in the Info struct. -// -// The package is marked as complete if no errors occurred, otherwise it is -// incomplete. See Config.Error for controlling behavior in the presence of -// errors. -// -// The package is specified by a list of *ast.Files and corresponding -// file set, and the package path the package is identified with. -// The clean path must not be empty or dot ("."). -func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) { - pkg := NewPackage(path, "") - return pkg, NewChecker(conf, fset, pkg, info).Files(files) -} - -// AssertableTo reports whether a value of type V can be asserted to have type T. -func AssertableTo(V *Interface, T Type) bool { - m, _ := assertableTo(V, T) - return m == nil -} - -// AssignableTo reports whether a value of type V is assignable to a variable of type T. -func AssignableTo(V, T Type) bool { - x := operand{mode: value, typ: V} - return x.assignableTo(nil, T, nil) // config not needed for non-constant x -} - -// ConvertibleTo reports whether a value of type V is convertible to a value of type T. -func ConvertibleTo(V, T Type) bool { - x := operand{mode: value, typ: V} - return x.convertibleTo(nil, T) // config not needed for non-constant x -} - -// Implements reports whether type V implements interface T. -func Implements(V Type, T *Interface) bool { - f, _ := MissingMethod(V, T, true) - return f == nil -} diff --git a/third_party/forked/golang/go/types/assignments.go b/third_party/forked/golang/go/types/assignments.go deleted file mode 100644 index 98c9e121b055a..0000000000000 --- a/third_party/forked/golang/go/types/assignments.go +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements initialization and assignment checks. - -package types - -import ( - "go/ast" - "go/token" -) - -// assignment reports whether x can be assigned to a variable of type T, -// if necessary by attempting to convert untyped values to the appropriate -// type. context describes the context in which the assignment takes place. -// Use T == nil to indicate assignment to an untyped blank identifier. -// x.mode is set to invalid if the assignment failed. -func (check *Checker) assignment(x *operand, T Type, context string) { - check.singleValue(x) - - switch x.mode { - case invalid: - return // error reported before - case constant_, variable, mapindex, value, commaok: - // ok - default: - unreachable() - } - - if isUntyped(x.typ) { - target := T - // spec: "If an untyped constant is assigned to a variable of interface - // type or the blank identifier, the constant is first converted to type - // bool, rune, int, float64, complex128 or string respectively, depending - // on whether the value is a boolean, rune, integer, floating-point, complex, - // or string constant." - if T == nil || IsInterface(T) { - if T == nil && x.typ == Typ[UntypedNil] { - check.errorf(x.pos(), "use of untyped nil in %s", context) - x.mode = invalid - return - } - target = Default(x.typ) - } - check.convertUntyped(x, target) - if x.mode == invalid { - return - } - } - // x.typ is typed - - // spec: "If a left-hand side is the blank identifier, any typed or - // non-constant value except for the predeclared identifier nil may - // be assigned to it." - if T == nil { - return - } - - if reason := ""; !x.assignableTo(check.conf, T, &reason) { - if reason != "" { - check.errorf(x.pos(), "cannot use %s as %s value in %s: %s", x, T, context, reason) - } else { - check.errorf(x.pos(), "cannot use %s as %s value in %s", x, T, context) - } - x.mode = invalid - } -} - -func (check *Checker) initConst(lhs *Const, x *operand) { - if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { - if lhs.typ == nil { - lhs.typ = Typ[Invalid] - } - return - } - - // rhs must be a constant - if x.mode != constant_ { - check.errorf(x.pos(), "%s is not constant", x) - if lhs.typ == nil { - lhs.typ = Typ[Invalid] - } - return - } - assert(isConstType(x.typ)) - - // If the lhs doesn't have a type yet, use the type of x. - if lhs.typ == nil { - lhs.typ = x.typ - } - - check.assignment(x, lhs.typ, "constant declaration") - if x.mode == invalid { - return - } - - lhs.val = x.val -} - -func (check *Checker) initVar(lhs *Var, x *operand, context string) Type { - if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { - if lhs.typ == nil { - lhs.typ = Typ[Invalid] - } - return nil - } - - // If the lhs doesn't have a type yet, use the type of x. - if lhs.typ == nil { - typ := x.typ - if isUntyped(typ) { - // convert untyped types to default types - if typ == Typ[UntypedNil] { - check.errorf(x.pos(), "use of untyped nil in %s", context) - lhs.typ = Typ[Invalid] - return nil - } - typ = Default(typ) - } - lhs.typ = typ - } - - check.assignment(x, lhs.typ, context) - if x.mode == invalid { - return nil - } - - return x.typ -} - -func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type { - if x.mode == invalid || x.typ == Typ[Invalid] { - return nil - } - - // Determine if the lhs is a (possibly parenthesized) identifier. - ident, _ := unparen(lhs).(*ast.Ident) - - // Don't evaluate lhs if it is the blank identifier. - if ident != nil && ident.Name == "_" { - check.recordDef(ident, nil) - check.assignment(x, nil, "assignment to _ identifier") - if x.mode == invalid { - return nil - } - return x.typ - } - - // If the lhs is an identifier denoting a variable v, this assignment - // is not a 'use' of v. Remember current value of v.used and restore - // after evaluating the lhs via check.expr. - var v *Var - var v_used bool - if ident != nil { - if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil { - // It's ok to mark non-local variables, but ignore variables - // from other packages to avoid potential race conditions with - // dot-imported variables. - if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg { - v = w - v_used = v.used - } - } - } - - var z operand - check.expr(&z, lhs) - if v != nil { - v.used = v_used // restore v.used - } - - if z.mode == invalid || z.typ == Typ[Invalid] { - return nil - } - - // spec: "Each left-hand side operand must be addressable, a map index - // expression, or the blank identifier. Operands may be parenthesized." - switch z.mode { - case invalid: - return nil - case variable, mapindex: - // ok - default: - if sel, ok := z.expr.(*ast.SelectorExpr); ok { - var op operand - check.expr(&op, sel.X) - if op.mode == mapindex { - check.errorf(z.pos(), "cannot assign to struct field %s in map", ExprString(z.expr)) - return nil - } - } - check.errorf(z.pos(), "cannot assign to %s", &z) - return nil - } - - check.assignment(x, z.typ, "assignment") - if x.mode == invalid { - return nil - } - - return x.typ -} - -// If returnPos is valid, initVars is called to type-check the assignment of -// return expressions, and returnPos is the position of the return statement. -func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) { - l := len(lhs) - get, r, commaOk := unpack(func(x *operand, i int) { check.multiExpr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid()) - if get == nil || l != r { - // invalidate lhs and use rhs - for _, obj := range lhs { - if obj.typ == nil { - obj.typ = Typ[Invalid] - } - } - if get == nil { - return // error reported by unpack - } - check.useGetter(get, r) - if returnPos.IsValid() { - check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r) - return - } - check.errorf(rhs[0].Pos(), "cannot initialize %d variables with %d values", l, r) - return - } - - context := "assignment" - if returnPos.IsValid() { - context = "return statement" - } - - var x operand - if commaOk { - var a [2]Type - for i := range a { - get(&x, i) - a[i] = check.initVar(lhs[i], &x, context) - } - check.recordCommaOkTypes(rhs[0], a) - return - } - - for i, lhs := range lhs { - get(&x, i) - check.initVar(lhs, &x, context) - } -} - -func (check *Checker) assignVars(lhs, rhs []ast.Expr) { - l := len(lhs) - get, r, commaOk := unpack(func(x *operand, i int) { check.multiExpr(x, rhs[i]) }, len(rhs), l == 2) - if get == nil { - check.useLHS(lhs...) - return // error reported by unpack - } - if l != r { - check.useGetter(get, r) - check.errorf(rhs[0].Pos(), "cannot assign %d values to %d variables", r, l) - return - } - - var x operand - if commaOk { - var a [2]Type - for i := range a { - get(&x, i) - a[i] = check.assignVar(lhs[i], &x) - } - check.recordCommaOkTypes(rhs[0], a) - return - } - - for i, lhs := range lhs { - get(&x, i) - check.assignVar(lhs, &x) - } -} - -func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) { - scope := check.scope - - // collect lhs variables - var newVars []*Var - var lhsVars = make([]*Var, len(lhs)) - for i, lhs := range lhs { - var obj *Var - if ident, _ := lhs.(*ast.Ident); ident != nil { - // Use the correct obj if the ident is redeclared. The - // variable's scope starts after the declaration; so we - // must use Scope.Lookup here and call Scope.Insert - // (via check.declare) later. - name := ident.Name - if alt := scope.Lookup(name); alt != nil { - // redeclared object must be a variable - if alt, _ := alt.(*Var); alt != nil { - obj = alt - } else { - check.errorf(lhs.Pos(), "cannot assign to %s", lhs) - } - check.recordUse(ident, alt) - } else { - // declare new variable, possibly a blank (_) variable - obj = NewVar(ident.Pos(), check.pkg, name, nil) - if name != "_" { - newVars = append(newVars, obj) - } - check.recordDef(ident, obj) - } - } else { - check.errorf(lhs.Pos(), "cannot declare %s", lhs) - } - if obj == nil { - obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable - } - lhsVars[i] = obj - } - - check.initVars(lhsVars, rhs, token.NoPos) - - // declare new variables - if len(newVars) > 0 { - // spec: "The scope of a constant or variable identifier declared inside - // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl - // for short variable declarations) and ends at the end of the innermost - // containing block." - scopePos := rhs[len(rhs)-1].End() - for _, obj := range newVars { - check.declare(scope, nil, obj, scopePos) // recordObject already called - } - } else { - check.softErrorf(pos, "no new variables on left side of :=") - } -} diff --git a/third_party/forked/golang/go/types/builtins.go b/third_party/forked/golang/go/types/builtins.go deleted file mode 100644 index 87f80630ac1cf..0000000000000 --- a/third_party/forked/golang/go/types/builtins.go +++ /dev/null @@ -1,670 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements typechecking of builtin function calls. - -package types - -import ( - "go/ast" - "go/constant" - "go/token" -) - -// builtin type-checks a call to the built-in specified by id and -// returns true if the call is valid, with *x holding the result; -// but x.expr is not set. If the call is invalid, the result is -// false, and *x is undefined. -// -func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) { - // append is the only built-in that permits the use of ... for the last argument - bin := predeclaredFuncs[id] - if call.Ellipsis.IsValid() && id != _Append { - check.invalidOp(call.Ellipsis, "invalid use of ... with built-in %s", bin.name) - check.use(call.Args...) - return - } - - // For len(x) and cap(x) we need to know if x contains any function calls or - // receive operations. Save/restore current setting and set hasCallOrRecv to - // false for the evaluation of x so that we can check it afterwards. - // Note: We must do this _before_ calling unpack because unpack evaluates the - // first argument before we even call arg(x, 0)! - if id == _Len || id == _Cap { - defer func(b bool) { - check.hasCallOrRecv = b - }(check.hasCallOrRecv) - check.hasCallOrRecv = false - } - - // determine actual arguments - var arg getter - nargs := len(call.Args) - switch id { - default: - // make argument getter - arg, nargs, _ = unpack(func(x *operand, i int) { check.multiExpr(x, call.Args[i]) }, nargs, false) - if arg == nil { - return - } - // evaluate first argument, if present - if nargs > 0 { - arg(x, 0) - if x.mode == invalid { - return - } - } - case _Make, _New, _Offsetof, _Trace: - // arguments require special handling - } - - // check argument count - { - msg := "" - if nargs < bin.nargs { - msg = "not enough" - } else if !bin.variadic && nargs > bin.nargs { - msg = "too many" - } - if msg != "" { - check.invalidOp(call.Rparen, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs) - return - } - } - - switch id { - case _Append: - // append(s S, x ...T) S, where T is the element type of S - // spec: "The variadic function append appends zero or more values x to s of type - // S, which must be a slice type, and returns the resulting slice, also of type S. - // The values x are passed to a parameter of type ...T where T is the element type - // of S and the respective parameter passing rules apply." - S := x.typ - var T Type - if s, _ := S.Underlying().(*Slice); s != nil { - T = s.elem - } else { - check.invalidArg(x.pos(), "%s is not a slice", x) - return - } - - // remember arguments that have been evaluated already - alist := []operand{*x} - - // spec: "As a special case, append also accepts a first argument assignable - // to type []byte with a second argument of string type followed by ... . - // This form appends the bytes of the string. - if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check.conf, NewSlice(universeByte), nil) { - arg(x, 1) - if x.mode == invalid { - return - } - if isString(x.typ) { - if check.Types != nil { - sig := makeSig(S, S, x.typ) - sig.variadic = true - check.recordBuiltinType(call.Fun, sig) - } - x.mode = value - x.typ = S - break - } - alist = append(alist, *x) - // fallthrough - } - - // check general case by creating custom signature - sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature - sig.variadic = true - check.arguments(x, call, sig, func(x *operand, i int) { - // only evaluate arguments that have not been evaluated before - if i < len(alist) { - *x = alist[i] - return - } - arg(x, i) - }, nargs) - // ok to continue even if check.arguments reported errors - - x.mode = value - x.typ = S - if check.Types != nil { - check.recordBuiltinType(call.Fun, sig) - } - - case _Cap, _Len: - // cap(x) - // len(x) - mode := invalid - var typ Type - var val constant.Value - switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) { - case *Basic: - if isString(t) && id == _Len { - if x.mode == constant_ { - mode = constant_ - val = constant.MakeInt64(int64(len(constant.StringVal(x.val)))) - } else { - mode = value - } - } - - case *Array: - mode = value - // spec: "The expressions len(s) and cap(s) are constants - // if the type of s is an array or pointer to an array and - // the expression s does not contain channel receives or - // function calls; in this case s is not evaluated." - if !check.hasCallOrRecv { - mode = constant_ - if t.len >= 0 { - val = constant.MakeInt64(t.len) - } else { - val = constant.MakeUnknown() - } - } - - case *Slice, *Chan: - mode = value - - case *Map: - if id == _Len { - mode = value - } - } - - if mode == invalid { - check.invalidArg(x.pos(), "%s for %s", x, bin.name) - return - } - - x.mode = mode - x.typ = Typ[Int] - x.val = val - if check.Types != nil && mode != constant_ { - check.recordBuiltinType(call.Fun, makeSig(x.typ, typ)) - } - - case _Close: - // close(c) - c, _ := x.typ.Underlying().(*Chan) - if c == nil { - check.invalidArg(x.pos(), "%s is not a channel", x) - return - } - if c.dir == RecvOnly { - check.invalidArg(x.pos(), "%s must not be a receive-only channel", x) - return - } - - x.mode = novalue - if check.Types != nil { - check.recordBuiltinType(call.Fun, makeSig(nil, c)) - } - - case _Complex: - // complex(x, y floatT) complexT - var y operand - arg(&y, 1) - if y.mode == invalid { - return - } - - // convert or check untyped arguments - d := 0 - if isUntyped(x.typ) { - d |= 1 - } - if isUntyped(y.typ) { - d |= 2 - } - switch d { - case 0: - // x and y are typed => nothing to do - case 1: - // only x is untyped => convert to type of y - check.convertUntyped(x, y.typ) - case 2: - // only y is untyped => convert to type of x - check.convertUntyped(&y, x.typ) - case 3: - // x and y are untyped => - // 1) if both are constants, convert them to untyped - // floating-point numbers if possible, - // 2) if one of them is not constant (possible because - // it contains a shift that is yet untyped), convert - // both of them to float64 since they must have the - // same type to succeed (this will result in an error - // because shifts of floats are not permitted) - if x.mode == constant_ && y.mode == constant_ { - toFloat := func(x *operand) { - if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 { - x.typ = Typ[UntypedFloat] - } - } - toFloat(x) - toFloat(&y) - } else { - check.convertUntyped(x, Typ[Float64]) - check.convertUntyped(&y, Typ[Float64]) - // x and y should be invalid now, but be conservative - // and check below - } - } - if x.mode == invalid || y.mode == invalid { - return - } - - // both argument types must be identical - if !Identical(x.typ, y.typ) { - check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ) - return - } - - // the argument types must be of floating-point type - if !isFloat(x.typ) { - check.invalidArg(x.pos(), "arguments have type %s, expected floating-point", x.typ) - return - } - - // if both arguments are constants, the result is a constant - if x.mode == constant_ && y.mode == constant_ { - x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val))) - } else { - x.mode = value - } - - // determine result type - var res BasicKind - switch x.typ.Underlying().(*Basic).kind { - case Float32: - res = Complex64 - case Float64: - res = Complex128 - case UntypedFloat: - res = UntypedComplex - default: - unreachable() - } - resTyp := Typ[res] - - if check.Types != nil && x.mode != constant_ { - check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ)) - } - - x.typ = resTyp - - case _Copy: - // copy(x, y []T) int - var dst Type - if t, _ := x.typ.Underlying().(*Slice); t != nil { - dst = t.elem - } - - var y operand - arg(&y, 1) - if y.mode == invalid { - return - } - var src Type - switch t := y.typ.Underlying().(type) { - case *Basic: - if isString(y.typ) { - src = universeByte - } - case *Slice: - src = t.elem - } - - if dst == nil || src == nil { - check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y) - return - } - - if !Identical(dst, src) { - check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src) - return - } - - if check.Types != nil { - check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ)) - } - x.mode = value - x.typ = Typ[Int] - - case _Delete: - // delete(m, k) - m, _ := x.typ.Underlying().(*Map) - if m == nil { - check.invalidArg(x.pos(), "%s is not a map", x) - return - } - arg(x, 1) // k - if x.mode == invalid { - return - } - - if !x.assignableTo(check.conf, m.key, nil) { - check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key) - return - } - - x.mode = novalue - if check.Types != nil { - check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key)) - } - - case _Imag, _Real: - // imag(complexT) floatT - // real(complexT) floatT - - // convert or check untyped argument - if isUntyped(x.typ) { - if x.mode == constant_ { - // an untyped constant number can alway be considered - // as a complex constant - if isNumeric(x.typ) { - x.typ = Typ[UntypedComplex] - } - } else { - // an untyped non-constant argument may appear if - // it contains a (yet untyped non-constant) shift - // expression: convert it to complex128 which will - // result in an error (shift of complex value) - check.convertUntyped(x, Typ[Complex128]) - // x should be invalid now, but be conservative and check - if x.mode == invalid { - return - } - } - } - - // the argument must be of complex type - if !isComplex(x.typ) { - check.invalidArg(x.pos(), "argument has type %s, expected complex type", x.typ) - return - } - - // if the argument is a constant, the result is a constant - if x.mode == constant_ { - if id == _Real { - x.val = constant.Real(x.val) - } else { - x.val = constant.Imag(x.val) - } - } else { - x.mode = value - } - - // determine result type - var res BasicKind - switch x.typ.Underlying().(*Basic).kind { - case Complex64: - res = Float32 - case Complex128: - res = Float64 - case UntypedComplex: - res = UntypedFloat - default: - unreachable() - } - resTyp := Typ[res] - - if check.Types != nil && x.mode != constant_ { - check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ)) - } - - x.typ = resTyp - - case _Make: - // make(T, n) - // make(T, n, m) - // (no argument evaluated yet) - arg0 := call.Args[0] - T := check.typ(arg0) - if T == Typ[Invalid] { - return - } - - var min int // minimum number of arguments - switch T.Underlying().(type) { - case *Slice: - min = 2 - case *Map, *Chan: - min = 1 - default: - check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0) - return - } - if nargs < min || min+1 < nargs { - check.errorf(call.Pos(), "%v expects %d or %d arguments; found %d", call, min, min+1, nargs) - return - } - var sizes []int64 // constant integer arguments, if any - for _, arg := range call.Args[1:] { - if s, ok := check.index(arg, -1); ok && s >= 0 { - sizes = append(sizes, s) - } - } - if len(sizes) == 2 && sizes[0] > sizes[1] { - check.invalidArg(call.Args[1].Pos(), "length and capacity swapped") - // safe to continue - } - x.mode = value - x.typ = T - if check.Types != nil { - params := [...]Type{T, Typ[Int], Typ[Int]} - check.recordBuiltinType(call.Fun, makeSig(x.typ, params[:1+len(sizes)]...)) - } - - case _New: - // new(T) - // (no argument evaluated yet) - T := check.typ(call.Args[0]) - if T == Typ[Invalid] { - return - } - - x.mode = value - x.typ = &Pointer{base: T} - if check.Types != nil { - check.recordBuiltinType(call.Fun, makeSig(x.typ, T)) - } - - case _Panic: - // panic(x) - check.assignment(x, &emptyInterface, "argument to panic") - if x.mode == invalid { - return - } - - x.mode = novalue - if check.Types != nil { - check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface)) - } - - case _Print, _Println: - // print(x, y, ...) - // println(x, y, ...) - var params []Type - if nargs > 0 { - params = make([]Type, nargs) - for i := 0; i < nargs; i++ { - if i > 0 { - arg(x, i) // first argument already evaluated - } - check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name) - if x.mode == invalid { - // TODO(gri) "use" all arguments? - return - } - params[i] = x.typ - } - } - - x.mode = novalue - if check.Types != nil { - check.recordBuiltinType(call.Fun, makeSig(nil, params...)) - } - - case _Recover: - // recover() interface{} - x.mode = value - x.typ = &emptyInterface - if check.Types != nil { - check.recordBuiltinType(call.Fun, makeSig(x.typ)) - } - - case _Alignof: - // unsafe.Alignof(x T) uintptr - check.assignment(x, nil, "argument to unsafe.Alignof") - if x.mode == invalid { - return - } - - x.mode = constant_ - x.val = constant.MakeInt64(check.conf.alignof(x.typ)) - x.typ = Typ[Uintptr] - // result is constant - no need to record signature - - case _Offsetof: - // unsafe.Offsetof(x T) uintptr, where x must be a selector - // (no argument evaluated yet) - arg0 := call.Args[0] - selx, _ := unparen(arg0).(*ast.SelectorExpr) - if selx == nil { - check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0) - check.use(arg0) - return - } - - check.expr(x, selx.X) - if x.mode == invalid { - return - } - - base := derefStructPtr(x.typ) - sel := selx.Sel.Name - obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel) - switch obj.(type) { - case nil: - check.invalidArg(x.pos(), "%s has no single field %s", base, sel) - return - case *Func: - // TODO(gri) Using derefStructPtr may result in methods being found - // that don't actually exist. An error either way, but the error - // message is confusing. See: https://play.golang.org/p/al75v23kUy , - // but go/types reports: "invalid argument: x.m is a method value". - check.invalidArg(arg0.Pos(), "%s is a method value", arg0) - return - } - if indirect { - check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base) - return - } - - // TODO(gri) Should we pass x.typ instead of base (and indirect report if derefStructPtr indirected)? - check.recordSelection(selx, FieldVal, base, obj, index, false) - - offs := check.conf.offsetof(base, index) - x.mode = constant_ - x.val = constant.MakeInt64(offs) - x.typ = Typ[Uintptr] - // result is constant - no need to record signature - - case _Sizeof: - // unsafe.Sizeof(x T) uintptr - check.assignment(x, nil, "argument to unsafe.Sizeof") - if x.mode == invalid { - return - } - - x.mode = constant_ - x.val = constant.MakeInt64(check.conf.sizeof(x.typ)) - x.typ = Typ[Uintptr] - // result is constant - no need to record signature - - case _Assert: - // assert(pred) causes a typechecker error if pred is false. - // The result of assert is the value of pred if there is no error. - // Note: assert is only available in self-test mode. - if x.mode != constant_ || !isBoolean(x.typ) { - check.invalidArg(x.pos(), "%s is not a boolean constant", x) - return - } - if x.val.Kind() != constant.Bool { - check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x) - return - } - if !constant.BoolVal(x.val) { - check.errorf(call.Pos(), "%v failed", call) - // compile-time assertion failure - safe to continue - } - // result is constant - no need to record signature - - case _Trace: - // trace(x, y, z, ...) dumps the positions, expressions, and - // values of its arguments. The result of trace is the value - // of the first argument. - // Note: trace is only available in self-test mode. - // (no argument evaluated yet) - if nargs == 0 { - check.dump("%s: trace() without arguments", call.Pos()) - x.mode = novalue - break - } - var t operand - x1 := x - for _, arg := range call.Args { - check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T)) - check.dump("%s: %s", x1.pos(), x1) - x1 = &t // use incoming x only for first argument - } - // trace is only available in test mode - no need to record signature - - default: - unreachable() - } - - return true -} - -// makeSig makes a signature for the given argument and result types. -// Default types are used for untyped arguments, and res may be nil. -func makeSig(res Type, args ...Type) *Signature { - list := make([]*Var, len(args)) - for i, param := range args { - list[i] = NewVar(token.NoPos, nil, "", Default(param)) - } - params := NewTuple(list...) - var result *Tuple - if res != nil { - assert(!isUntyped(res)) - result = NewTuple(NewVar(token.NoPos, nil, "", res)) - } - return &Signature{params: params, results: result} -} - -// implicitArrayDeref returns A if typ is of the form *A and A is an array; -// otherwise it returns typ. -// -func implicitArrayDeref(typ Type) Type { - if p, ok := typ.(*Pointer); ok { - if a, ok := p.base.Underlying().(*Array); ok { - return a - } - } - return typ -} - -// unparen returns e with any enclosing parentheses stripped. -func unparen(e ast.Expr) ast.Expr { - for { - p, ok := e.(*ast.ParenExpr) - if !ok { - return e - } - e = p.X - } -} diff --git a/third_party/forked/golang/go/types/call.go b/third_party/forked/golang/go/types/call.go deleted file mode 100644 index 8fe65e41d5f35..0000000000000 --- a/third_party/forked/golang/go/types/call.go +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements typechecking of call and selector expressions. - -package types - -import ( - "go/ast" - "go/token" -) - -func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { - check.exprOrType(x, e.Fun) - - switch x.mode { - case invalid: - check.use(e.Args...) - x.mode = invalid - x.expr = e - return statement - - case typexpr: - // conversion - T := x.typ - x.mode = invalid - switch n := len(e.Args); n { - case 0: - check.errorf(e.Rparen, "missing argument in conversion to %s", T) - case 1: - check.expr(x, e.Args[0]) - if x.mode != invalid { - check.conversion(x, T) - } - default: - check.errorf(e.Args[n-1].Pos(), "too many arguments in conversion to %s", T) - } - x.expr = e - return conversion - - case builtin: - id := x.id - if !check.builtin(x, e, id) { - x.mode = invalid - } - x.expr = e - // a non-constant result implies a function call - if x.mode != invalid && x.mode != constant_ { - check.hasCallOrRecv = true - } - return predeclaredFuncs[id].kind - - default: - // function/method call - sig, _ := x.typ.Underlying().(*Signature) - if sig == nil { - check.invalidOp(x.pos(), "cannot call non-function %s", x) - x.mode = invalid - x.expr = e - return statement - } - - arg, n, _ := unpack(func(x *operand, i int) { check.multiExpr(x, e.Args[i]) }, len(e.Args), false) - if arg != nil { - check.arguments(x, e, sig, arg, n) - } else { - x.mode = invalid - } - - // determine result - switch sig.results.Len() { - case 0: - x.mode = novalue - case 1: - x.mode = value - x.typ = sig.results.vars[0].typ // unpack tuple - default: - x.mode = value - x.typ = sig.results - } - - x.expr = e - check.hasCallOrRecv = true - - return statement - } -} - -// use type-checks each argument. -// Useful to make sure expressions are evaluated -// (and variables are "used") in the presence of other errors. -// The arguments may be nil. -func (check *Checker) use(arg ...ast.Expr) { - var x operand - for _, e := range arg { - // The nil check below is necessary since certain AST fields - // may legally be nil (e.g., the ast.SliceExpr.High field). - if e != nil { - check.rawExpr(&x, e, nil) - } - } -} - -// useLHS is like use, but doesn't "use" top-level identifiers. -// It should be called instead of use if the arguments are -// expressions on the lhs of an assignment. -// The arguments must not be nil. -func (check *Checker) useLHS(arg ...ast.Expr) { - var x operand - for _, e := range arg { - // If the lhs is an identifier denoting a variable v, this assignment - // is not a 'use' of v. Remember current value of v.used and restore - // after evaluating the lhs via check.rawExpr. - var v *Var - var v_used bool - if ident, _ := unparen(e).(*ast.Ident); ident != nil { - // never type-check the blank name on the lhs - if ident.Name == "_" { - continue - } - if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil { - // It's ok to mark non-local variables, but ignore variables - // from other packages to avoid potential race conditions with - // dot-imported variables. - if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg { - v = w - v_used = v.used - } - } - } - check.rawExpr(&x, e, nil) - if v != nil { - v.used = v_used // restore v.used - } - } -} - -// useGetter is like use, but takes a getter instead of a list of expressions. -// It should be called instead of use if a getter is present to avoid repeated -// evaluation of the first argument (since the getter was likely obtained via -// unpack, which may have evaluated the first argument already). -func (check *Checker) useGetter(get getter, n int) { - var x operand - for i := 0; i < n; i++ { - get(&x, i) - } -} - -// A getter sets x as the i'th operand, where 0 <= i < n and n is the total -// number of operands (context-specific, and maintained elsewhere). A getter -// type-checks the i'th operand; the details of the actual check are getter- -// specific. -type getter func(x *operand, i int) - -// unpack takes a getter get and a number of operands n. If n == 1, unpack -// calls the incoming getter for the first operand. If that operand is -// invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a -// function call, or a comma-ok expression and allowCommaOk is set, the result -// is a new getter and operand count providing access to the function results, -// or comma-ok values, respectively. The third result value reports if it -// is indeed the comma-ok case. In all other cases, the incoming getter and -// operand count are returned unchanged, and the third result value is false. -// -// In other words, if there's exactly one operand that - after type-checking -// by calling get - stands for multiple operands, the resulting getter provides -// access to those operands instead. -// -// If the returned getter is called at most once for a given operand index i -// (including i == 0), that operand is guaranteed to cause only one call of -// the incoming getter with that i. -// -func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) { - if n != 1 { - // zero or multiple values - return get, n, false - } - // possibly result of an n-valued function call or comma,ok value - var x0 operand - get(&x0, 0) - if x0.mode == invalid { - return nil, 0, false - } - - if t, ok := x0.typ.(*Tuple); ok { - // result of an n-valued function call - return func(x *operand, i int) { - x.mode = value - x.expr = x0.expr - x.typ = t.At(i).typ - }, t.Len(), false - } - - if x0.mode == mapindex || x0.mode == commaok { - // comma-ok value - if allowCommaOk { - a := [2]Type{x0.typ, Typ[UntypedBool]} - return func(x *operand, i int) { - x.mode = value - x.expr = x0.expr - x.typ = a[i] - }, 2, true - } - x0.mode = value - } - - // single value - return func(x *operand, i int) { - if i != 0 { - unreachable() - } - *x = x0 - }, 1, false -} - -// arguments checks argument passing for the call with the given signature. -// The arg function provides the operand for the i'th argument. -func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) { - if call.Ellipsis.IsValid() { - // last argument is of the form x... - if !sig.variadic { - check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun) - check.useGetter(arg, n) - return - } - if len(call.Args) == 1 && n > 1 { - // f()... is not permitted if f() is multi-valued - check.errorf(call.Ellipsis, "cannot use ... with %d-valued %s", n, call.Args[0]) - check.useGetter(arg, n) - return - } - } - - // evaluate arguments - for i := 0; i < n; i++ { - arg(x, i) - if x.mode != invalid { - var ellipsis token.Pos - if i == n-1 && call.Ellipsis.IsValid() { - ellipsis = call.Ellipsis - } - check.argument(call.Fun, sig, i, x, ellipsis) - } - } - - // check argument count - if sig.variadic { - // a variadic function accepts an "empty" - // last argument: count one extra - n++ - } - if n < sig.params.Len() { - check.errorf(call.Rparen, "too few arguments in call to %s", call.Fun) - // ok to continue - } -} - -// argument checks passing of argument x to the i'th parameter of the given signature. -// If ellipsis is valid, the argument is followed by ... at that position in the call. -func (check *Checker) argument(fun ast.Expr, sig *Signature, i int, x *operand, ellipsis token.Pos) { - check.singleValue(x) - if x.mode == invalid { - return - } - - n := sig.params.Len() - - // determine parameter type - var typ Type - switch { - case i < n: - typ = sig.params.vars[i].typ - case sig.variadic: - typ = sig.params.vars[n-1].typ - if debug { - if _, ok := typ.(*Slice); !ok { - check.dump("%s: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ) - } - } - default: - check.errorf(x.pos(), "too many arguments") - return - } - - if ellipsis.IsValid() { - // argument is of the form x... and x is single-valued - if i != n-1 { - check.errorf(ellipsis, "can only use ... with matching parameter") - return - } - if _, ok := x.typ.Underlying().(*Slice); !ok && x.typ != Typ[UntypedNil] { // see issue #18268 - check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ) - return - } - } else if sig.variadic && i >= n-1 { - // use the variadic parameter slice's element type - typ = typ.(*Slice).elem - } - - check.assignment(x, typ, check.sprintf("argument to %s", fun)) -} - -func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { - // these must be declared before the "goto Error" statements - var ( - obj Object - index []int - indirect bool - ) - - sel := e.Sel.Name - // If the identifier refers to a package, handle everything here - // so we don't need a "package" mode for operands: package names - // can only appear in qualified identifiers which are mapped to - // selector expressions. - if ident, ok := e.X.(*ast.Ident); ok { - _, obj := check.scope.LookupParent(ident.Name, check.pos) - if pname, _ := obj.(*PkgName); pname != nil { - assert(pname.pkg == check.pkg) - check.recordUse(ident, pname) - pname.used = true - pkg := pname.imported - exp := pkg.scope.Lookup(sel) - if exp == nil { - if !pkg.fake { - check.errorf(e.Pos(), "%s not declared by package %s", sel, pkg.name) - } - goto Error - } - if !exp.Exported() { - check.errorf(e.Pos(), "%s not exported by package %s", sel, pkg.name) - // ok to continue - } - check.recordUse(e.Sel, exp) - - // Simplified version of the code for *ast.Idents: - // - imported objects are always fully initialized - switch exp := exp.(type) { - case *Const: - assert(exp.Val() != nil) - x.mode = constant_ - x.typ = exp.typ - x.val = exp.val - case *TypeName: - x.mode = typexpr - x.typ = exp.typ - case *Var: - x.mode = variable - x.typ = exp.typ - case *Func: - x.mode = value - x.typ = exp.typ - case *Builtin: - x.mode = builtin - x.typ = exp.typ - x.id = exp.id - default: - check.dump("unexpected object %v", exp) - unreachable() - } - x.expr = e - return - } - } - - check.exprOrType(x, e.X) - if x.mode == invalid { - goto Error - } - - obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel) - if obj == nil { - switch { - case index != nil: - // TODO(gri) should provide actual type where the conflict happens - check.invalidOp(e.Pos(), "ambiguous selector %s", sel) - case indirect: - check.invalidOp(e.Pos(), "%s is not in method set of %s", sel, x.typ) - default: - check.invalidOp(e.Pos(), "%s has no field or method %s", x, sel) - } - goto Error - } - - if x.mode == typexpr { - // method expression - m, _ := obj.(*Func) - if m == nil { - check.invalidOp(e.Pos(), "%s has no method %s", x, sel) - goto Error - } - - check.recordSelection(e, MethodExpr, x.typ, m, index, indirect) - - // the receiver type becomes the type of the first function - // argument of the method expression's function type - var params []*Var - sig := m.typ.(*Signature) - if sig.params != nil { - params = sig.params.vars - } - x.mode = value - x.typ = &Signature{ - params: NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...), - results: sig.results, - variadic: sig.variadic, - } - - check.addDeclDep(m) - - } else { - // regular selector - switch obj := obj.(type) { - case *Var: - check.recordSelection(e, FieldVal, x.typ, obj, index, indirect) - if x.mode == variable || indirect { - x.mode = variable - } else { - x.mode = value - } - x.typ = obj.typ - - case *Func: - // TODO(gri) If we needed to take into account the receiver's - // addressability, should we report the type &(x.typ) instead? - check.recordSelection(e, MethodVal, x.typ, obj, index, indirect) - - if debug { - // Verify that LookupFieldOrMethod and MethodSet.Lookup agree. - typ := x.typ - if x.mode == variable { - // If typ is not an (unnamed) pointer or an interface, - // use *typ instead, because the method set of *typ - // includes the methods of typ. - // Variables are addressable, so we can always take their - // address. - if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) { - typ = &Pointer{base: typ} - } - } - // If we created a synthetic pointer type above, we will throw - // away the method set computed here after use. - // TODO(gri) Method set computation should probably always compute - // both, the value and the pointer receiver method set and represent - // them in a single structure. - // TODO(gri) Consider also using a method set cache for the lifetime - // of checker once we rely on MethodSet lookup instead of individual - // lookup. - mset := NewMethodSet(typ) - if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj { - check.dump("%s: (%s).%v -> %s", e.Pos(), typ, obj.name, m) - check.dump("%s\n", mset) - panic("method sets and lookup don't agree") - } - } - - x.mode = value - - // remove receiver - sig := *obj.typ.(*Signature) - sig.recv = nil - x.typ = &sig - - check.addDeclDep(obj) - - default: - unreachable() - } - } - - // everything went well - x.expr = e - return - -Error: - x.mode = invalid - x.expr = e -} diff --git a/third_party/forked/golang/go/types/check.go b/third_party/forked/golang/go/types/check.go deleted file mode 100644 index 26db5769b98d3..0000000000000 --- a/third_party/forked/golang/go/types/check.go +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements the Check function, which drives type-checking. - -package types - -import ( - "go/ast" - "go/constant" - "go/token" -) - -// debugging/development support -const ( - debug = false // leave on during development - trace = false // turn on for detailed type resolution traces -) - -// If Strict is set, the type-checker enforces additional -// rules not specified by the Go 1 spec, but which will -// catch guaranteed run-time errors if the respective -// code is executed. In other words, programs passing in -// Strict mode are Go 1 compliant, but not all Go 1 programs -// will pass in Strict mode. The additional rules are: -// -// - A type assertion x.(T) where T is an interface type -// is invalid if any (statically known) method that exists -// for both x and T have different signatures. -// -const strict = false - -// exprInfo stores information about an untyped expression. -type exprInfo struct { - isLhs bool // expression is lhs operand of a shift with delayed type-check - mode operandMode - typ *Basic - val constant.Value // constant value; or nil (if not a constant) -} - -// funcInfo stores the information required for type-checking a function. -type funcInfo struct { - name string // for debugging/tracing only - decl *declInfo // for cycle detection - sig *Signature - body *ast.BlockStmt -} - -// A context represents the context within which an object is type-checked. -type context struct { - decl *declInfo // package-level declaration whose init expression/function body is checked - scope *Scope // top-most scope for lookups - iota constant.Value // value of iota in a constant declaration; nil otherwise - sig *Signature // function signature if inside a function; nil otherwise - hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions - hasCallOrRecv bool // set if an expression contains a function call or channel receive operation -} - -// An importKey identifies an imported package by import path and source directory -// (directory containing the file containing the import). In practice, the directory -// may always be the same, or may not matter. Given an (import path, directory), an -// importer must always return the same package (but given two different import paths, -// an importer may still return the same package by mapping them to the same package -// paths). -type importKey struct { - path, dir string -} - -// A Checker maintains the state of the type checker. -// It must be created with NewChecker. -type Checker struct { - // package information - // (initialized by NewChecker, valid for the life-time of checker) - conf *Config - fset *token.FileSet - pkg *Package - *Info - objMap map[Object]*declInfo // maps package-level object to declaration info - impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package - - // information collected during type-checking of a set of package files - // (initialized by Files, valid only for the duration of check.Files; - // maps and lists are allocated on demand) - files []*ast.File // package files - unusedDotImports map[*Scope]map[*Package]token.Pos // positions of unused dot-imported packages for each file scope - - firstErr error // first error encountered - methods map[string][]*Func // maps type names to associated methods - untyped map[ast.Expr]exprInfo // map of expressions without final type - funcs []funcInfo // list of functions to type-check - delayed []func() // delayed checks requiring fully setup types - - // context within which the current object is type-checked - // (valid only for the duration of type-checking a specific object) - context - pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval) - - // debugging - indent int // indentation for tracing -} - -// addUnusedImport adds the position of a dot-imported package -// pkg to the map of dot imports for the given file scope. -func (check *Checker) addUnusedDotImport(scope *Scope, pkg *Package, pos token.Pos) { - mm := check.unusedDotImports - if mm == nil { - mm = make(map[*Scope]map[*Package]token.Pos) - check.unusedDotImports = mm - } - m := mm[scope] - if m == nil { - m = make(map[*Package]token.Pos) - mm[scope] = m - } - m[pkg] = pos -} - -// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists -func (check *Checker) addDeclDep(to Object) { - from := check.decl - if from == nil { - return // not in a package-level init expression - } - if _, found := check.objMap[to]; !found { - return // to is not a package-level object - } - from.addDep(to) -} - -func (check *Checker) assocMethod(tname string, meth *Func) { - m := check.methods - if m == nil { - m = make(map[string][]*Func) - check.methods = m - } - m[tname] = append(m[tname], meth) -} - -func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) { - m := check.untyped - if m == nil { - m = make(map[ast.Expr]exprInfo) - check.untyped = m - } - m[e] = exprInfo{lhs, mode, typ, val} -} - -func (check *Checker) later(name string, decl *declInfo, sig *Signature, body *ast.BlockStmt) { - check.funcs = append(check.funcs, funcInfo{name, decl, sig, body}) -} - -func (check *Checker) delay(f func()) { - check.delayed = append(check.delayed, f) -} - -// NewChecker returns a new Checker instance for a given package. -// Package files may be added incrementally via checker.Files. -func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Checker { - // make sure we have a configuration - if conf == nil { - conf = new(Config) - } - - // make sure we have an info struct - if info == nil { - info = new(Info) - } - - return &Checker{ - conf: conf, - fset: fset, - pkg: pkg, - Info: info, - objMap: make(map[Object]*declInfo), - impMap: make(map[importKey]*Package), - } -} - -// initFiles initializes the files-specific portion of checker. -// The provided files must all belong to the same package. -func (check *Checker) initFiles(files []*ast.File) { - // start with a clean slate (check.Files may be called multiple times) - check.files = nil - check.unusedDotImports = nil - - check.firstErr = nil - check.methods = nil - check.untyped = nil - check.funcs = nil - check.delayed = nil - - // determine package name and collect valid files - pkg := check.pkg - for _, file := range files { - switch name := file.Name.Name; pkg.name { - case "": - if name != "_" { - pkg.name = name - } else { - check.errorf(file.Name.Pos(), "invalid package name _") - } - fallthrough - - case name: - check.files = append(check.files, file) - - default: - check.errorf(file.Package, "package %s; expected %s", name, pkg.name) - // ignore this file - } - } -} - -// A bailout panic is used for early termination. -type bailout struct{} - -func (check *Checker) handleBailout(err *error) { - switch p := recover().(type) { - case nil, bailout: - // normal return or early exit - *err = check.firstErr - default: - // re-panic - panic(p) - } -} - -// Files checks the provided files as part of the checker's package. -func (check *Checker) Files(files []*ast.File) error { return check.checkFiles(files) } - -func (check *Checker) checkFiles(files []*ast.File) (err error) { - defer check.handleBailout(&err) - - check.initFiles(files) - - check.collectObjects() - - check.packageObjects(check.resolveOrder()) - - check.functionBodies() - - check.initOrder() - - if !check.conf.DisableUnusedImportCheck { - check.unusedImports() - } - - // perform delayed checks - for _, f := range check.delayed { - f() - } - - check.recordUntyped() - - check.pkg.complete = true - return -} - -func (check *Checker) recordUntyped() { - if !debug && check.Types == nil { - return // nothing to do - } - - for x, info := range check.untyped { - if debug && isTyped(info.typ) { - check.dump("%s: %s (type %s) is typed", x.Pos(), x, info.typ) - unreachable() - } - check.recordTypeAndValue(x, info.mode, info.typ, info.val) - } -} - -func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val constant.Value) { - assert(x != nil) - assert(typ != nil) - if mode == invalid { - return // omit - } - assert(typ != nil) - if mode == constant_ { - assert(val != nil) - assert(typ == Typ[Invalid] || isConstType(typ)) - } - if m := check.Types; m != nil { - m[x] = TypeAndValue{mode, typ, val} - } -} - -func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) { - // f must be a (possibly parenthesized) identifier denoting a built-in - // (built-ins in package unsafe always produce a constant result and - // we don't record their signatures, so we don't see qualified idents - // here): record the signature for f and possible children. - for { - check.recordTypeAndValue(f, builtin, sig, nil) - switch p := f.(type) { - case *ast.Ident: - return // we're done - case *ast.ParenExpr: - f = p.X - default: - unreachable() - } - } -} - -func (check *Checker) recordCommaOkTypes(x ast.Expr, a [2]Type) { - assert(x != nil) - if a[0] == nil || a[1] == nil { - return - } - assert(isTyped(a[0]) && isTyped(a[1]) && isBoolean(a[1])) - if m := check.Types; m != nil { - for { - tv := m[x] - assert(tv.Type != nil) // should have been recorded already - pos := x.Pos() - tv.Type = NewTuple( - NewVar(pos, check.pkg, "", a[0]), - NewVar(pos, check.pkg, "", a[1]), - ) - m[x] = tv - // if x is a parenthesized expression (p.X), update p.X - p, _ := x.(*ast.ParenExpr) - if p == nil { - break - } - x = p.X - } - } -} - -func (check *Checker) recordDef(id *ast.Ident, obj Object) { - assert(id != nil) - if m := check.Defs; m != nil { - m[id] = obj - } -} - -func (check *Checker) recordUse(id *ast.Ident, obj Object) { - assert(id != nil) - assert(obj != nil) - if m := check.Uses; m != nil { - m[id] = obj - } -} - -func (check *Checker) recordImplicit(node ast.Node, obj Object) { - assert(node != nil) - assert(obj != nil) - if m := check.Implicits; m != nil { - m[node] = obj - } -} - -func (check *Checker) recordSelection(x *ast.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) { - assert(obj != nil && (recv == nil || len(index) > 0)) - check.recordUse(x.Sel, obj) - if m := check.Selections; m != nil { - m[x] = &Selection{kind, recv, obj, index, indirect} - } -} - -func (check *Checker) recordScope(node ast.Node, scope *Scope) { - assert(node != nil) - assert(scope != nil) - if m := check.Scopes; m != nil { - m[node] = scope - } -} diff --git a/third_party/forked/golang/go/types/conversions.go b/third_party/forked/golang/go/types/conversions.go deleted file mode 100644 index 81a65838fe091..0000000000000 --- a/third_party/forked/golang/go/types/conversions.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements typechecking of conversions. - -package types - -import "go/constant" - -// Conversion type-checks the conversion T(x). -// The result is in x. -func (check *Checker) conversion(x *operand, T Type) { - constArg := x.mode == constant_ - - var ok bool - switch { - case constArg && isConstType(T): - // constant conversion - switch t := T.Underlying().(*Basic); { - case representableConst(x.val, check.conf, t, &x.val): - ok = true - case isInteger(x.typ) && isString(t): - codepoint := int64(-1) - if i, ok := constant.Int64Val(x.val); ok { - codepoint = i - } - // If codepoint < 0 the absolute value is too large (or unknown) for - // conversion. This is the same as converting any other out-of-range - // value - let string(codepoint) do the work. - x.val = constant.MakeString(string(codepoint)) - ok = true - } - case x.convertibleTo(check.conf, T): - // non-constant conversion - x.mode = value - ok = true - } - - if !ok { - check.errorf(x.pos(), "cannot convert %s to %s", x, T) - x.mode = invalid - return - } - - // The conversion argument types are final. For untyped values the - // conversion provides the type, per the spec: "A constant may be - // given a type explicitly by a constant declaration or conversion,...". - if isUntyped(x.typ) { - final := T - // - For conversions to interfaces, use the argument's default type. - // - For conversions of untyped constants to non-constant types, also - // use the default type (e.g., []byte("foo") should report string - // not []byte as type for the constant "foo"). - // - Keep untyped nil for untyped nil arguments. - // - For integer to string conversions, keep the argument type. - // (See also the TODO below.) - if IsInterface(T) || constArg && !isConstType(T) { - final = Default(x.typ) - } else if isInteger(x.typ) && isString(T) { - final = x.typ - } - check.updateExprType(x.expr, final, true) - } - - x.typ = T -} - -// TODO(gri) convertibleTo checks if T(x) is valid. It assumes that the type -// of x is fully known, but that's not the case for say string(1< %s", obj) - }() - } - - d := check.objMap[obj] - if d == nil { - check.dump("%s: %s should have been declared", obj.Pos(), obj.Name()) - unreachable() - } - - // save/restore current context and setup object context - defer func(ctxt context) { - check.context = ctxt - }(check.context) - check.context = context{ - scope: d.file, - } - - // Const and var declarations must not have initialization - // cycles. We track them by remembering the current declaration - // in check.decl. Initialization expressions depending on other - // consts, vars, or functions, add dependencies to the current - // check.decl. - switch obj := obj.(type) { - case *Const: - check.decl = d // new package-level const decl - check.constDecl(obj, d.typ, d.init) - case *Var: - check.decl = d // new package-level var decl - check.varDecl(obj, d.lhs, d.typ, d.init) - case *TypeName: - // invalid recursive types are detected via path - check.typeDecl(obj, d.typ, def, path, d.alias) - case *Func: - // functions may be recursive - no need to track dependencies - check.funcDecl(obj, d) - default: - unreachable() - } -} - -func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { - assert(obj.typ == nil) - - if obj.visited { - obj.typ = Typ[Invalid] - return - } - obj.visited = true - - // use the correct value of iota - assert(check.iota == nil) - check.iota = obj.val - defer func() { check.iota = nil }() - - // provide valid constant value under all circumstances - obj.val = constant.MakeUnknown() - - // determine type, if any - if typ != nil { - t := check.typ(typ) - if !isConstType(t) { - // don't report an error if the type is an invalid C (defined) type - // (issue #22090) - if t.Underlying() != Typ[Invalid] { - check.errorf(typ.Pos(), "invalid constant type %s", t) - } - obj.typ = Typ[Invalid] - return - } - obj.typ = t - } - - // check initialization - var x operand - if init != nil { - check.expr(&x, init) - } - check.initConst(obj, &x) -} - -func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { - assert(obj.typ == nil) - - if obj.visited { - obj.typ = Typ[Invalid] - return - } - obj.visited = true - - // var declarations cannot use iota - assert(check.iota == nil) - - // determine type, if any - if typ != nil { - obj.typ = check.typ(typ) - // We cannot spread the type to all lhs variables if there - // are more than one since that would mark them as checked - // (see Checker.objDecl) and the assignment of init exprs, - // if any, would not be checked. - // - // TODO(gri) If we have no init expr, we should distribute - // a given type otherwise we need to re-evalate the type - // expr for each lhs variable, leading to duplicate work. - } - - // check initialization - if init == nil { - if typ == nil { - // error reported before by arityMatch - obj.typ = Typ[Invalid] - } - return - } - - if lhs == nil || len(lhs) == 1 { - assert(lhs == nil || lhs[0] == obj) - var x operand - check.expr(&x, init) - check.initVar(obj, &x, "variable declaration") - return - } - - if debug { - // obj must be one of lhs - found := false - for _, lhs := range lhs { - if obj == lhs { - found = true - break - } - } - if !found { - panic("inconsistent lhs") - } - } - - // We have multiple variables on the lhs and one init expr. - // Make sure all variables have been given the same type if - // one was specified, otherwise they assume the type of the - // init expression values (was issue #15755). - if typ != nil { - for _, lhs := range lhs { - lhs.typ = obj.typ - } - } - - check.initVars(lhs, []ast.Expr{init}, token.NoPos) -} - -// underlying returns the underlying type of typ; possibly by following -// forward chains of named types. Such chains only exist while named types -// are incomplete. -func underlying(typ Type) Type { - for { - n, _ := typ.(*Named) - if n == nil { - break - } - typ = n.underlying - } - return typ -} - -func (n *Named) setUnderlying(typ Type) { - if n != nil { - n.underlying = typ - } -} - -func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*TypeName, alias bool) { - assert(obj.typ == nil) - - // type declarations cannot use iota - assert(check.iota == nil) - - if alias { - - obj.typ = Typ[Invalid] - obj.typ = check.typExpr(typ, nil, append(path, obj)) - - } else { - - named := &Named{obj: obj} - def.setUnderlying(named) - obj.typ = named // make sure recursive type declarations terminate - - // determine underlying type of named - check.typExpr(typ, named, append(path, obj)) - - // The underlying type of named may be itself a named type that is - // incomplete: - // - // type ( - // A B - // B *C - // C A - // ) - // - // The type of C is the (named) type of A which is incomplete, - // and which has as its underlying type the named type B. - // Determine the (final, unnamed) underlying type by resolving - // any forward chain (they always end in an unnamed type). - named.underlying = underlying(named.underlying) - - } - - // check and add associated methods - // TODO(gri) It's easy to create pathological cases where the - // current approach is incorrect: In general we need to know - // and add all methods _before_ type-checking the type. - // See https://play.golang.org/p/WMpE0q2wK8 - check.addMethodDecls(obj) -} - -func (check *Checker) addMethodDecls(obj *TypeName) { - // get associated methods - methods := check.methods[obj.name] - if len(methods) == 0 { - return // no methods - } - delete(check.methods, obj.name) - - // use an objset to check for name conflicts - var mset objset - - // spec: "If the base type is a struct type, the non-blank method - // and field names must be distinct." - base, _ := obj.typ.(*Named) // nil if receiver base type is type alias - if base != nil { - if t, _ := base.underlying.(*Struct); t != nil { - for _, fld := range t.fields { - if fld.name != "_" { - assert(mset.insert(fld) == nil) - } - } - } - - // Checker.Files may be called multiple times; additional package files - // may add methods to already type-checked types. Add pre-existing methods - // so that we can detect redeclarations. - for _, m := range base.methods { - assert(m.name != "_") - assert(mset.insert(m) == nil) - } - } - - // type-check methods - for _, m := range methods { - // spec: "For a base type, the non-blank names of methods bound - // to it must be unique." - if m.name != "_" { - if alt := mset.insert(m); alt != nil { - switch alt.(type) { - case *Var: - check.errorf(m.pos, "field and method with the same name %s", m.name) - case *Func: - check.errorf(m.pos, "method %s already declared for %s", m.name, obj) - default: - unreachable() - } - check.reportAltDecl(alt) - continue - } - } - - // type-check - check.objDecl(m, nil, nil) - - // methods with blank _ names cannot be found - don't keep them - if base != nil && m.name != "_" { - base.methods = append(base.methods, m) - } - } -} - -func (check *Checker) funcDecl(obj *Func, decl *declInfo) { - assert(obj.typ == nil) - - // func declarations cannot use iota - assert(check.iota == nil) - - sig := new(Signature) - obj.typ = sig // guard against cycles - fdecl := decl.fdecl - check.funcType(sig, fdecl.Recv, fdecl.Type) - if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) { - check.errorf(fdecl.Pos(), "func init must have no arguments and no return values") - // ok to continue - } - - // function body must be type-checked after global declarations - // (functions implemented elsewhere have no body) - if !check.conf.IgnoreFuncBodies && fdecl.Body != nil { - check.later(obj.name, decl, sig, fdecl.Body) - } -} - -func (check *Checker) declStmt(decl ast.Decl) { - pkg := check.pkg - - switch d := decl.(type) { - case *ast.BadDecl: - // ignore - - case *ast.GenDecl: - var last *ast.ValueSpec // last ValueSpec with type or init exprs seen - for iota, spec := range d.Specs { - switch s := spec.(type) { - case *ast.ValueSpec: - switch d.Tok { - case token.CONST: - // determine which init exprs to use - switch { - case s.Type != nil || len(s.Values) > 0: - last = s - case last == nil: - last = new(ast.ValueSpec) // make sure last exists - } - - // declare all constants - lhs := make([]*Const, len(s.Names)) - for i, name := range s.Names { - obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) - lhs[i] = obj - - var init ast.Expr - if i < len(last.Values) { - init = last.Values[i] - } - - check.constDecl(obj, last.Type, init) - } - - check.arityMatch(s, last) - - // spec: "The scope of a constant or variable identifier declared - // inside a function begins at the end of the ConstSpec or VarSpec - // (ShortVarDecl for short variable declarations) and ends at the - // end of the innermost containing block." - scopePos := s.End() - for i, name := range s.Names { - check.declare(check.scope, name, lhs[i], scopePos) - } - - case token.VAR: - lhs0 := make([]*Var, len(s.Names)) - for i, name := range s.Names { - lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) - } - - // initialize all variables - for i, obj := range lhs0 { - var lhs []*Var - var init ast.Expr - switch len(s.Values) { - case len(s.Names): - // lhs and rhs match - init = s.Values[i] - case 1: - // rhs is expected to be a multi-valued expression - lhs = lhs0 - init = s.Values[0] - default: - if i < len(s.Values) { - init = s.Values[i] - } - } - check.varDecl(obj, lhs, s.Type, init) - if len(s.Values) == 1 { - // If we have a single lhs variable we are done either way. - // If we have a single rhs expression, it must be a multi- - // valued expression, in which case handling the first lhs - // variable will cause all lhs variables to have a type - // assigned, and we are done as well. - if debug { - for _, obj := range lhs0 { - assert(obj.typ != nil) - } - } - break - } - } - - check.arityMatch(s, nil) - - // declare all variables - // (only at this point are the variable scopes (parents) set) - scopePos := s.End() // see constant declarations - for i, name := range s.Names { - // see constant declarations - check.declare(check.scope, name, lhs0[i], scopePos) - } - - default: - check.invalidAST(s.Pos(), "invalid token %s", d.Tok) - } - - case *ast.TypeSpec: - obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) - // spec: "The scope of a type identifier declared inside a function - // begins at the identifier in the TypeSpec and ends at the end of - // the innermost containing block." - scopePos := s.Name.Pos() - check.declare(check.scope, s.Name, obj, scopePos) - check.typeDecl(obj, s.Type, nil, nil, s.Assign.IsValid()) - - default: - check.invalidAST(s.Pos(), "const, type, or var declaration expected") - } - } - - default: - check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) - } -} diff --git a/third_party/forked/golang/go/types/errors.go b/third_party/forked/golang/go/types/errors.go deleted file mode 100644 index 0c0049b1f3e21..0000000000000 --- a/third_party/forked/golang/go/types/errors.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements various error reporters. - -package types - -import ( - "fmt" - "go/ast" - "go/token" - "strings" -) - -func assert(p bool) { - if !p { - panic("assertion failed") - } -} - -func unreachable() { - panic("unreachable") -} - -func (check *Checker) qualifier(pkg *Package) string { - if pkg != check.pkg { - return pkg.path - } - return "" -} - -func (check *Checker) sprintf(format string, args ...interface{}) string { - for i, arg := range args { - switch a := arg.(type) { - case nil: - arg = "" - case operand: - panic("internal error: should always pass *operand") - case *operand: - arg = operandString(a, check.qualifier) - case token.Pos: - arg = check.fset.Position(a).String() - case ast.Expr: - arg = ExprString(a) - case Object: - arg = ObjectString(a, check.qualifier) - case Type: - arg = TypeString(a, check.qualifier) - } - args[i] = arg - } - return fmt.Sprintf(format, args...) -} - -func (check *Checker) trace(pos token.Pos, format string, args ...interface{}) { - fmt.Printf("%s:\t%s%s\n", - check.fset.Position(pos), - strings.Repeat(". ", check.indent), - check.sprintf(format, args...), - ) -} - -// dump is only needed for debugging -func (check *Checker) dump(format string, args ...interface{}) { - fmt.Println(check.sprintf(format, args...)) -} - -func (check *Checker) err(pos token.Pos, msg string, soft bool) { - err := Error{check.fset, pos, msg, soft} - if check.firstErr == nil { - check.firstErr = err - } - f := check.conf.Error - if f == nil { - panic(bailout{}) // report only first error - } - f(err) -} - -func (check *Checker) error(pos token.Pos, msg string) { - check.err(pos, msg, false) -} - -func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) { - check.err(pos, check.sprintf(format, args...), false) -} - -func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) { - check.err(pos, check.sprintf(format, args...), true) -} - -func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) { - check.errorf(pos, "invalid AST: "+format, args...) -} - -func (check *Checker) invalidArg(pos token.Pos, format string, args ...interface{}) { - check.errorf(pos, "invalid argument: "+format, args...) -} - -func (check *Checker) invalidOp(pos token.Pos, format string, args ...interface{}) { - check.errorf(pos, "invalid operation: "+format, args...) -} diff --git a/third_party/forked/golang/go/types/eval.go b/third_party/forked/golang/go/types/eval.go deleted file mode 100644 index 831d771d8075c..0000000000000 --- a/third_party/forked/golang/go/types/eval.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -import ( - "fmt" - "go/parser" - "go/token" -) - -// Eval returns the type and, if constant, the value for the -// expression expr, evaluated at position pos of package pkg, -// which must have been derived from type-checking an AST with -// complete position information relative to the provided file -// set. -// -// If the expression contains function literals, their bodies -// are ignored (i.e., the bodies are not type-checked). -// -// If pkg == nil, the Universe scope is used and the provided -// position pos is ignored. If pkg != nil, and pos is invalid, -// the package scope is used. Otherwise, pos must belong to the -// package. -// -// An error is returned if pos is not within the package or -// if the node cannot be evaluated. -// -// Note: Eval should not be used instead of running Check to compute -// types and values, but in addition to Check. Eval will re-evaluate -// its argument each time, and it also does not know about the context -// in which an expression is used (e.g., an assignment). Thus, top- -// level untyped constants will return an untyped type rather then the -// respective context-specific type. -// -func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (TypeAndValue, error) { - // determine scope - var scope *Scope - if pkg == nil { - scope = Universe - pos = token.NoPos - } else if !pos.IsValid() { - scope = pkg.scope - } else { - // The package scope extent (position information) may be - // incorrect (files spread across a wide range of fset - // positions) - ignore it and just consider its children - // (file scopes). - for _, fscope := range pkg.scope.children { - if scope = fscope.Innermost(pos); scope != nil { - break - } - } - if scope == nil || debug { - s := scope - for s != nil && s != pkg.scope { - s = s.parent - } - // s == nil || s == pkg.scope - if s == nil { - return TypeAndValue{}, fmt.Errorf("no position %s found in package %s", fset.Position(pos), pkg.name) - } - } - } - - // parse expressions - node, err := parser.ParseExprFrom(fset, "eval", expr, 0) - if err != nil { - return TypeAndValue{}, err - } - - // initialize checker - check := NewChecker(nil, fset, pkg, nil) - check.scope = scope - check.pos = pos - defer check.handleBailout(&err) - - // evaluate node - var x operand - check.rawExpr(&x, node, nil) - return TypeAndValue{x.mode, x.typ, x.val}, err -} diff --git a/third_party/forked/golang/go/types/expr.go b/third_party/forked/golang/go/types/expr.go deleted file mode 100644 index 59534c75708b9..0000000000000 --- a/third_party/forked/golang/go/types/expr.go +++ /dev/null @@ -1,1623 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements typechecking of expressions. - -package types - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "math" -) - -/* -Basic algorithm: - -Expressions are checked recursively, top down. Expression checker functions -are generally of the form: - - func f(x *operand, e *ast.Expr, ...) - -where e is the expression to be checked, and x is the result of the check. -The check performed by f may fail in which case x.mode == invalid, and -related error messages will have been issued by f. - -If a hint argument is present, it is the composite literal element type -of an outer composite literal; it is used to type-check composite literal -elements that have no explicit type specification in the source -(e.g.: []T{{...}, {...}}, the hint is the type T in this case). - -All expressions are checked via rawExpr, which dispatches according -to expression kind. Upon returning, rawExpr is recording the types and -constant values for all expressions that have an untyped type (those types -may change on the way up in the expression tree). Usually these are constants, -but the results of comparisons or non-constant shifts of untyped constants -may also be untyped, but not constant. - -Untyped expressions may eventually become fully typed (i.e., not untyped), -typically when the value is assigned to a variable, or is used otherwise. -The updateExprType method is used to record this final type and update -the recorded types: the type-checked expression tree is again traversed down, -and the new type is propagated as needed. Untyped constant expression values -that become fully typed must now be representable by the full type (constant -sub-expression trees are left alone except for their roots). This mechanism -ensures that a client sees the actual (run-time) type an untyped value would -have. It also permits type-checking of lhs shift operands "as if the shift -were not present": when updateExprType visits an untyped lhs shift operand -and assigns it it's final type, that type must be an integer type, and a -constant lhs must be representable as an integer. - -When an expression gets its final type, either on the way out from rawExpr, -on the way down in updateExprType, or at the end of the type checker run, -the type (and constant value, if any) is recorded via Info.Types, if present. -*/ - -type opPredicates map[token.Token]func(Type) bool - -var unaryOpPredicates = opPredicates{ - token.ADD: isNumeric, - token.SUB: isNumeric, - token.XOR: isInteger, - token.NOT: isBoolean, -} - -func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool { - if pred := m[op]; pred != nil { - if !pred(x.typ) { - check.invalidOp(x.pos(), "operator %s not defined for %s", op, x) - return false - } - } else { - check.invalidAST(x.pos(), "unknown operator %s", op) - return false - } - return true -} - -// The unary expression e may be nil. It's passed in for better error messages only. -func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) { - switch op { - case token.AND: - // spec: "As an exception to the addressability - // requirement x may also be a composite literal." - if _, ok := unparen(x.expr).(*ast.CompositeLit); !ok && x.mode != variable { - check.invalidOp(x.pos(), "cannot take address of %s", x) - x.mode = invalid - return - } - x.mode = value - x.typ = &Pointer{base: x.typ} - return - - case token.ARROW: - typ, ok := x.typ.Underlying().(*Chan) - if !ok { - check.invalidOp(x.pos(), "cannot receive from non-channel %s", x) - x.mode = invalid - return - } - if typ.dir == SendOnly { - check.invalidOp(x.pos(), "cannot receive from send-only channel %s", x) - x.mode = invalid - return - } - x.mode = commaok - x.typ = typ.elem - check.hasCallOrRecv = true - return - } - - if !check.op(unaryOpPredicates, x, op) { - x.mode = invalid - return - } - - if x.mode == constant_ { - typ := x.typ.Underlying().(*Basic) - var prec uint - if isUnsigned(typ) { - prec = uint(check.conf.sizeof(typ) * 8) - } - x.val = constant.UnaryOp(op, x.val, prec) - // Typed constants must be representable in - // their type after each constant operation. - if isTyped(typ) { - if e != nil { - x.expr = e // for better error message - } - check.representable(x, typ) - } - return - } - - x.mode = value - // x.typ remains unchanged -} - -func isShift(op token.Token) bool { - return op == token.SHL || op == token.SHR -} - -func isComparison(op token.Token) bool { - // Note: tokens are not ordered well to make this much easier - switch op { - case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ: - return true - } - return false -} - -func fitsFloat32(x constant.Value) bool { - f32, _ := constant.Float32Val(x) - f := float64(f32) - return !math.IsInf(f, 0) -} - -func roundFloat32(x constant.Value) constant.Value { - f32, _ := constant.Float32Val(x) - f := float64(f32) - if !math.IsInf(f, 0) { - return constant.MakeFloat64(f) - } - return nil -} - -func fitsFloat64(x constant.Value) bool { - f, _ := constant.Float64Val(x) - return !math.IsInf(f, 0) -} - -func roundFloat64(x constant.Value) constant.Value { - f, _ := constant.Float64Val(x) - if !math.IsInf(f, 0) { - return constant.MakeFloat64(f) - } - return nil -} - -// representableConst reports whether x can be represented as -// value of the given basic type and for the configuration -// provided (only needed for int/uint sizes). -// -// If rounded != nil, *rounded is set to the rounded value of x for -// representable floating-point and complex values, and to an Int -// value for integer values; it is left alone otherwise. -// It is ok to provide the addressof the first argument for rounded. -func representableConst(x constant.Value, conf *Config, typ *Basic, rounded *constant.Value) bool { - if x.Kind() == constant.Unknown { - return true // avoid follow-up errors - } - - switch { - case isInteger(typ): - x := constant.ToInt(x) - if x.Kind() != constant.Int { - return false - } - if rounded != nil { - *rounded = x - } - if x, ok := constant.Int64Val(x); ok { - switch typ.kind { - case Int: - var s = uint(conf.sizeof(typ)) * 8 - return int64(-1)<<(s-1) <= x && x <= int64(1)<<(s-1)-1 - case Int8: - const s = 8 - return -1<<(s-1) <= x && x <= 1<<(s-1)-1 - case Int16: - const s = 16 - return -1<<(s-1) <= x && x <= 1<<(s-1)-1 - case Int32: - const s = 32 - return -1<<(s-1) <= x && x <= 1<<(s-1)-1 - case Int64, UntypedInt: - return true - case Uint, Uintptr: - if s := uint(conf.sizeof(typ)) * 8; s < 64 { - return 0 <= x && x <= int64(1)<= 0 && n <= int(s) - case Uint64: - return constant.Sign(x) >= 0 && n <= 64 - case UntypedInt: - return true - } - - case isFloat(typ): - x := constant.ToFloat(x) - if x.Kind() != constant.Float { - return false - } - switch typ.kind { - case Float32: - if rounded == nil { - return fitsFloat32(x) - } - r := roundFloat32(x) - if r != nil { - *rounded = r - return true - } - case Float64: - if rounded == nil { - return fitsFloat64(x) - } - r := roundFloat64(x) - if r != nil { - *rounded = r - return true - } - case UntypedFloat: - return true - default: - unreachable() - } - - case isComplex(typ): - x := constant.ToComplex(x) - if x.Kind() != constant.Complex { - return false - } - switch typ.kind { - case Complex64: - if rounded == nil { - return fitsFloat32(constant.Real(x)) && fitsFloat32(constant.Imag(x)) - } - re := roundFloat32(constant.Real(x)) - im := roundFloat32(constant.Imag(x)) - if re != nil && im != nil { - *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) - return true - } - case Complex128: - if rounded == nil { - return fitsFloat64(constant.Real(x)) && fitsFloat64(constant.Imag(x)) - } - re := roundFloat64(constant.Real(x)) - im := roundFloat64(constant.Imag(x)) - if re != nil && im != nil { - *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) - return true - } - case UntypedComplex: - return true - default: - unreachable() - } - - case isString(typ): - return x.Kind() == constant.String - - case isBoolean(typ): - return x.Kind() == constant.Bool - } - - return false -} - -// representable checks that a constant operand is representable in the given basic type. -func (check *Checker) representable(x *operand, typ *Basic) { - assert(x.mode == constant_) - if !representableConst(x.val, check.conf, typ, &x.val) { - var msg string - if isNumeric(x.typ) && isNumeric(typ) { - // numeric conversion : error msg - // - // integer -> integer : overflows - // integer -> float : overflows (actually not possible) - // float -> integer : truncated - // float -> float : overflows - // - if !isInteger(x.typ) && isInteger(typ) { - msg = "%s truncated to %s" - } else { - msg = "%s overflows %s" - } - } else { - msg = "cannot convert %s to %s" - } - check.errorf(x.pos(), msg, x, typ) - x.mode = invalid - } -} - -// updateExprType updates the type of x to typ and invokes itself -// recursively for the operands of x, depending on expression kind. -// If typ is still an untyped and not the final type, updateExprType -// only updates the recorded untyped type for x and possibly its -// operands. Otherwise (i.e., typ is not an untyped type anymore, -// or it is the final type for x), the type and value are recorded. -// Also, if x is a constant, it must be representable as a value of typ, -// and if x is the (formerly untyped) lhs operand of a non-constant -// shift, it must be an integer value. -// -func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) { - old, found := check.untyped[x] - if !found { - return // nothing to do - } - - // update operands of x if necessary - switch x := x.(type) { - case *ast.BadExpr, - *ast.FuncLit, - *ast.CompositeLit, - *ast.IndexExpr, - *ast.SliceExpr, - *ast.TypeAssertExpr, - *ast.StarExpr, - *ast.KeyValueExpr, - *ast.ArrayType, - *ast.StructType, - *ast.FuncType, - *ast.InterfaceType, - *ast.MapType, - *ast.ChanType: - // These expression are never untyped - nothing to do. - // The respective sub-expressions got their final types - // upon assignment or use. - if debug { - check.dump("%s: found old type(%s): %s (new: %s)", x.Pos(), x, old.typ, typ) - unreachable() - } - return - - case *ast.CallExpr: - // Resulting in an untyped constant (e.g., built-in complex). - // The respective calls take care of calling updateExprType - // for the arguments if necessary. - - case *ast.Ident, *ast.BasicLit, *ast.SelectorExpr: - // An identifier denoting a constant, a constant literal, - // or a qualified identifier (imported untyped constant). - // No operands to take care of. - - case *ast.ParenExpr: - check.updateExprType(x.X, typ, final) - - case *ast.UnaryExpr: - // If x is a constant, the operands were constants. - // The operands don't need to be updated since they - // never get "materialized" into a typed value. If - // left in the untyped map, they will be processed - // at the end of the type check. - if old.val != nil { - break - } - check.updateExprType(x.X, typ, final) - - case *ast.BinaryExpr: - if old.val != nil { - break // see comment for unary expressions - } - if isComparison(x.Op) { - // The result type is independent of operand types - // and the operand types must have final types. - } else if isShift(x.Op) { - // The result type depends only on lhs operand. - // The rhs type was updated when checking the shift. - check.updateExprType(x.X, typ, final) - } else { - // The operand types match the result type. - check.updateExprType(x.X, typ, final) - check.updateExprType(x.Y, typ, final) - } - - default: - unreachable() - } - - // If the new type is not final and still untyped, just - // update the recorded type. - if !final && isUntyped(typ) { - old.typ = typ.Underlying().(*Basic) - check.untyped[x] = old - return - } - - // Otherwise we have the final (typed or untyped type). - // Remove it from the map of yet untyped expressions. - delete(check.untyped, x) - - if old.isLhs { - // If x is the lhs of a shift, its final type must be integer. - // We already know from the shift check that it is representable - // as an integer if it is a constant. - if !isInteger(typ) { - check.invalidOp(x.Pos(), "shifted operand %s (type %s) must be integer", x, typ) - return - } - } else if old.val != nil { - // If x is a constant, it must be representable as a value of typ. - c := operand{old.mode, x, old.typ, old.val, 0} - check.convertUntyped(&c, typ) - if c.mode == invalid { - return - } - } - - // Everything's fine, record final type and value for x. - check.recordTypeAndValue(x, old.mode, typ, old.val) -} - -// updateExprVal updates the value of x to val. -func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) { - if info, ok := check.untyped[x]; ok { - info.val = val - check.untyped[x] = info - } -} - -// convertUntyped attempts to set the type of an untyped value to the target type. -func (check *Checker) convertUntyped(x *operand, target Type) { - if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] { - return - } - - // TODO(gri) Sloppy code - clean up. This function is central - // to assignment and expression checking. - - if isUntyped(target) { - // both x and target are untyped - xkind := x.typ.(*Basic).kind - tkind := target.(*Basic).kind - if isNumeric(x.typ) && isNumeric(target) { - if xkind < tkind { - x.typ = target - check.updateExprType(x.expr, target, false) - } - } else if xkind != tkind { - goto Error - } - return - } - - // typed target - switch t := target.Underlying().(type) { - case *Basic: - if x.mode == constant_ { - check.representable(x, t) - if x.mode == invalid { - return - } - // expression value may have been rounded - update if needed - check.updateExprVal(x.expr, x.val) - } else { - // Non-constant untyped values may appear as the - // result of comparisons (untyped bool), intermediate - // (delayed-checked) rhs operands of shifts, and as - // the value nil. - switch x.typ.(*Basic).kind { - case UntypedBool: - if !isBoolean(target) { - goto Error - } - case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex: - if !isNumeric(target) { - goto Error - } - case UntypedString: - // Non-constant untyped string values are not - // permitted by the spec and should not occur. - unreachable() - case UntypedNil: - // Unsafe.Pointer is a basic type that includes nil. - if !hasNil(target) { - goto Error - } - default: - goto Error - } - } - case *Interface: - if !x.isNil() && !t.Empty() /* empty interfaces are ok */ { - goto Error - } - // Update operand types to the default type rather then - // the target (interface) type: values must have concrete - // dynamic types. If the value is nil, keep it untyped - // (this is important for tools such as go vet which need - // the dynamic type for argument checking of say, print - // functions) - if x.isNil() { - target = Typ[UntypedNil] - } else { - // cannot assign untyped values to non-empty interfaces - if !t.Empty() { - goto Error - } - target = Default(x.typ) - } - case *Pointer, *Signature, *Slice, *Map, *Chan: - if !x.isNil() { - goto Error - } - // keep nil untyped - see comment for interfaces, above - target = Typ[UntypedNil] - default: - goto Error - } - - x.typ = target - check.updateExprType(x.expr, target, true) // UntypedNils are final - return - -Error: - check.errorf(x.pos(), "cannot convert %s to %s", x, target) - x.mode = invalid -} - -func (check *Checker) comparison(x, y *operand, op token.Token) { - // spec: "In any comparison, the first operand must be assignable - // to the type of the second operand, or vice versa." - err := "" - if x.assignableTo(check.conf, y.typ, nil) || y.assignableTo(check.conf, x.typ, nil) { - defined := false - switch op { - case token.EQL, token.NEQ: - // spec: "The equality operators == and != apply to operands that are comparable." - defined = Comparable(x.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ) - case token.LSS, token.LEQ, token.GTR, token.GEQ: - // spec: The ordering operators <, <=, >, and >= apply to operands that are ordered." - defined = isOrdered(x.typ) - default: - unreachable() - } - if !defined { - typ := x.typ - if x.isNil() { - typ = y.typ - } - err = check.sprintf("operator %s not defined for %s", op, typ) - } - } else { - err = check.sprintf("mismatched types %s and %s", x.typ, y.typ) - } - - if err != "" { - check.errorf(x.pos(), "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err) - x.mode = invalid - return - } - - if x.mode == constant_ && y.mode == constant_ { - x.val = constant.MakeBool(constant.Compare(x.val, op, y.val)) - // The operands are never materialized; no need to update - // their types. - } else { - x.mode = value - // The operands have now their final types, which at run- - // time will be materialized. Update the expression trees. - // If the current types are untyped, the materialized type - // is the respective default type. - check.updateExprType(x.expr, Default(x.typ), true) - check.updateExprType(y.expr, Default(y.typ), true) - } - - // spec: "Comparison operators compare two operands and yield - // an untyped boolean value." - x.typ = Typ[UntypedBool] -} - -func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) { - untypedx := isUntyped(x.typ) - - var xval constant.Value - if x.mode == constant_ { - xval = constant.ToInt(x.val) - } - - if isInteger(x.typ) || untypedx && xval != nil && xval.Kind() == constant.Int { - // The lhs is of integer type or an untyped constant representable - // as an integer. Nothing to do. - } else { - // shift has no chance - check.invalidOp(x.pos(), "shifted operand %s must be integer", x) - x.mode = invalid - return - } - - // spec: "The right operand in a shift expression must have unsigned - // integer type or be an untyped constant representable by a value of - // type uint." - switch { - case isUnsigned(y.typ): - // nothing to do - case isUntyped(y.typ): - check.convertUntyped(y, Typ[Uint]) - if y.mode == invalid { - x.mode = invalid - return - } - default: - check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y) - x.mode = invalid - return - } - - if x.mode == constant_ { - if y.mode == constant_ { - // rhs must be an integer value - yval := constant.ToInt(y.val) - if yval.Kind() != constant.Int { - check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y) - x.mode = invalid - return - } - // rhs must be within reasonable bounds - const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 - s, ok := constant.Uint64Val(yval) - if !ok || s > shiftBound { - check.invalidOp(y.pos(), "invalid shift count %s", y) - x.mode = invalid - return - } - // The lhs is representable as an integer but may not be an integer - // (e.g., 2.0, an untyped float) - this can only happen for untyped - // non-integer numeric constants. Correct the type so that the shift - // result is of integer type. - if !isInteger(x.typ) { - x.typ = Typ[UntypedInt] - } - // x is a constant so xval != nil and it must be of Int kind. - x.val = constant.Shift(xval, op, uint(s)) - // Typed constants must be representable in - // their type after each constant operation. - if isTyped(x.typ) { - if e != nil { - x.expr = e // for better error message - } - check.representable(x, x.typ.Underlying().(*Basic)) - } - return - } - - // non-constant shift with constant lhs - if untypedx { - // spec: "If the left operand of a non-constant shift - // expression is an untyped constant, the type of the - // constant is what it would be if the shift expression - // were replaced by its left operand alone.". - // - // Delay operand checking until we know the final type - // by marking the lhs expression as lhs shift operand. - // - // Usually (in correct programs), the lhs expression - // is in the untyped map. However, it is possible to - // create incorrect programs where the same expression - // is evaluated twice (via a declaration cycle) such - // that the lhs expression type is determined in the - // first round and thus deleted from the map, and then - // not found in the second round (double insertion of - // the same expr node still just leads to one entry for - // that node, and it can only be deleted once). - // Be cautious and check for presence of entry. - // Example: var e, f = int(1<<""[f]) // issue 11347 - if info, found := check.untyped[x.expr]; found { - info.isLhs = true - check.untyped[x.expr] = info - } - // keep x's type - x.mode = value - return - } - } - - // constant rhs must be >= 0 - if y.mode == constant_ && constant.Sign(y.val) < 0 { - check.invalidOp(y.pos(), "shift count %s must not be negative", y) - } - - // non-constant shift - lhs must be an integer - if !isInteger(x.typ) { - check.invalidOp(x.pos(), "shifted operand %s must be integer", x) - x.mode = invalid - return - } - - x.mode = value -} - -var binaryOpPredicates = opPredicates{ - token.ADD: func(typ Type) bool { return isNumeric(typ) || isString(typ) }, - token.SUB: isNumeric, - token.MUL: isNumeric, - token.QUO: isNumeric, - token.REM: isInteger, - - token.AND: isInteger, - token.OR: isInteger, - token.XOR: isInteger, - token.AND_NOT: isInteger, - - token.LAND: isBoolean, - token.LOR: isBoolean, -} - -// The binary expression e may be nil. It's passed in for better error messages only. -func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token) { - var y operand - - check.expr(x, lhs) - check.expr(&y, rhs) - - if x.mode == invalid { - return - } - if y.mode == invalid { - x.mode = invalid - x.expr = y.expr - return - } - - if isShift(op) { - check.shift(x, &y, e, op) - return - } - - check.convertUntyped(x, y.typ) - if x.mode == invalid { - return - } - check.convertUntyped(&y, x.typ) - if y.mode == invalid { - x.mode = invalid - return - } - - if isComparison(op) { - check.comparison(x, &y, op) - return - } - - if !Identical(x.typ, y.typ) { - // only report an error if we have valid types - // (otherwise we had an error reported elsewhere already) - if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] { - check.invalidOp(x.pos(), "mismatched types %s and %s", x.typ, y.typ) - } - x.mode = invalid - return - } - - if !check.op(binaryOpPredicates, x, op) { - x.mode = invalid - return - } - - if op == token.QUO || op == token.REM { - // check for zero divisor - if (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 { - check.invalidOp(y.pos(), "division by zero") - x.mode = invalid - return - } - - // check for divisor underflow in complex division (see issue 20227) - if x.mode == constant_ && y.mode == constant_ && isComplex(x.typ) { - re, im := constant.Real(y.val), constant.Imag(y.val) - re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im) - if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 { - check.invalidOp(y.pos(), "division by zero") - x.mode = invalid - return - } - } - } - - if x.mode == constant_ && y.mode == constant_ { - xval := x.val - yval := y.val - typ := x.typ.Underlying().(*Basic) - // force integer division of integer operands - if op == token.QUO && isInteger(typ) { - op = token.QUO_ASSIGN - } - x.val = constant.BinaryOp(xval, op, yval) - // Typed constants must be representable in - // their type after each constant operation. - if isTyped(typ) { - if e != nil { - x.expr = e // for better error message - } - check.representable(x, typ) - } - return - } - - x.mode = value - // x.typ is unchanged -} - -// index checks an index expression for validity. -// If max >= 0, it is the upper bound for index. -// If index is valid and the result i >= 0, then i is the constant value of index. -func (check *Checker) index(index ast.Expr, max int64) (i int64, valid bool) { - var x operand - check.expr(&x, index) - if x.mode == invalid { - return - } - - // an untyped constant must be representable as Int - check.convertUntyped(&x, Typ[Int]) - if x.mode == invalid { - return - } - - // the index must be of integer type - if !isInteger(x.typ) { - check.invalidArg(x.pos(), "index %s must be integer", &x) - return - } - - // a constant index i must be in bounds - if x.mode == constant_ { - if constant.Sign(x.val) < 0 { - check.invalidArg(x.pos(), "index %s must not be negative", &x) - return - } - i, valid = constant.Int64Val(constant.ToInt(x.val)) - if !valid || max >= 0 && i >= max { - check.errorf(x.pos(), "index %s is out of bounds", &x) - return i, false - } - // 0 <= i [ && i < max ] - return i, true - } - - return -1, true -} - -// indexElts checks the elements (elts) of an array or slice composite literal -// against the literal's element type (typ), and the element indices against -// the literal length if known (length >= 0). It returns the length of the -// literal (maximum index value + 1). -// -func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 { - visited := make(map[int64]bool, len(elts)) - var index, max int64 - for _, e := range elts { - // determine and check index - validIndex := false - eval := e - if kv, _ := e.(*ast.KeyValueExpr); kv != nil { - if i, ok := check.index(kv.Key, length); ok { - if i >= 0 { - index = i - validIndex = true - } else { - check.errorf(e.Pos(), "index %s must be integer constant", kv.Key) - } - } - eval = kv.Value - } else if length >= 0 && index >= length { - check.errorf(e.Pos(), "index %d is out of bounds (>= %d)", index, length) - } else { - validIndex = true - } - - // if we have a valid index, check for duplicate entries - if validIndex { - if visited[index] { - check.errorf(e.Pos(), "duplicate index %d in array or slice literal", index) - } - visited[index] = true - } - index++ - if index > max { - max = index - } - - // check element against composite literal element type - var x operand - check.exprWithHint(&x, eval, typ) - check.assignment(&x, typ, "array or slice literal") - } - return max -} - -// exprKind describes the kind of an expression; the kind -// determines if an expression is valid in 'statement context'. -type exprKind int - -const ( - conversion exprKind = iota - expression - statement -) - -// rawExpr typechecks expression e and initializes x with the expression -// value or type. If an error occurred, x.mode is set to invalid. -// If hint != nil, it is the type of a composite literal element. -// -func (check *Checker) rawExpr(x *operand, e ast.Expr, hint Type) exprKind { - if trace { - check.trace(e.Pos(), "%s", e) - check.indent++ - defer func() { - check.indent-- - check.trace(e.Pos(), "=> %s", x) - }() - } - - kind := check.exprInternal(x, e, hint) - - // convert x into a user-friendly set of values - // TODO(gri) this code can be simplified - var typ Type - var val constant.Value - switch x.mode { - case invalid: - typ = Typ[Invalid] - case novalue: - typ = (*Tuple)(nil) - case constant_: - typ = x.typ - val = x.val - default: - typ = x.typ - } - assert(x.expr != nil && typ != nil) - - if isUntyped(typ) { - // delay type and value recording until we know the type - // or until the end of type checking - check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val) - } else { - check.recordTypeAndValue(e, x.mode, typ, val) - } - - return kind -} - -// exprInternal contains the core of type checking of expressions. -// Must only be called by rawExpr. -// -func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { - // make sure x has a valid state in case of bailout - // (was issue 5770) - x.mode = invalid - x.typ = Typ[Invalid] - - switch e := e.(type) { - case *ast.BadExpr: - goto Error // error was reported before - - case *ast.Ident: - check.ident(x, e, nil, nil) - - case *ast.Ellipsis: - // ellipses are handled explicitly where they are legal - // (array composite literals and parameter lists) - check.error(e.Pos(), "invalid use of '...'") - goto Error - - case *ast.BasicLit: - x.setConst(e.Kind, e.Value) - if x.mode == invalid { - check.invalidAST(e.Pos(), "invalid literal %v", e.Value) - goto Error - } - - case *ast.FuncLit: - if sig, ok := check.typ(e.Type).(*Signature); ok { - // Anonymous functions are considered part of the - // init expression/func declaration which contains - // them: use existing package-level declaration info. - // - // TODO(gri) We delay type-checking of regular (top-level) - // function bodies until later. Why don't we do - // it for closures of top-level expressions? - // (We can't easily do it for local closures - // because the surrounding scopes must reflect - // the exact position where the closure appears - // in the source; e.g., variables declared below - // must not be visible). - check.funcBody(check.decl, "", sig, e.Body) - x.mode = value - x.typ = sig - } else { - check.invalidAST(e.Pos(), "invalid function literal %s", e) - goto Error - } - - case *ast.CompositeLit: - var typ, base Type - - switch { - case e.Type != nil: - // composite literal type present - use it - // [...]T array types may only appear with composite literals. - // Check for them here so we don't have to handle ... in general. - if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && atyp.Len != nil { - if ellip, _ := atyp.Len.(*ast.Ellipsis); ellip != nil && ellip.Elt == nil { - // We have an "open" [...]T array type. - // Create a new ArrayType with unknown length (-1) - // and finish setting it up after analyzing the literal. - typ = &Array{len: -1, elem: check.typ(atyp.Elt)} - base = typ - break - } - } - typ = check.typ(e.Type) - base = typ - - case hint != nil: - // no composite literal type present - use hint (element type of enclosing type) - typ = hint - base, _ = deref(typ.Underlying()) // *T implies &T{} - - default: - // TODO(gri) provide better error messages depending on context - check.error(e.Pos(), "missing type in composite literal") - goto Error - } - - switch utyp := base.Underlying().(type) { - case *Struct: - if len(e.Elts) == 0 { - break - } - fields := utyp.fields - if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok { - // all elements must have keys - visited := make([]bool, len(fields)) - for _, e := range e.Elts { - kv, _ := e.(*ast.KeyValueExpr) - if kv == nil { - check.error(e.Pos(), "mixture of field:value and value elements in struct literal") - continue - } - key, _ := kv.Key.(*ast.Ident) - if key == nil { - check.errorf(kv.Pos(), "invalid field name %s in struct literal", kv.Key) - continue - } - i := fieldIndex(utyp.fields, check.pkg, key.Name) - if i < 0 { - check.errorf(kv.Pos(), "unknown field %s in struct literal", key.Name) - continue - } - fld := fields[i] - check.recordUse(key, fld) - // 0 <= i < len(fields) - if visited[i] { - check.errorf(kv.Pos(), "duplicate field name %s in struct literal", key.Name) - continue - } - visited[i] = true - check.expr(x, kv.Value) - etyp := fld.typ - check.assignment(x, etyp, "struct literal") - } - } else { - // no element must have a key - for i, e := range e.Elts { - if kv, _ := e.(*ast.KeyValueExpr); kv != nil { - check.error(kv.Pos(), "mixture of field:value and value elements in struct literal") - continue - } - check.expr(x, e) - if i >= len(fields) { - check.error(x.pos(), "too many values in struct literal") - break // cannot continue - } - // i < len(fields) - fld := fields[i] - if !fld.Exported() && fld.pkg != check.pkg { - check.errorf(x.pos(), "implicit assignment to unexported field %s in %s literal", fld.name, typ) - continue - } - etyp := fld.typ - check.assignment(x, etyp, "struct literal") - } - if len(e.Elts) < len(fields) { - check.error(e.Rbrace, "too few values in struct literal") - // ok to continue - } - } - - case *Array: - // Prevent crash if the array referred to is not yet set up. - // This is a stop-gap solution; a better approach would use the mechanism of - // Checker.ident (typexpr.go) using a path of types. But that would require - // passing the path everywhere (all expression-checking methods, not just - // type expression checking), and we're not set up for that (quite possibly - // an indication that cycle detection needs to be rethought). Was issue #18643. - if utyp.elem == nil { - check.error(e.Pos(), "illegal cycle in type declaration") - goto Error - } - n := check.indexedElts(e.Elts, utyp.elem, utyp.len) - // If we have an "open" [...]T array, set the length now that we know it - // and record the type for [...] (usually done by check.typExpr which is - // not called for [...]). - if utyp.len < 0 { - utyp.len = n - check.recordTypeAndValue(e.Type, typexpr, utyp, nil) - } - - case *Slice: - // Prevent crash if the slice referred to is not yet set up. - // See analogous comment for *Array. - if utyp.elem == nil { - check.error(e.Pos(), "illegal cycle in type declaration") - goto Error - } - check.indexedElts(e.Elts, utyp.elem, -1) - - case *Map: - // Prevent crash if the map referred to is not yet set up. - // See analogous comment for *Array. - if utyp.key == nil || utyp.elem == nil { - check.error(e.Pos(), "illegal cycle in type declaration") - goto Error - } - visited := make(map[interface{}][]Type, len(e.Elts)) - for _, e := range e.Elts { - kv, _ := e.(*ast.KeyValueExpr) - if kv == nil { - check.error(e.Pos(), "missing key in map literal") - continue - } - check.exprWithHint(x, kv.Key, utyp.key) - check.assignment(x, utyp.key, "map literal") - if x.mode == invalid { - continue - } - if x.mode == constant_ { - duplicate := false - // if the key is of interface type, the type is also significant when checking for duplicates - xkey := keyVal(x.val) - if _, ok := utyp.key.Underlying().(*Interface); ok { - for _, vtyp := range visited[xkey] { - if Identical(vtyp, x.typ) { - duplicate = true - break - } - } - visited[xkey] = append(visited[xkey], x.typ) - } else { - _, duplicate = visited[xkey] - visited[xkey] = nil - } - if duplicate { - check.errorf(x.pos(), "duplicate key %s in map literal", x.val) - continue - } - } - check.exprWithHint(x, kv.Value, utyp.elem) - check.assignment(x, utyp.elem, "map literal") - } - - default: - // when "using" all elements unpack KeyValueExpr - // explicitly because check.use doesn't accept them - for _, e := range e.Elts { - if kv, _ := e.(*ast.KeyValueExpr); kv != nil { - // Ideally, we should also "use" kv.Key but we can't know - // if it's an externally defined struct key or not. Going - // forward anyway can lead to other errors. Give up instead. - e = kv.Value - } - check.use(e) - } - // if utyp is invalid, an error was reported before - if utyp != Typ[Invalid] { - check.errorf(e.Pos(), "invalid composite literal type %s", typ) - goto Error - } - } - - x.mode = value - x.typ = typ - - case *ast.ParenExpr: - kind := check.rawExpr(x, e.X, nil) - x.expr = e - return kind - - case *ast.SelectorExpr: - check.selector(x, e) - - case *ast.IndexExpr: - check.expr(x, e.X) - if x.mode == invalid { - check.use(e.Index) - goto Error - } - - valid := false - length := int64(-1) // valid if >= 0 - switch typ := x.typ.Underlying().(type) { - case *Basic: - if isString(typ) { - valid = true - if x.mode == constant_ { - length = int64(len(constant.StringVal(x.val))) - } - // an indexed string always yields a byte value - // (not a constant) even if the string and the - // index are constant - x.mode = value - x.typ = universeByte // use 'byte' name - } - - case *Array: - valid = true - length = typ.len - if x.mode != variable { - x.mode = value - } - x.typ = typ.elem - - case *Pointer: - if typ, _ := typ.base.Underlying().(*Array); typ != nil { - valid = true - length = typ.len - x.mode = variable - x.typ = typ.elem - } - - case *Slice: - valid = true - x.mode = variable - x.typ = typ.elem - - case *Map: - var key operand - check.expr(&key, e.Index) - check.assignment(&key, typ.key, "map index") - if x.mode == invalid { - goto Error - } - x.mode = mapindex - x.typ = typ.elem - x.expr = e - return expression - } - - if !valid { - check.invalidOp(x.pos(), "cannot index %s", x) - goto Error - } - - if e.Index == nil { - check.invalidAST(e.Pos(), "missing index for %s", x) - goto Error - } - - check.index(e.Index, length) - // ok to continue - - case *ast.SliceExpr: - check.expr(x, e.X) - if x.mode == invalid { - check.use(e.Low, e.High, e.Max) - goto Error - } - - valid := false - length := int64(-1) // valid if >= 0 - switch typ := x.typ.Underlying().(type) { - case *Basic: - if isString(typ) { - if e.Slice3 { - check.invalidOp(x.pos(), "3-index slice of string") - goto Error - } - valid = true - if x.mode == constant_ { - length = int64(len(constant.StringVal(x.val))) - } - // spec: "For untyped string operands the result - // is a non-constant value of type string." - if typ.kind == UntypedString { - x.typ = Typ[String] - } - } - - case *Array: - valid = true - length = typ.len - if x.mode != variable { - check.invalidOp(x.pos(), "cannot slice %s (value not addressable)", x) - goto Error - } - x.typ = &Slice{elem: typ.elem} - - case *Pointer: - if typ, _ := typ.base.Underlying().(*Array); typ != nil { - valid = true - length = typ.len - x.typ = &Slice{elem: typ.elem} - } - - case *Slice: - valid = true - // x.typ doesn't change - } - - if !valid { - check.invalidOp(x.pos(), "cannot slice %s", x) - goto Error - } - - x.mode = value - - // spec: "Only the first index may be omitted; it defaults to 0." - if e.Slice3 && (e.High == nil || e.Max == nil) { - check.error(e.Rbrack, "2nd and 3rd index required in 3-index slice") - goto Error - } - - // check indices - var ind [3]int64 - for i, expr := range []ast.Expr{e.Low, e.High, e.Max} { - x := int64(-1) - switch { - case expr != nil: - // The "capacity" is only known statically for strings, arrays, - // and pointers to arrays, and it is the same as the length for - // those types. - max := int64(-1) - if length >= 0 { - max = length + 1 - } - if t, ok := check.index(expr, max); ok && t >= 0 { - x = t - } - case i == 0: - // default is 0 for the first index - x = 0 - case length >= 0: - // default is length (== capacity) otherwise - x = length - } - ind[i] = x - } - - // constant indices must be in range - // (check.index already checks that existing indices >= 0) - L: - for i, x := range ind[:len(ind)-1] { - if x > 0 { - for _, y := range ind[i+1:] { - if y >= 0 && x > y { - check.errorf(e.Rbrack, "invalid slice indices: %d > %d", x, y) - break L // only report one error, ok to continue - } - } - } - } - - case *ast.TypeAssertExpr: - check.expr(x, e.X) - if x.mode == invalid { - goto Error - } - xtyp, _ := x.typ.Underlying().(*Interface) - if xtyp == nil { - check.invalidOp(x.pos(), "%s is not an interface", x) - goto Error - } - // x.(type) expressions are handled explicitly in type switches - if e.Type == nil { - check.invalidAST(e.Pos(), "use of .(type) outside type switch") - goto Error - } - T := check.typ(e.Type) - if T == Typ[Invalid] { - goto Error - } - check.typeAssertion(x.pos(), x, xtyp, T) - x.mode = commaok - x.typ = T - - case *ast.CallExpr: - return check.call(x, e) - - case *ast.StarExpr: - check.exprOrType(x, e.X) - switch x.mode { - case invalid: - goto Error - case typexpr: - x.typ = &Pointer{base: x.typ} - default: - if typ, ok := x.typ.Underlying().(*Pointer); ok { - x.mode = variable - x.typ = typ.base - } else { - check.invalidOp(x.pos(), "cannot indirect %s", x) - goto Error - } - } - - case *ast.UnaryExpr: - check.expr(x, e.X) - if x.mode == invalid { - goto Error - } - check.unary(x, e, e.Op) - if x.mode == invalid { - goto Error - } - if e.Op == token.ARROW { - x.expr = e - return statement // receive operations may appear in statement context - } - - case *ast.BinaryExpr: - check.binary(x, e, e.X, e.Y, e.Op) - if x.mode == invalid { - goto Error - } - - case *ast.KeyValueExpr: - // key:value expressions are handled in composite literals - check.invalidAST(e.Pos(), "no key:value expected") - goto Error - - case *ast.ArrayType, *ast.StructType, *ast.FuncType, - *ast.InterfaceType, *ast.MapType, *ast.ChanType: - x.mode = typexpr - x.typ = check.typ(e) - // Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue - // even though check.typ has already called it. This is fine as both - // times the same expression and type are recorded. It is also not a - // performance issue because we only reach here for composite literal - // types, which are comparatively rare. - - default: - panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e)) - } - - // everything went well - x.expr = e - return expression - -Error: - x.mode = invalid - x.expr = e - return statement // avoid follow-up errors -} - -func keyVal(x constant.Value) interface{} { - switch x.Kind() { - case constant.Bool: - return constant.BoolVal(x) - case constant.String: - return constant.StringVal(x) - case constant.Int: - if v, ok := constant.Int64Val(x); ok { - return v - } - if v, ok := constant.Uint64Val(x); ok { - return v - } - case constant.Float: - v, _ := constant.Float64Val(x) - return v - case constant.Complex: - r, _ := constant.Float64Val(constant.Real(x)) - i, _ := constant.Float64Val(constant.Imag(x)) - return complex(r, i) - } - return x -} - -// typeAssertion checks that x.(T) is legal; xtyp must be the type of x. -func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, T Type) { - method, wrongType := assertableTo(xtyp, T) - if method == nil { - return - } - - var msg string - if wrongType { - msg = "wrong type for method" - } else { - msg = "missing method" - } - check.errorf(pos, "%s cannot have dynamic type %s (%s %s)", x, T, msg, method.name) -} - -func (check *Checker) singleValue(x *operand) { - if x.mode == value { - // tuple types are never named - no need for underlying type below - if t, ok := x.typ.(*Tuple); ok { - assert(t.Len() != 1) - check.errorf(x.pos(), "%d-valued %s where single value is expected", t.Len(), x) - x.mode = invalid - } - } -} - -// expr typechecks expression e and initializes x with the expression value. -// The result must be a single value. -// If an error occurred, x.mode is set to invalid. -// -func (check *Checker) expr(x *operand, e ast.Expr) { - check.multiExpr(x, e) - check.singleValue(x) -} - -// multiExpr is like expr but the result may be a multi-value. -func (check *Checker) multiExpr(x *operand, e ast.Expr) { - check.rawExpr(x, e, nil) - var msg string - switch x.mode { - default: - return - case novalue: - msg = "%s used as value" - case builtin: - msg = "%s must be called" - case typexpr: - msg = "%s is not an expression" - } - check.errorf(x.pos(), msg, x) - x.mode = invalid -} - -// exprWithHint typechecks expression e and initializes x with the expression value; -// hint is the type of a composite literal element. -// If an error occurred, x.mode is set to invalid. -// -func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) { - assert(hint != nil) - check.rawExpr(x, e, hint) - check.singleValue(x) - var msg string - switch x.mode { - default: - return - case novalue: - msg = "%s used as value" - case builtin: - msg = "%s must be called" - case typexpr: - msg = "%s is not an expression" - } - check.errorf(x.pos(), msg, x) - x.mode = invalid -} - -// exprOrType typechecks expression or type e and initializes x with the expression value or type. -// If an error occurred, x.mode is set to invalid. -// -func (check *Checker) exprOrType(x *operand, e ast.Expr) { - check.rawExpr(x, e, nil) - check.singleValue(x) - if x.mode == novalue { - check.errorf(x.pos(), "%s used as value or type", x) - x.mode = invalid - } -} diff --git a/third_party/forked/golang/go/types/exprstring.go b/third_party/forked/golang/go/types/exprstring.go deleted file mode 100644 index 28d605f5ee841..0000000000000 --- a/third_party/forked/golang/go/types/exprstring.go +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements printing of expressions. - -package types - -import ( - "bytes" - "go/ast" -) - -// ExprString returns the (possibly shortened) string representation for x. -// Shortened representations are suitable for user interfaces but may not -// necessarily follow Go syntax. -func ExprString(x ast.Expr) string { - var buf bytes.Buffer - WriteExpr(&buf, x) - return buf.String() -} - -// WriteExpr writes the (possibly shortened) string representation for x to buf. -// Shortened representations are suitable for user interfaces but may not -// necessarily follow Go syntax. -func WriteExpr(buf *bytes.Buffer, x ast.Expr) { - // The AST preserves source-level parentheses so there is - // no need to introduce them here to correct for different - // operator precedences. (This assumes that the AST was - // generated by a Go parser.) - - switch x := x.(type) { - default: - buf.WriteString("(bad expr)") // nil, ast.BadExpr, ast.KeyValueExpr - - case *ast.Ident: - buf.WriteString(x.Name) - - case *ast.Ellipsis: - buf.WriteString("...") - if x.Elt != nil { - WriteExpr(buf, x.Elt) - } - - case *ast.BasicLit: - buf.WriteString(x.Value) - - case *ast.FuncLit: - buf.WriteByte('(') - WriteExpr(buf, x.Type) - buf.WriteString(" literal)") // shortened - - case *ast.CompositeLit: - buf.WriteByte('(') - WriteExpr(buf, x.Type) - buf.WriteString(" literal)") // shortened - - case *ast.ParenExpr: - buf.WriteByte('(') - WriteExpr(buf, x.X) - buf.WriteByte(')') - - case *ast.SelectorExpr: - WriteExpr(buf, x.X) - buf.WriteByte('.') - buf.WriteString(x.Sel.Name) - - case *ast.IndexExpr: - WriteExpr(buf, x.X) - buf.WriteByte('[') - WriteExpr(buf, x.Index) - buf.WriteByte(']') - - case *ast.SliceExpr: - WriteExpr(buf, x.X) - buf.WriteByte('[') - if x.Low != nil { - WriteExpr(buf, x.Low) - } - buf.WriteByte(':') - if x.High != nil { - WriteExpr(buf, x.High) - } - if x.Slice3 { - buf.WriteByte(':') - if x.Max != nil { - WriteExpr(buf, x.Max) - } - } - buf.WriteByte(']') - - case *ast.TypeAssertExpr: - WriteExpr(buf, x.X) - buf.WriteString(".(") - WriteExpr(buf, x.Type) - buf.WriteByte(')') - - case *ast.CallExpr: - WriteExpr(buf, x.Fun) - buf.WriteByte('(') - for i, arg := range x.Args { - if i > 0 { - buf.WriteString(", ") - } - WriteExpr(buf, arg) - } - if x.Ellipsis.IsValid() { - buf.WriteString("...") - } - buf.WriteByte(')') - - case *ast.StarExpr: - buf.WriteByte('*') - WriteExpr(buf, x.X) - - case *ast.UnaryExpr: - buf.WriteString(x.Op.String()) - WriteExpr(buf, x.X) - - case *ast.BinaryExpr: - WriteExpr(buf, x.X) - buf.WriteByte(' ') - buf.WriteString(x.Op.String()) - buf.WriteByte(' ') - WriteExpr(buf, x.Y) - - case *ast.ArrayType: - buf.WriteByte('[') - if x.Len != nil { - WriteExpr(buf, x.Len) - } - buf.WriteByte(']') - WriteExpr(buf, x.Elt) - - case *ast.StructType: - buf.WriteString("struct{") - writeFieldList(buf, x.Fields, "; ", false) - buf.WriteByte('}') - - case *ast.FuncType: - buf.WriteString("func") - writeSigExpr(buf, x) - - case *ast.InterfaceType: - buf.WriteString("interface{") - writeFieldList(buf, x.Methods, "; ", true) - buf.WriteByte('}') - - case *ast.MapType: - buf.WriteString("map[") - WriteExpr(buf, x.Key) - buf.WriteByte(']') - WriteExpr(buf, x.Value) - - case *ast.ChanType: - var s string - switch x.Dir { - case ast.SEND: - s = "chan<- " - case ast.RECV: - s = "<-chan " - default: - s = "chan " - } - buf.WriteString(s) - WriteExpr(buf, x.Value) - } -} - -func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) { - buf.WriteByte('(') - writeFieldList(buf, sig.Params, ", ", false) - buf.WriteByte(')') - - res := sig.Results - n := res.NumFields() - if n == 0 { - // no result - return - } - - buf.WriteByte(' ') - if n == 1 && len(res.List[0].Names) == 0 { - // single unnamed result - WriteExpr(buf, res.List[0].Type) - return - } - - // multiple or named result(s) - buf.WriteByte('(') - writeFieldList(buf, res, ", ", false) - buf.WriteByte(')') -} - -func writeFieldList(buf *bytes.Buffer, fields *ast.FieldList, sep string, iface bool) { - for i, f := range fields.List { - if i > 0 { - buf.WriteString(sep) - } - - // field list names - for i, name := range f.Names { - if i > 0 { - buf.WriteString(", ") - } - buf.WriteString(name.Name) - } - - // types of interface methods consist of signatures only - if sig, _ := f.Type.(*ast.FuncType); sig != nil && iface { - writeSigExpr(buf, sig) - continue - } - - // named fields are separated with a blank from the field type - if len(f.Names) > 0 { - buf.WriteByte(' ') - } - - WriteExpr(buf, f.Type) - - // ignore tag - } -} diff --git a/third_party/forked/golang/go/types/gotype.go b/third_party/forked/golang/go/types/gotype.go deleted file mode 100644 index 196fc9bbd6041..0000000000000 --- a/third_party/forked/golang/go/types/gotype.go +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -// Build this command explicitly: go build gotype.go - -/* -The gotype command, like the front-end of a Go compiler, parses and -type-checks a single Go package. Errors are reported if the analysis -fails; otherwise gotype is quiet (unless -v is set). - -Without a list of paths, gotype reads from standard input, which -must provide a single Go source file defining a complete package. - -With a single directory argument, gotype checks the Go files in -that directory, comprising a single package. Use -t to include the -(in-package) _test.go files. Use -x to type check only external -test files. - -Otherwise, each path must be the filename of a Go file belonging -to the same package. - -Imports are processed by importing directly from the source of -imported packages (default), or by importing from compiled and -installed packages (by setting -c to the respective compiler). - -The -c flag must be set to a compiler ("gc", "gccgo") when type- -checking packages containing imports with relative import paths -(import "./mypkg") because the source importer cannot know which -files to include for such packages. - -Usage: - gotype [flags] [path...] - -The flags are: - -t - include local test files in a directory (ignored if -x is provided) - -x - consider only external test files in a directory - -e - report all errors (not just the first 10) - -v - verbose mode - -c - compiler used for installed packages (gc, gccgo, or source); default: source - -Flags controlling additional output: - -ast - print AST (forces -seq) - -trace - print parse trace (forces -seq) - -comments - parse comments (ignored unless -ast or -trace is provided) - -Examples: - -To check the files a.go, b.go, and c.go: - - gotype a.go b.go c.go - -To check an entire package including (in-package) tests in the directory dir and print the processed files: - - gotype -t -v dir - -To check the external test package (if any) in the current directory, based on installed packages compiled with -cmd/compile: - - gotype -c=gc -x . - -To verify the output of a pipe: - - echo "package foo" | gotype - -*/ -package main - -import ( - "flag" - "fmt" - "go/ast" - "go/build" - "go/importer" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "io/ioutil" - "os" - "path/filepath" - "sync" - "time" -) - -var ( - // main operation modes - testFiles = flag.Bool("t", false, "include in-package test files in a directory") - xtestFiles = flag.Bool("x", false, "consider only external test files in a directory") - allErrors = flag.Bool("e", false, "report all errors, not just the first 10") - verbose = flag.Bool("v", false, "verbose mode") - compiler = flag.String("c", "source", "compiler used for installed packages (gc, gccgo, or source)") - - // additional output control - printAST = flag.Bool("ast", false, "print AST (forces -seq)") - printTrace = flag.Bool("trace", false, "print parse trace (forces -seq)") - parseComments = flag.Bool("comments", false, "parse comments (ignored unless -ast or -trace is provided)") -) - -var ( - fset = token.NewFileSet() - errorCount = 0 - sequential = false - parserMode parser.Mode -) - -func initParserMode() { - if *allErrors { - parserMode |= parser.AllErrors - } - if *printAST { - sequential = true - } - if *printTrace { - parserMode |= parser.Trace - sequential = true - } - if *parseComments && (*printAST || *printTrace) { - parserMode |= parser.ParseComments - } -} - -const usageString = `usage: gotype [flags] [path ...] - -The gotype command, like the front-end of a Go compiler, parses and -type-checks a single Go package. Errors are reported if the analysis -fails; otherwise gotype is quiet (unless -v is set). - -Without a list of paths, gotype reads from standard input, which -must provide a single Go source file defining a complete package. - -With a single directory argument, gotype checks the Go files in -that directory, comprising a single package. Use -t to include the -(in-package) _test.go files. Use -x to type check only external -test files. - -Otherwise, each path must be the filename of a Go file belonging -to the same package. - -Imports are processed by importing directly from the source of -imported packages (default), or by importing from compiled and -installed packages (by setting -c to the respective compiler). - -The -c flag must be set to a compiler ("gc", "gccgo") when type- -checking packages containing imports with relative import paths -(import "./mypkg") because the source importer cannot know which -files to include for such packages. -` - -func usage() { - fmt.Fprintln(os.Stderr, usageString) - flag.PrintDefaults() - os.Exit(2) -} - -func report(err error) { - scanner.PrintError(os.Stderr, err) - if list, ok := err.(scanner.ErrorList); ok { - errorCount += len(list) - return - } - errorCount++ -} - -// parse may be called concurrently -func parse(filename string, src interface{}) (*ast.File, error) { - if *verbose { - fmt.Println(filename) - } - file, err := parser.ParseFile(fset, filename, src, parserMode) // ok to access fset concurrently - if *printAST { - ast.Print(fset, file) - } - return file, err -} - -func parseStdin() (*ast.File, error) { - src, err := ioutil.ReadAll(os.Stdin) - if err != nil { - return nil, err - } - return parse("", src) -} - -func parseFiles(dir string, filenames []string) ([]*ast.File, error) { - files := make([]*ast.File, len(filenames)) - errors := make([]error, len(filenames)) - - var wg sync.WaitGroup - for i, filename := range filenames { - wg.Add(1) - go func(i int, filepath string) { - defer wg.Done() - files[i], errors[i] = parse(filepath, nil) - }(i, filepath.Join(dir, filename)) - if sequential { - wg.Wait() - } - } - wg.Wait() - - // if there are errors, return the first one for deterministic results - for _, err := range errors { - if err != nil { - return nil, err - } - } - - return files, nil -} - -func parseDir(dir string) ([]*ast.File, error) { - ctxt := build.Default - pkginfo, err := ctxt.ImportDir(dir, 0) - if _, nogo := err.(*build.NoGoError); err != nil && !nogo { - return nil, err - } - - if *xtestFiles { - return parseFiles(dir, pkginfo.XTestGoFiles) - } - - filenames := append(pkginfo.GoFiles, pkginfo.CgoFiles...) - if *testFiles { - filenames = append(filenames, pkginfo.TestGoFiles...) - } - return parseFiles(dir, filenames) -} - -func getPkgFiles(args []string) ([]*ast.File, error) { - if len(args) == 0 { - // stdin - file, err := parseStdin() - if err != nil { - return nil, err - } - return []*ast.File{file}, nil - } - - if len(args) == 1 { - // possibly a directory - path := args[0] - info, err := os.Stat(path) - if err != nil { - return nil, err - } - if info.IsDir() { - return parseDir(path) - } - } - - // list of files - return parseFiles("", args) -} - -func checkPkgFiles(files []*ast.File) { - type bailout struct{} - - // if checkPkgFiles is called multiple times, set up conf only once - conf := types.Config{ - FakeImportC: true, - Error: func(err error) { - if !*allErrors && errorCount >= 10 { - panic(bailout{}) - } - report(err) - }, - Importer: importer.For(*compiler, nil), - Sizes: types.SizesFor(build.Default.Compiler, build.Default.GOARCH), - } - - defer func() { - switch p := recover().(type) { - case nil, bailout: - // normal return or early exit - default: - // re-panic - panic(p) - } - }() - - const path = "pkg" // any non-empty string will do for now - conf.Check(path, fset, files, nil) -} - -func printStats(d time.Duration) { - fileCount := 0 - lineCount := 0 - fset.Iterate(func(f *token.File) bool { - fileCount++ - lineCount += f.LineCount() - return true - }) - - fmt.Printf( - "%s (%d files, %d lines, %d lines/s)\n", - d, fileCount, lineCount, int64(float64(lineCount)/d.Seconds()), - ) -} - -func main() { - flag.Usage = usage - flag.Parse() - initParserMode() - - start := time.Now() - - files, err := getPkgFiles(flag.Args()) - if err != nil { - report(err) - os.Exit(2) - } - - checkPkgFiles(files) - if errorCount > 0 { - os.Exit(2) - } - - if *verbose { - printStats(time.Since(start)) - } -} diff --git a/third_party/forked/golang/go/types/initorder.go b/third_party/forked/golang/go/types/initorder.go deleted file mode 100644 index 966dccb8289f6..0000000000000 --- a/third_party/forked/golang/go/types/initorder.go +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -import ( - "container/heap" - "fmt" -) - -// initOrder computes the Info.InitOrder for package variables. -func (check *Checker) initOrder() { - // An InitOrder may already have been computed if a package is - // built from several calls to (*Checker).Files. Clear it. - check.Info.InitOrder = check.Info.InitOrder[:0] - - // Compute the object dependency graph and initialize - // a priority queue with the list of graph nodes. - pq := nodeQueue(dependencyGraph(check.objMap)) - heap.Init(&pq) - - const debug = false - if debug { - fmt.Printf("Computing initialization order for %s\n\n", check.pkg) - fmt.Println("Object dependency graph:") - for obj, d := range check.objMap { - // only print objects that may appear in the dependency graph - if obj, _ := obj.(dependency); obj != nil { - if len(d.deps) > 0 { - fmt.Printf("\t%s depends on\n", obj.Name()) - for dep := range d.deps { - fmt.Printf("\t\t%s\n", dep.Name()) - } - } else { - fmt.Printf("\t%s has no dependencies\n", obj.Name()) - } - } - } - fmt.Println() - - fmt.Println("Transposed object dependency graph (functions eliminated):") - for _, n := range pq { - fmt.Printf("\t%s depends on %d nodes\n", n.obj.Name(), n.ndeps) - for p := range n.pred { - fmt.Printf("\t\t%s is dependent\n", p.obj.Name()) - } - } - fmt.Println() - - fmt.Println("Processing nodes:") - } - - // Determine initialization order by removing the highest priority node - // (the one with the fewest dependencies) and its edges from the graph, - // repeatedly, until there are no nodes left. - // In a valid Go program, those nodes always have zero dependencies (after - // removing all incoming dependencies), otherwise there are initialization - // cycles. - emitted := make(map[*declInfo]bool) - for len(pq) > 0 { - // get the next node - n := heap.Pop(&pq).(*graphNode) - - if debug { - fmt.Printf("\t%s (src pos %d) depends on %d nodes now\n", - n.obj.Name(), n.obj.order(), n.ndeps) - } - - // if n still depends on other nodes, we have a cycle - if n.ndeps > 0 { - cycle := findPath(check.objMap, n.obj, n.obj, make(objSet)) - // If n.obj is not part of the cycle (e.g., n.obj->b->c->d->c), - // cycle will be nil. Don't report anything in that case since - // the cycle is reported when the algorithm gets to an object - // in the cycle. - // Furthermore, once an object in the cycle is encountered, - // the cycle will be broken (dependency count will be reduced - // below), and so the remaining nodes in the cycle don't trigger - // another error (unless they are part of multiple cycles). - if cycle != nil { - check.reportCycle(cycle) - } - // Ok to continue, but the variable initialization order - // will be incorrect at this point since it assumes no - // cycle errors. - } - - // reduce dependency count of all dependent nodes - // and update priority queue - for p := range n.pred { - p.ndeps-- - heap.Fix(&pq, p.index) - } - - // record the init order for variables with initializers only - v, _ := n.obj.(*Var) - info := check.objMap[v] - if v == nil || !info.hasInitializer() { - continue - } - - // n:1 variable declarations such as: a, b = f() - // introduce a node for each lhs variable (here: a, b); - // but they all have the same initializer - emit only - // one, for the first variable seen - if emitted[info] { - continue // initializer already emitted, if any - } - emitted[info] = true - - infoLhs := info.lhs // possibly nil (see declInfo.lhs field comment) - if infoLhs == nil { - infoLhs = []*Var{v} - } - init := &Initializer{infoLhs, info.init} - check.Info.InitOrder = append(check.Info.InitOrder, init) - } - - if debug { - fmt.Println() - fmt.Println("Initialization order:") - for _, init := range check.Info.InitOrder { - fmt.Printf("\t%s\n", init) - } - fmt.Println() - } -} - -// findPath returns the (reversed) list of objects []Object{to, ... from} -// such that there is a path of object dependencies from 'from' to 'to'. -// If there is no such path, the result is nil. -func findPath(objMap map[Object]*declInfo, from, to Object, visited objSet) []Object { - if visited[from] { - return nil // node already seen - } - visited[from] = true - - for d := range objMap[from].deps { - if d == to { - return []Object{d} - } - if P := findPath(objMap, d, to, visited); P != nil { - return append(P, d) - } - } - - return nil -} - -// reportCycle reports an error for the given cycle. -func (check *Checker) reportCycle(cycle []Object) { - obj := cycle[0] - check.errorf(obj.Pos(), "initialization cycle for %s", obj.Name()) - // subtle loop: print cycle[i] for i = 0, n-1, n-2, ... 1 for len(cycle) = n - for i := len(cycle) - 1; i >= 0; i-- { - check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented - obj = cycle[i] - } - // print cycle[0] again to close the cycle - check.errorf(obj.Pos(), "\t%s", obj.Name()) -} - -// ---------------------------------------------------------------------------- -// Object dependency graph - -// A dependency is an object that may be a dependency in an initialization -// expression. Only constants, variables, and functions can be dependencies. -// Constants are here because constant expression cycles are reported during -// initialization order computation. -type dependency interface { - Object - isDependency() -} - -// A graphNode represents a node in the object dependency graph. -// Each node p in n.pred represents an edge p->n, and each node -// s in n.succ represents an edge n->s; with a->b indicating that -// a depends on b. -type graphNode struct { - obj dependency // object represented by this node - pred, succ nodeSet // consumers and dependencies of this node (lazily initialized) - index int // node index in graph slice/priority queue - ndeps int // number of outstanding dependencies before this object can be initialized -} - -type nodeSet map[*graphNode]bool - -func (s *nodeSet) add(p *graphNode) { - if *s == nil { - *s = make(nodeSet) - } - (*s)[p] = true -} - -// dependencyGraph computes the object dependency graph from the given objMap, -// with any function nodes removed. The resulting graph contains only constants -// and variables. -func dependencyGraph(objMap map[Object]*declInfo) []*graphNode { - // M is the dependency (Object) -> graphNode mapping - M := make(map[dependency]*graphNode) - for obj := range objMap { - // only consider nodes that may be an initialization dependency - if obj, _ := obj.(dependency); obj != nil { - M[obj] = &graphNode{obj: obj} - } - } - - // compute edges for graph M - // (We need to include all nodes, even isolated ones, because they still need - // to be scheduled for initialization in correct order relative to other nodes.) - for obj, n := range M { - // for each dependency obj -> d (= deps[i]), create graph edges n->s and s->n - for d := range objMap[obj].deps { - // only consider nodes that may be an initialization dependency - if d, _ := d.(dependency); d != nil { - d := M[d] - n.succ.add(d) - d.pred.add(n) - } - } - } - - // remove function nodes and collect remaining graph nodes in G - // (Mutually recursive functions may introduce cycles among themselves - // which are permitted. Yet such cycles may incorrectly inflate the dependency - // count for variables which in turn may not get scheduled for initialization - // in correct order.) - var G []*graphNode - for obj, n := range M { - if _, ok := obj.(*Func); ok { - // connect each predecessor p of n with each successor s - // and drop the function node (don't collect it in G) - for p := range n.pred { - // ignore self-cycles - if p != n { - // Each successor s of n becomes a successor of p, and - // each predecessor p of n becomes a predecessor of s. - for s := range n.succ { - // ignore self-cycles - if s != n { - p.succ.add(s) - s.pred.add(p) - delete(s.pred, n) // remove edge to n - } - } - delete(p.succ, n) // remove edge to n - } - } - } else { - // collect non-function nodes - G = append(G, n) - } - } - - // fill in index and ndeps fields - for i, n := range G { - n.index = i - n.ndeps = len(n.succ) - } - - return G -} - -// ---------------------------------------------------------------------------- -// Priority queue - -// nodeQueue implements the container/heap interface; -// a nodeQueue may be used as a priority queue. -type nodeQueue []*graphNode - -func (a nodeQueue) Len() int { return len(a) } - -func (a nodeQueue) Swap(i, j int) { - x, y := a[i], a[j] - a[i], a[j] = y, x - x.index, y.index = j, i -} - -func (a nodeQueue) Less(i, j int) bool { - x, y := a[i], a[j] - // nodes are prioritized by number of incoming dependencies (1st key) - // and source order (2nd key) - return x.ndeps < y.ndeps || x.ndeps == y.ndeps && x.obj.order() < y.obj.order() -} - -func (a *nodeQueue) Push(x interface{}) { - panic("unreachable") -} - -func (a *nodeQueue) Pop() interface{} { - n := len(*a) - x := (*a)[n-1] - x.index = -1 // for safety - *a = (*a)[:n-1] - return x -} diff --git a/third_party/forked/golang/go/types/labels.go b/third_party/forked/golang/go/types/labels.go deleted file mode 100644 index 3b43b4ba05c63..0000000000000 --- a/third_party/forked/golang/go/types/labels.go +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -import ( - "go/ast" - "go/token" -) - -// labels checks correct label use in body. -func (check *Checker) labels(body *ast.BlockStmt) { - // set of all labels in this body - all := NewScope(nil, body.Pos(), body.End(), "label") - - fwdJumps := check.blockBranches(all, nil, nil, body.List) - - // If there are any forward jumps left, no label was found for - // the corresponding goto statements. Either those labels were - // never defined, or they are inside blocks and not reachable - // for the respective gotos. - for _, jmp := range fwdJumps { - var msg string - name := jmp.Label.Name - if alt := all.Lookup(name); alt != nil { - msg = "goto %s jumps into block" - alt.(*Label).used = true // avoid another error - } else { - msg = "label %s not declared" - } - check.errorf(jmp.Label.Pos(), msg, name) - } - - // spec: "It is illegal to define a label that is never used." - for _, obj := range all.elems { - if lbl := obj.(*Label); !lbl.used { - check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name) - } - } -} - -// A block tracks label declarations in a block and its enclosing blocks. -type block struct { - parent *block // enclosing block - lstmt *ast.LabeledStmt // labeled statement to which this block belongs, or nil - labels map[string]*ast.LabeledStmt // allocated lazily -} - -// insert records a new label declaration for the current block. -// The label must not have been declared before in any block. -func (b *block) insert(s *ast.LabeledStmt) { - name := s.Label.Name - if debug { - assert(b.gotoTarget(name) == nil) - } - labels := b.labels - if labels == nil { - labels = make(map[string]*ast.LabeledStmt) - b.labels = labels - } - labels[name] = s -} - -// gotoTarget returns the labeled statement in the current -// or an enclosing block with the given label name, or nil. -func (b *block) gotoTarget(name string) *ast.LabeledStmt { - for s := b; s != nil; s = s.parent { - if t := s.labels[name]; t != nil { - return t - } - } - return nil -} - -// enclosingTarget returns the innermost enclosing labeled -// statement with the given label name, or nil. -func (b *block) enclosingTarget(name string) *ast.LabeledStmt { - for s := b; s != nil; s = s.parent { - if t := s.lstmt; t != nil && t.Label.Name == name { - return t - } - } - return nil -} - -// blockBranches processes a block's statement list and returns the set of outgoing forward jumps. -// all is the scope of all declared labels, parent the set of labels declared in the immediately -// enclosing block, and lstmt is the labeled statement this block is associated with (or nil). -func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.LabeledStmt, list []ast.Stmt) []*ast.BranchStmt { - b := &block{parent: parent, lstmt: lstmt} - - var ( - varDeclPos token.Pos - fwdJumps, badJumps []*ast.BranchStmt - ) - - // All forward jumps jumping over a variable declaration are possibly - // invalid (they may still jump out of the block and be ok). - // recordVarDecl records them for the given position. - recordVarDecl := func(pos token.Pos) { - varDeclPos = pos - badJumps = append(badJumps[:0], fwdJumps...) // copy fwdJumps to badJumps - } - - jumpsOverVarDecl := func(jmp *ast.BranchStmt) bool { - if varDeclPos.IsValid() { - for _, bad := range badJumps { - if jmp == bad { - return true - } - } - } - return false - } - - blockBranches := func(lstmt *ast.LabeledStmt, list []ast.Stmt) { - // Unresolved forward jumps inside the nested block - // become forward jumps in the current block. - fwdJumps = append(fwdJumps, check.blockBranches(all, b, lstmt, list)...) - } - - var stmtBranches func(ast.Stmt) - stmtBranches = func(s ast.Stmt) { - switch s := s.(type) { - case *ast.DeclStmt: - if d, _ := s.Decl.(*ast.GenDecl); d != nil && d.Tok == token.VAR { - recordVarDecl(d.Pos()) - } - - case *ast.LabeledStmt: - // declare non-blank label - if name := s.Label.Name; name != "_" { - lbl := NewLabel(s.Label.Pos(), check.pkg, name) - if alt := all.Insert(lbl); alt != nil { - check.softErrorf(lbl.pos, "label %s already declared", name) - check.reportAltDecl(alt) - // ok to continue - } else { - b.insert(s) - check.recordDef(s.Label, lbl) - } - // resolve matching forward jumps and remove them from fwdJumps - i := 0 - for _, jmp := range fwdJumps { - if jmp.Label.Name == name { - // match - lbl.used = true - check.recordUse(jmp.Label, lbl) - if jumpsOverVarDecl(jmp) { - check.softErrorf( - jmp.Label.Pos(), - "goto %s jumps over variable declaration at line %d", - name, - check.fset.Position(varDeclPos).Line, - ) - // ok to continue - } - } else { - // no match - record new forward jump - fwdJumps[i] = jmp - i++ - } - } - fwdJumps = fwdJumps[:i] - lstmt = s - } - stmtBranches(s.Stmt) - - case *ast.BranchStmt: - if s.Label == nil { - return // checked in 1st pass (check.stmt) - } - - // determine and validate target - name := s.Label.Name - switch s.Tok { - case token.BREAK: - // spec: "If there is a label, it must be that of an enclosing - // "for", "switch", or "select" statement, and that is the one - // whose execution terminates." - valid := false - if t := b.enclosingTarget(name); t != nil { - switch t.Stmt.(type) { - case *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt, *ast.ForStmt, *ast.RangeStmt: - valid = true - } - } - if !valid { - check.errorf(s.Label.Pos(), "invalid break label %s", name) - return - } - - case token.CONTINUE: - // spec: "If there is a label, it must be that of an enclosing - // "for" statement, and that is the one whose execution advances." - valid := false - if t := b.enclosingTarget(name); t != nil { - switch t.Stmt.(type) { - case *ast.ForStmt, *ast.RangeStmt: - valid = true - } - } - if !valid { - check.errorf(s.Label.Pos(), "invalid continue label %s", name) - return - } - - case token.GOTO: - if b.gotoTarget(name) == nil { - // label may be declared later - add branch to forward jumps - fwdJumps = append(fwdJumps, s) - return - } - - default: - check.invalidAST(s.Pos(), "branch statement: %s %s", s.Tok, name) - return - } - - // record label use - obj := all.Lookup(name) - obj.(*Label).used = true - check.recordUse(s.Label, obj) - - case *ast.AssignStmt: - if s.Tok == token.DEFINE { - recordVarDecl(s.Pos()) - } - - case *ast.BlockStmt: - blockBranches(lstmt, s.List) - - case *ast.IfStmt: - stmtBranches(s.Body) - if s.Else != nil { - stmtBranches(s.Else) - } - - case *ast.CaseClause: - blockBranches(nil, s.Body) - - case *ast.SwitchStmt: - stmtBranches(s.Body) - - case *ast.TypeSwitchStmt: - stmtBranches(s.Body) - - case *ast.CommClause: - blockBranches(nil, s.Body) - - case *ast.SelectStmt: - stmtBranches(s.Body) - - case *ast.ForStmt: - stmtBranches(s.Body) - - case *ast.RangeStmt: - stmtBranches(s.Body) - } - } - - for _, s := range list { - stmtBranches(s) - } - - return fwdJumps -} diff --git a/third_party/forked/golang/go/types/lookup.go b/third_party/forked/golang/go/types/lookup.go deleted file mode 100644 index ee8202d9e42d7..0000000000000 --- a/third_party/forked/golang/go/types/lookup.go +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements various field and method lookup functions. - -package types - -// LookupFieldOrMethod looks up a field or method with given package and name -// in T and returns the corresponding *Var or *Func, an index sequence, and a -// bool indicating if there were any pointer indirections on the path to the -// field or method. If addressable is set, T is the type of an addressable -// variable (only matters for method lookups). -// -// The last index entry is the field or method index in the (possibly embedded) -// type where the entry was found, either: -// -// 1) the list of declared methods of a named type; or -// 2) the list of all methods (method set) of an interface type; or -// 3) the list of fields of a struct type. -// -// The earlier index entries are the indices of the anonymous struct fields -// traversed to get to the found entry, starting at depth 0. -// -// If no entry is found, a nil object is returned. In this case, the returned -// index and indirect values have the following meaning: -// -// - If index != nil, the index sequence points to an ambiguous entry -// (the same name appeared more than once at the same embedding level). -// -// - If indirect is set, a method with a pointer receiver type was found -// but there was no pointer on the path from the actual receiver type to -// the method's formal receiver base type, nor was the receiver addressable. -// -func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { - // Methods cannot be associated to a named pointer type - // (spec: "The type denoted by T is called the receiver base type; - // it must not be a pointer or interface type and it must be declared - // in the same package as the method."). - // Thus, if we have a named pointer type, proceed with the underlying - // pointer type but discard the result if it is a method since we would - // not have found it for T (see also issue 8590). - if t, _ := T.(*Named); t != nil { - if p, _ := t.underlying.(*Pointer); p != nil { - obj, index, indirect = lookupFieldOrMethod(p, false, pkg, name) - if _, ok := obj.(*Func); ok { - return nil, nil, false - } - return - } - } - - return lookupFieldOrMethod(T, addressable, pkg, name) -} - -// TODO(gri) The named type consolidation and seen maps below must be -// indexed by unique keys for a given type. Verify that named -// types always have only one representation (even when imported -// indirectly via different packages.) - -func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { - // WARNING: The code in this function is extremely subtle - do not modify casually! - // This function and NewMethodSet should be kept in sync. - - if name == "_" { - return // blank fields/methods are never found - } - - typ, isPtr := deref(T) - - // *typ where typ is an interface has no methods. - if isPtr && IsInterface(typ) { - return - } - - // Start with typ as single entry at shallowest depth. - current := []embeddedType{{typ, nil, isPtr, false}} - - // Named types that we have seen already, allocated lazily. - // Used to avoid endless searches in case of recursive types. - // Since only Named types can be used for recursive types, we - // only need to track those. - // (If we ever allow type aliases to construct recursive types, - // we must use type identity rather than pointer equality for - // the map key comparison, as we do in consolidateMultiples.) - var seen map[*Named]bool - - // search current depth - for len(current) > 0 { - var next []embeddedType // embedded types found at current depth - - // look for (pkg, name) in all types at current depth - for _, e := range current { - typ := e.typ - - // If we have a named type, we may have associated methods. - // Look for those first. - if named, _ := typ.(*Named); named != nil { - if seen[named] { - // We have seen this type before, at a more shallow depth - // (note that multiples of this type at the current depth - // were consolidated before). The type at that depth shadows - // this same type at the current depth, so we can ignore - // this one. - continue - } - if seen == nil { - seen = make(map[*Named]bool) - } - seen[named] = true - - // look for a matching attached method - if i, m := lookupMethod(named.methods, pkg, name); m != nil { - // potential match - assert(m.typ != nil) - index = concat(e.index, i) - if obj != nil || e.multiples { - return nil, index, false // collision - } - obj = m - indirect = e.indirect - continue // we can't have a matching field or interface method - } - - // continue with underlying type - typ = named.underlying - } - - switch t := typ.(type) { - case *Struct: - // look for a matching field and collect embedded types - for i, f := range t.fields { - if f.sameId(pkg, name) { - assert(f.typ != nil) - index = concat(e.index, i) - if obj != nil || e.multiples { - return nil, index, false // collision - } - obj = f - indirect = e.indirect - continue // we can't have a matching interface method - } - // Collect embedded struct fields for searching the next - // lower depth, but only if we have not seen a match yet - // (if we have a match it is either the desired field or - // we have a name collision on the same depth; in either - // case we don't need to look further). - // Embedded fields are always of the form T or *T where - // T is a type name. If e.typ appeared multiple times at - // this depth, f.typ appears multiple times at the next - // depth. - if obj == nil && f.anonymous { - typ, isPtr := deref(f.typ) - // TODO(gri) optimization: ignore types that can't - // have fields or methods (only Named, Struct, and - // Interface types need to be considered). - next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples}) - } - } - - case *Interface: - // look for a matching method - // TODO(gri) t.allMethods is sorted - use binary search - if i, m := lookupMethod(t.allMethods, pkg, name); m != nil { - assert(m.typ != nil) - index = concat(e.index, i) - if obj != nil || e.multiples { - return nil, index, false // collision - } - obj = m - indirect = e.indirect - } - } - } - - if obj != nil { - // found a potential match - // spec: "A method call x.m() is valid if the method set of (the type of) x - // contains m and the argument list can be assigned to the parameter - // list of m. If x is addressable and &x's method set contains m, x.m() - // is shorthand for (&x).m()". - if f, _ := obj.(*Func); f != nil && ptrRecv(f) && !indirect && !addressable { - return nil, nil, true // pointer/addressable receiver required - } - return - } - - current = consolidateMultiples(next) - } - - return nil, nil, false // not found -} - -// embeddedType represents an embedded type -type embeddedType struct { - typ Type - index []int // embedded field indices, starting with index at depth 0 - indirect bool // if set, there was a pointer indirection on the path to this field - multiples bool // if set, typ appears multiple times at this depth -} - -// consolidateMultiples collects multiple list entries with the same type -// into a single entry marked as containing multiples. The result is the -// consolidated list. -func consolidateMultiples(list []embeddedType) []embeddedType { - if len(list) <= 1 { - return list // at most one entry - nothing to do - } - - n := 0 // number of entries w/ unique type - prev := make(map[Type]int) // index at which type was previously seen - for _, e := range list { - if i, found := lookupType(prev, e.typ); found { - list[i].multiples = true - // ignore this entry - } else { - prev[e.typ] = n - list[n] = e - n++ - } - } - return list[:n] -} - -func lookupType(m map[Type]int, typ Type) (int, bool) { - // fast path: maybe the types are equal - if i, found := m[typ]; found { - return i, true - } - - for t, i := range m { - if Identical(t, typ) { - return i, true - } - } - - return 0, false -} - -// MissingMethod returns (nil, false) if V implements T, otherwise it -// returns a missing method required by T and whether it is missing or -// just has the wrong type. -// -// For non-interface types V, or if static is set, V implements T if all -// methods of T are present in V. Otherwise (V is an interface and static -// is not set), MissingMethod only checks that methods of T which are also -// present in V have matching types (e.g., for a type assertion x.(T) where -// x is of interface type V). -// -func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) { - // fast path for common case - if T.Empty() { - return - } - - // TODO(gri) Consider using method sets here. Might be more efficient. - - if ityp, _ := V.Underlying().(*Interface); ityp != nil { - // TODO(gri) allMethods is sorted - can do this more efficiently - for _, m := range T.allMethods { - _, obj := lookupMethod(ityp.allMethods, m.pkg, m.name) - switch { - case obj == nil: - if static { - return m, false - } - case !Identical(obj.Type(), m.typ): - return m, true - } - } - return - } - - // A concrete type implements T if it implements all methods of T. - for _, m := range T.allMethods { - obj, _, _ := lookupFieldOrMethod(V, false, m.pkg, m.name) - - f, _ := obj.(*Func) - if f == nil { - return m, false - } - - if !Identical(f.typ, m.typ) { - return m, true - } - } - - return -} - -// assertableTo reports whether a value of type V can be asserted to have type T. -// It returns (nil, false) as affirmative answer. Otherwise it returns a missing -// method required by V and whether it is missing or just has the wrong type. -func assertableTo(V *Interface, T Type) (method *Func, wrongType bool) { - // no static check is required if T is an interface - // spec: "If T is an interface type, x.(T) asserts that the - // dynamic type of x implements the interface T." - if _, ok := T.Underlying().(*Interface); ok && !strict { - return - } - return MissingMethod(T, V, false) -} - -// deref dereferences typ if it is a *Pointer and returns its base and true. -// Otherwise it returns (typ, false). -func deref(typ Type) (Type, bool) { - if p, _ := typ.(*Pointer); p != nil { - return p.base, true - } - return typ, false -} - -// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a -// (named or unnamed) struct and returns its base. Otherwise it returns typ. -func derefStructPtr(typ Type) Type { - if p, _ := typ.Underlying().(*Pointer); p != nil { - if _, ok := p.base.Underlying().(*Struct); ok { - return p.base - } - } - return typ -} - -// concat returns the result of concatenating list and i. -// The result does not share its underlying array with list. -func concat(list []int, i int) []int { - var t []int - t = append(t, list...) - return append(t, i) -} - -// fieldIndex returns the index for the field with matching package and name, or a value < 0. -func fieldIndex(fields []*Var, pkg *Package, name string) int { - if name != "_" { - for i, f := range fields { - if f.sameId(pkg, name) { - return i - } - } - } - return -1 -} - -// lookupMethod returns the index of and method with matching package and name, or (-1, nil). -func lookupMethod(methods []*Func, pkg *Package, name string) (int, *Func) { - if name != "_" { - for i, m := range methods { - if m.sameId(pkg, name) { - return i, m - } - } - } - return -1, nil -} diff --git a/third_party/forked/golang/go/types/methodset.go b/third_party/forked/golang/go/types/methodset.go deleted file mode 100644 index 2a8b1c24f7a2d..0000000000000 --- a/third_party/forked/golang/go/types/methodset.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements method sets. - -package types - -import ( - "bytes" - "fmt" - "sort" -) - -// A MethodSet is an ordered set of concrete or abstract (interface) methods; -// a method is a MethodVal selection, and they are ordered by ascending m.Obj().Id(). -// The zero value for a MethodSet is a ready-to-use empty method set. -type MethodSet struct { - list []*Selection -} - -func (s *MethodSet) String() string { - if s.Len() == 0 { - return "MethodSet {}" - } - - var buf bytes.Buffer - fmt.Fprintln(&buf, "MethodSet {") - for _, f := range s.list { - fmt.Fprintf(&buf, "\t%s\n", f) - } - fmt.Fprintln(&buf, "}") - return buf.String() -} - -// Len returns the number of methods in s. -func (s *MethodSet) Len() int { return len(s.list) } - -// At returns the i'th method in s for 0 <= i < s.Len(). -func (s *MethodSet) At(i int) *Selection { return s.list[i] } - -// Lookup returns the method with matching package and name, or nil if not found. -func (s *MethodSet) Lookup(pkg *Package, name string) *Selection { - if s.Len() == 0 { - return nil - } - - key := Id(pkg, name) - i := sort.Search(len(s.list), func(i int) bool { - m := s.list[i] - return m.obj.Id() >= key - }) - if i < len(s.list) { - m := s.list[i] - if m.obj.Id() == key { - return m - } - } - return nil -} - -// Shared empty method set. -var emptyMethodSet MethodSet - -// NewMethodSet returns the method set for the given type T. -// It always returns a non-nil method set, even if it is empty. -func NewMethodSet(T Type) *MethodSet { - // WARNING: The code in this function is extremely subtle - do not modify casually! - // This function and lookupFieldOrMethod should be kept in sync. - - // method set up to the current depth, allocated lazily - var base methodSet - - typ, isPtr := deref(T) - - // *typ where typ is an interface has no methods. - if isPtr && IsInterface(typ) { - return &emptyMethodSet - } - - // Start with typ as single entry at shallowest depth. - current := []embeddedType{{typ, nil, isPtr, false}} - - // Named types that we have seen already, allocated lazily. - // Used to avoid endless searches in case of recursive types. - // Since only Named types can be used for recursive types, we - // only need to track those. - // (If we ever allow type aliases to construct recursive types, - // we must use type identity rather than pointer equality for - // the map key comparison, as we do in consolidateMultiples.) - var seen map[*Named]bool - - // collect methods at current depth - for len(current) > 0 { - var next []embeddedType // embedded types found at current depth - - // field and method sets at current depth, allocated lazily - var fset fieldSet - var mset methodSet - - for _, e := range current { - typ := e.typ - - // If we have a named type, we may have associated methods. - // Look for those first. - if named, _ := typ.(*Named); named != nil { - if seen[named] { - // We have seen this type before, at a more shallow depth - // (note that multiples of this type at the current depth - // were consolidated before). The type at that depth shadows - // this same type at the current depth, so we can ignore - // this one. - continue - } - if seen == nil { - seen = make(map[*Named]bool) - } - seen[named] = true - - mset = mset.add(named.methods, e.index, e.indirect, e.multiples) - - // continue with underlying type - typ = named.underlying - } - - switch t := typ.(type) { - case *Struct: - for i, f := range t.fields { - fset = fset.add(f, e.multiples) - - // Embedded fields are always of the form T or *T where - // T is a type name. If typ appeared multiple times at - // this depth, f.Type appears multiple times at the next - // depth. - if f.anonymous { - typ, isPtr := deref(f.typ) - // TODO(gri) optimization: ignore types that can't - // have fields or methods (only Named, Struct, and - // Interface types need to be considered). - next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples}) - } - } - - case *Interface: - mset = mset.add(t.allMethods, e.index, true, e.multiples) - } - } - - // Add methods and collisions at this depth to base if no entries with matching - // names exist already. - for k, m := range mset { - if _, found := base[k]; !found { - // Fields collide with methods of the same name at this depth. - if _, found := fset[k]; found { - m = nil // collision - } - if base == nil { - base = make(methodSet) - } - base[k] = m - } - } - - // Multiple fields with matching names collide at this depth and shadow all - // entries further down; add them as collisions to base if no entries with - // matching names exist already. - for k, f := range fset { - if f == nil { - if _, found := base[k]; !found { - if base == nil { - base = make(methodSet) - } - base[k] = nil // collision - } - } - } - - current = consolidateMultiples(next) - } - - if len(base) == 0 { - return &emptyMethodSet - } - - // collect methods - var list []*Selection - for _, m := range base { - if m != nil { - m.recv = T - list = append(list, m) - } - } - // sort by unique name - sort.Slice(list, func(i, j int) bool { - return list[i].obj.Id() < list[j].obj.Id() - }) - return &MethodSet{list} -} - -// A fieldSet is a set of fields and name collisions. -// A collision indicates that multiple fields with the -// same unique id appeared. -type fieldSet map[string]*Var // a nil entry indicates a name collision - -// Add adds field f to the field set s. -// If multiples is set, f appears multiple times -// and is treated as a collision. -func (s fieldSet) add(f *Var, multiples bool) fieldSet { - if s == nil { - s = make(fieldSet) - } - key := f.Id() - // if f is not in the set, add it - if !multiples { - if _, found := s[key]; !found { - s[key] = f - return s - } - } - s[key] = nil // collision - return s -} - -// A methodSet is a set of methods and name collisions. -// A collision indicates that multiple methods with the -// same unique id appeared. -type methodSet map[string]*Selection // a nil entry indicates a name collision - -// Add adds all functions in list to the method set s. -// If multiples is set, every function in list appears multiple times -// and is treated as a collision. -func (s methodSet) add(list []*Func, index []int, indirect bool, multiples bool) methodSet { - if len(list) == 0 { - return s - } - if s == nil { - s = make(methodSet) - } - for i, f := range list { - key := f.Id() - // if f is not in the set, add it - if !multiples { - // TODO(gri) A found method may not be added because it's not in the method set - // (!indirect && ptrRecv(f)). A 2nd method on the same level may be in the method - // set and may not collide with the first one, thus leading to a false positive. - // Is that possible? Investigate. - if _, found := s[key]; !found && (indirect || !ptrRecv(f)) { - s[key] = &Selection{MethodVal, nil, f, concat(index, i), indirect} - continue - } - } - s[key] = nil // collision - } - return s -} - -// ptrRecv reports whether the receiver is of the form *T. -// The receiver must exist. -func ptrRecv(f *Func) bool { - _, isPtr := deref(f.typ.(*Signature).recv.typ) - return isPtr -} diff --git a/third_party/forked/golang/go/types/object.go b/third_party/forked/golang/go/types/object.go deleted file mode 100644 index 633d32712ae19..0000000000000 --- a/third_party/forked/golang/go/types/object.go +++ /dev/null @@ -1,424 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -import ( - "bytes" - "fmt" - "go/ast" - "go/constant" - "go/token" -) - -// An Object describes a named language entity such as a package, -// constant, type, variable, function (incl. methods), or label. -// All objects implement the Object interface. -// -type Object interface { - Parent() *Scope // scope in which this object is declared; nil for methods and struct fields - Pos() token.Pos // position of object identifier in declaration - Pkg() *Package // package to which this object belongs; nil for labels and objects in the Universe scope - Name() string // package local object name - Type() Type // object type - Exported() bool // reports whether the name starts with a capital letter - Id() string // object name if exported, qualified name if not exported (see func Id) - - // String returns a human-readable string of the object. - String() string - - // order reflects a package-level object's source order: if object - // a is before object b in the source, then a.order() < b.order(). - // order returns a value > 0 for package-level objects; it returns - // 0 for all other objects (including objects in file scopes). - order() uint32 - - // setOrder sets the order number of the object. It must be > 0. - setOrder(uint32) - - // setParent sets the parent scope of the object. - setParent(*Scope) - - // sameId reports whether obj.Id() and Id(pkg, name) are the same. - sameId(pkg *Package, name string) bool - - // scopePos returns the start position of the scope of this Object - scopePos() token.Pos - - // setScopePos sets the start position of the scope for this Object. - setScopePos(pos token.Pos) -} - -// Id returns name if it is exported, otherwise it -// returns the name qualified with the package path. -func Id(pkg *Package, name string) string { - if ast.IsExported(name) { - return name - } - // unexported names need the package path for differentiation - // (if there's no package, make sure we don't start with '.' - // as that may change the order of methods between a setup - // inside a package and outside a package - which breaks some - // tests) - path := "_" - // pkg is nil for objects in Universe scope and possibly types - // introduced via Eval (see also comment in object.sameId) - if pkg != nil && pkg.path != "" { - path = pkg.path - } - return path + "." + name -} - -// An object implements the common parts of an Object. -type object struct { - parent *Scope - pos token.Pos - pkg *Package - name string - typ Type - order_ uint32 - scopePos_ token.Pos -} - -func (obj *object) Parent() *Scope { return obj.parent } -func (obj *object) Pos() token.Pos { return obj.pos } -func (obj *object) Pkg() *Package { return obj.pkg } -func (obj *object) Name() string { return obj.name } -func (obj *object) Type() Type { return obj.typ } -func (obj *object) Exported() bool { return ast.IsExported(obj.name) } -func (obj *object) Id() string { return Id(obj.pkg, obj.name) } -func (obj *object) String() string { panic("abstract") } -func (obj *object) order() uint32 { return obj.order_ } -func (obj *object) scopePos() token.Pos { return obj.scopePos_ } - -func (obj *object) setParent(parent *Scope) { obj.parent = parent } -func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order } -func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos } - -func (obj *object) sameId(pkg *Package, name string) bool { - // spec: - // "Two identifiers are different if they are spelled differently, - // or if they appear in different packages and are not exported. - // Otherwise, they are the same." - if name != obj.name { - return false - } - // obj.Name == name - if obj.Exported() { - return true - } - // not exported, so packages must be the same (pkg == nil for - // fields in Universe scope; this can only happen for types - // introduced via Eval) - if pkg == nil || obj.pkg == nil { - return pkg == obj.pkg - } - // pkg != nil && obj.pkg != nil - return pkg.path == obj.pkg.path -} - -// A PkgName represents an imported Go package. -// PkgNames don't have a type. -type PkgName struct { - object - imported *Package - used bool // set if the package was used -} - -// NewPkgName returns a new PkgName object representing an imported package. -// The remaining arguments set the attributes found with all Objects. -func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName { - return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, token.NoPos}, imported, false} -} - -// Imported returns the package that was imported. -// It is distinct from Pkg(), which is the package containing the import statement. -func (obj *PkgName) Imported() *Package { return obj.imported } - -// A Const represents a declared constant. -type Const struct { - object - val constant.Value - visited bool // for initialization cycle detection -} - -// NewConst returns a new constant with value val. -// The remaining arguments set the attributes found with all Objects. -func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const { - return &Const{object{nil, pos, pkg, name, typ, 0, token.NoPos}, val, false} -} - -func (obj *Const) Val() constant.Value { return obj.val } -func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression - -// A TypeName represents a name for a (named or alias) type. -type TypeName struct { - object -} - -// NewTypeName returns a new type name denoting the given typ. -// The remaining arguments set the attributes found with all Objects. -// -// The typ argument may be a defined (Named) type or an alias type. -// It may also be nil such that the returned TypeName can be used as -// argument for NewNamed, which will set the TypeName's type as a side- -// effect. -func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName { - return &TypeName{object{nil, pos, pkg, name, typ, 0, token.NoPos}} -} - -// IsAlias reports whether obj is an alias name for a type. -func (obj *TypeName) IsAlias() bool { - switch t := obj.typ.(type) { - case nil: - return false - case *Basic: - // unsafe.Pointer is not an alias. - if obj.pkg == Unsafe { - return false - } - // Any user-defined type name for a basic type is an alias for a - // basic type (because basic types are pre-declared in the Universe - // scope, outside any package scope), and so is any type name with - // a different name than the name of the basic type it refers to. - // Additionally, we need to look for "byte" and "rune" because they - // are aliases but have the same names (for better error messages). - return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune - case *Named: - return obj != t.obj - default: - return true - } -} - -// A Variable represents a declared variable (including function parameters and results, and struct fields). -type Var struct { - object - anonymous bool // if set, the variable is an anonymous struct field, and name is the type name - visited bool // for initialization cycle detection - isField bool // var is struct field - used bool // set if the variable was used -} - -// NewVar returns a new variable. -// The arguments set the attributes found with all Objects. -func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var { - return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}} -} - -// NewParam returns a new variable representing a function parameter. -func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var { - return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, used: true} // parameters are always 'used' -} - -// NewField returns a new variable representing a struct field. -// For anonymous (embedded) fields, the name is the unqualified -// type name under which the field is accessible. -func NewField(pos token.Pos, pkg *Package, name string, typ Type, anonymous bool) *Var { - return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, anonymous: anonymous, isField: true} -} - -// Anonymous reports whether the variable is an anonymous field. -func (obj *Var) Anonymous() bool { return obj.anonymous } - -// IsField reports whether the variable is a struct field. -func (obj *Var) IsField() bool { return obj.isField } - -func (*Var) isDependency() {} // a variable may be a dependency of an initialization expression - -// A Func represents a declared function, concrete method, or abstract -// (interface) method. Its Type() is always a *Signature. -// An abstract method may belong to many interfaces due to embedding. -type Func struct { - object -} - -// NewFunc returns a new function with the given signature, representing -// the function's type. -func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func { - // don't store a nil signature - var typ Type - if sig != nil { - typ = sig - } - return &Func{object{nil, pos, pkg, name, typ, 0, token.NoPos}} -} - -// FullName returns the package- or receiver-type-qualified name of -// function or method obj. -func (obj *Func) FullName() string { - var buf bytes.Buffer - writeFuncName(&buf, obj, nil) - return buf.String() -} - -// Scope returns the scope of the function's body block. -func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope } - -func (*Func) isDependency() {} // a function may be a dependency of an initialization expression - -// A Label represents a declared label. -// Labels don't have a type. -type Label struct { - object - used bool // set if the label was used -} - -// NewLabel returns a new label. -func NewLabel(pos token.Pos, pkg *Package, name string) *Label { - return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid]}, false} -} - -// A Builtin represents a built-in function. -// Builtins don't have a valid type. -type Builtin struct { - object - id builtinId -} - -func newBuiltin(id builtinId) *Builtin { - return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid]}, id} -} - -// Nil represents the predeclared value nil. -type Nil struct { - object -} - -func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) { - var tname *TypeName - typ := obj.Type() - - switch obj := obj.(type) { - case *PkgName: - fmt.Fprintf(buf, "package %s", obj.Name()) - if path := obj.imported.path; path != "" && path != obj.name { - fmt.Fprintf(buf, " (%q)", path) - } - return - - case *Const: - buf.WriteString("const") - - case *TypeName: - tname = obj - buf.WriteString("type") - - case *Var: - if obj.isField { - buf.WriteString("field") - } else { - buf.WriteString("var") - } - - case *Func: - buf.WriteString("func ") - writeFuncName(buf, obj, qf) - if typ != nil { - WriteSignature(buf, typ.(*Signature), qf) - } - return - - case *Label: - buf.WriteString("label") - typ = nil - - case *Builtin: - buf.WriteString("builtin") - typ = nil - - case *Nil: - buf.WriteString("nil") - return - - default: - panic(fmt.Sprintf("writeObject(%T)", obj)) - } - - buf.WriteByte(' ') - - // For package-level objects, qualify the name. - if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj { - writePackage(buf, obj.Pkg(), qf) - } - buf.WriteString(obj.Name()) - - if typ == nil { - return - } - - if tname != nil { - // We have a type object: Don't print anything more for - // basic types since there's no more information (names - // are the same; see also comment in TypeName.IsAlias). - if _, ok := typ.(*Basic); ok { - return - } - if tname.IsAlias() { - buf.WriteString(" =") - } else { - typ = typ.Underlying() - } - } - - buf.WriteByte(' ') - WriteType(buf, typ, qf) -} - -func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) { - if pkg == nil { - return - } - var s string - if qf != nil { - s = qf(pkg) - } else { - s = pkg.Path() - } - if s != "" { - buf.WriteString(s) - buf.WriteByte('.') - } -} - -// ObjectString returns the string form of obj. -// The Qualifier controls the printing of -// package-level objects, and may be nil. -func ObjectString(obj Object, qf Qualifier) string { - var buf bytes.Buffer - writeObject(&buf, obj, qf) - return buf.String() -} - -func (obj *PkgName) String() string { return ObjectString(obj, nil) } -func (obj *Const) String() string { return ObjectString(obj, nil) } -func (obj *TypeName) String() string { return ObjectString(obj, nil) } -func (obj *Var) String() string { return ObjectString(obj, nil) } -func (obj *Func) String() string { return ObjectString(obj, nil) } -func (obj *Label) String() string { return ObjectString(obj, nil) } -func (obj *Builtin) String() string { return ObjectString(obj, nil) } -func (obj *Nil) String() string { return ObjectString(obj, nil) } - -func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) { - if f.typ != nil { - sig := f.typ.(*Signature) - if recv := sig.Recv(); recv != nil { - buf.WriteByte('(') - if _, ok := recv.Type().(*Interface); ok { - // gcimporter creates abstract methods of - // named interfaces using the interface type - // (not the named type) as the receiver. - // Don't print it in full. - buf.WriteString("interface") - } else { - WriteType(buf, recv.Type(), qf) - } - buf.WriteByte(')') - buf.WriteByte('.') - } else if f.pkg != nil { - writePackage(buf, f.pkg, qf) - } - } - buf.WriteString(f.name) -} diff --git a/third_party/forked/golang/go/types/objset.go b/third_party/forked/golang/go/types/objset.go deleted file mode 100644 index 55eb74addbae5..0000000000000 --- a/third_party/forked/golang/go/types/objset.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements objsets. -// -// An objset is similar to a Scope but objset elements -// are identified by their unique id, instead of their -// object name. - -package types - -// An objset is a set of objects identified by their unique id. -// The zero value for objset is a ready-to-use empty objset. -type objset map[string]Object // initialized lazily - -// insert attempts to insert an object obj into objset s. -// If s already contains an alternative object alt with -// the same name, insert leaves s unchanged and returns alt. -// Otherwise it inserts obj and returns nil. -func (s *objset) insert(obj Object) Object { - id := obj.Id() - if alt := (*s)[id]; alt != nil { - return alt - } - if *s == nil { - *s = make(map[string]Object) - } - (*s)[id] = obj - return nil -} diff --git a/third_party/forked/golang/go/types/operand.go b/third_party/forked/golang/go/types/operand.go deleted file mode 100644 index 07247bd6f5883..0000000000000 --- a/third_party/forked/golang/go/types/operand.go +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file defines operands and associated operations. - -package types - -import ( - "bytes" - "go/ast" - "go/constant" - "go/token" -) - -// An operandMode specifies the (addressing) mode of an operand. -type operandMode byte - -const ( - invalid operandMode = iota // operand is invalid - novalue // operand represents no value (result of a function call w/o result) - builtin // operand is a built-in function - typexpr // operand is a type - constant_ // operand is a constant; the operand's typ is a Basic type - variable // operand is an addressable variable - mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment) - value // operand is a computed value - commaok // like value, but operand may be used in a comma,ok expression -) - -var operandModeString = [...]string{ - invalid: "invalid operand", - novalue: "no value", - builtin: "built-in", - typexpr: "type", - constant_: "constant", - variable: "variable", - mapindex: "map index expression", - value: "value", - commaok: "comma, ok expression", -} - -// An operand represents an intermediate value during type checking. -// Operands have an (addressing) mode, the expression evaluating to -// the operand, the operand's type, a value for constants, and an id -// for built-in functions. -// The zero value of operand is a ready to use invalid operand. -// -type operand struct { - mode operandMode - expr ast.Expr - typ Type - val constant.Value - id builtinId -} - -// pos returns the position of the expression corresponding to x. -// If x is invalid the position is token.NoPos. -// -func (x *operand) pos() token.Pos { - // x.expr may not be set if x is invalid - if x.expr == nil { - return token.NoPos - } - return x.expr.Pos() -} - -// Operand string formats -// (not all "untyped" cases can appear due to the type system, -// but they fall out naturally here) -// -// mode format -// -// invalid ( ) -// novalue ( ) -// builtin ( ) -// typexpr ( ) -// -// constant ( ) -// constant ( of type ) -// constant ( ) -// constant ( of type ) -// -// variable ( ) -// variable ( of type ) -// -// mapindex ( ) -// mapindex ( of type ) -// -// value ( ) -// value ( of type ) -// -// commaok ( ) -// commaok ( of type ) -// -func operandString(x *operand, qf Qualifier) string { - var buf bytes.Buffer - - var expr string - if x.expr != nil { - expr = ExprString(x.expr) - } else { - switch x.mode { - case builtin: - expr = predeclaredFuncs[x.id].name - case typexpr: - expr = TypeString(x.typ, qf) - case constant_: - expr = x.val.String() - } - } - - // ( - if expr != "" { - buf.WriteString(expr) - buf.WriteString(" (") - } - - // - hasType := false - switch x.mode { - case invalid, novalue, builtin, typexpr: - // no type - default: - // should have a type, but be cautious (don't crash during printing) - if x.typ != nil { - if isUntyped(x.typ) { - buf.WriteString(x.typ.(*Basic).name) - buf.WriteByte(' ') - break - } - hasType = true - } - } - - // - buf.WriteString(operandModeString[x.mode]) - - // - if x.mode == constant_ { - if s := x.val.String(); s != expr { - buf.WriteByte(' ') - buf.WriteString(s) - } - } - - // - if hasType { - if x.typ != Typ[Invalid] { - buf.WriteString(" of type ") - WriteType(&buf, x.typ, qf) - } else { - buf.WriteString(" with invalid type") - } - } - - // ) - if expr != "" { - buf.WriteByte(')') - } - - return buf.String() -} - -func (x *operand) String() string { - return operandString(x, nil) -} - -// setConst sets x to the untyped constant for literal lit. -func (x *operand) setConst(tok token.Token, lit string) { - var kind BasicKind - switch tok { - case token.INT: - kind = UntypedInt - case token.FLOAT: - kind = UntypedFloat - case token.IMAG: - kind = UntypedComplex - case token.CHAR: - kind = UntypedRune - case token.STRING: - kind = UntypedString - default: - unreachable() - } - - x.mode = constant_ - x.typ = Typ[kind] - x.val = constant.MakeFromLiteral(lit, tok, 0) -} - -// isNil reports whether x is the nil value. -func (x *operand) isNil() bool { - return x.mode == value && x.typ == Typ[UntypedNil] -} - -// TODO(gri) The functions operand.assignableTo, checker.convertUntyped, -// checker.representable, and checker.assignment are -// overlapping in functionality. Need to simplify and clean up. - -// assignableTo reports whether x is assignable to a variable of type T. -// If the result is false and a non-nil reason is provided, it may be set -// to a more detailed explanation of the failure (result != ""). -func (x *operand) assignableTo(conf *Config, T Type, reason *string) bool { - if x.mode == invalid || T == Typ[Invalid] { - return true // avoid spurious errors - } - - V := x.typ - - // x's type is identical to T - if Identical(V, T) { - return true - } - - Vu := V.Underlying() - Tu := T.Underlying() - - // x is an untyped value representable by a value of type T - // TODO(gri) This is borrowing from checker.convertUntyped and - // checker.representable. Need to clean up. - if isUntyped(Vu) { - switch t := Tu.(type) { - case *Basic: - if x.isNil() && t.kind == UnsafePointer { - return true - } - if x.mode == constant_ { - return representableConst(x.val, conf, t, nil) - } - // The result of a comparison is an untyped boolean, - // but may not be a constant. - if Vb, _ := Vu.(*Basic); Vb != nil { - return Vb.kind == UntypedBool && isBoolean(Tu) - } - case *Interface: - return x.isNil() || t.Empty() - case *Pointer, *Signature, *Slice, *Map, *Chan: - return x.isNil() - } - } - // Vu is typed - - // x's type V and T have identical underlying types - // and at least one of V or T is not a named type - if Identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) { - return true - } - - // T is an interface type and x implements T - if Ti, ok := Tu.(*Interface); ok { - if m, wrongType := MissingMethod(x.typ, Ti, true); m != nil /* Implements(x.typ, Ti) */ { - if reason != nil { - if wrongType { - *reason = "wrong type for method " + m.Name() - } else { - *reason = "missing method " + m.Name() - } - } - return false - } - return true - } - - // x is a bidirectional channel value, T is a channel - // type, x's type V and T have identical element types, - // and at least one of V or T is not a named type - if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv { - if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) { - return !isNamed(V) || !isNamed(T) - } - } - - return false -} diff --git a/third_party/forked/golang/go/types/ordering.go b/third_party/forked/golang/go/types/ordering.go deleted file mode 100644 index 3579abf7d7bb4..0000000000000 --- a/third_party/forked/golang/go/types/ordering.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements resolveOrder. - -package types - -import ( - "go/ast" - "sort" -) - -// resolveOrder computes the order in which package-level objects -// must be type-checked. -// -// Interface types appear first in the list, sorted topologically -// by dependencies on embedded interfaces that are also declared -// in this package, followed by all other objects sorted in source -// order. -// -// TODO(gri) Consider sorting all types by dependencies here, and -// in the process check _and_ report type cycles. This may simplify -// the full type-checking phase. -// -func (check *Checker) resolveOrder() []Object { - var ifaces, others []Object - - // collect interface types with their dependencies, and all other objects - for obj := range check.objMap { - if ityp := check.interfaceFor(obj); ityp != nil { - ifaces = append(ifaces, obj) - // determine dependencies on embedded interfaces - for _, f := range ityp.Methods.List { - if len(f.Names) == 0 { - // Embedded interface: The type must be a (possibly - // qualified) identifier denoting another interface. - // Imported interfaces are already fully resolved, - // so we can ignore qualified identifiers. - if ident, _ := f.Type.(*ast.Ident); ident != nil { - embedded := check.pkg.scope.Lookup(ident.Name) - if check.interfaceFor(embedded) != nil { - check.objMap[obj].addDep(embedded) - } - } - } - } - } else { - others = append(others, obj) - } - } - - // final object order - var order []Object - - // sort interface types topologically by dependencies, - // and in source order if there are no dependencies - sort.Sort(inSourceOrder(ifaces)) - visited := make(objSet) - for _, obj := range ifaces { - check.appendInPostOrder(&order, obj, visited) - } - - // sort everything else in source order - sort.Sort(inSourceOrder(others)) - - return append(order, others...) -} - -// interfaceFor returns the AST interface denoted by obj, or nil. -func (check *Checker) interfaceFor(obj Object) *ast.InterfaceType { - tname, _ := obj.(*TypeName) - if tname == nil { - return nil // not a type - } - d := check.objMap[obj] - if d == nil { - check.dump("%s: %s should have been declared", obj.Pos(), obj.Name()) - unreachable() - } - if d.typ == nil { - return nil // invalid AST - ignore (will be handled later) - } - ityp, _ := d.typ.(*ast.InterfaceType) - return ityp -} - -func (check *Checker) appendInPostOrder(order *[]Object, obj Object, visited objSet) { - if visited[obj] { - // We've already seen this object; either because it's - // already added to order, or because we have a cycle. - // In both cases we stop. Cycle errors are reported - // when type-checking types. - return - } - visited[obj] = true - - d := check.objMap[obj] - for _, obj := range orderedSetObjects(d.deps) { - check.appendInPostOrder(order, obj, visited) - } - - *order = append(*order, obj) -} - -func orderedSetObjects(set objSet) []Object { - list := make([]Object, len(set)) - i := 0 - for obj := range set { - // we don't care about the map element value - list[i] = obj - i++ - } - sort.Sort(inSourceOrder(list)) - return list -} - -// inSourceOrder implements the sort.Sort interface. -type inSourceOrder []Object - -func (a inSourceOrder) Len() int { return len(a) } -func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() } -func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] } diff --git a/third_party/forked/golang/go/types/package.go b/third_party/forked/golang/go/types/package.go deleted file mode 100644 index cd202a0ed9f78..0000000000000 --- a/third_party/forked/golang/go/types/package.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -import ( - "fmt" - "go/token" -) - -// A Package describes a Go package. -type Package struct { - path string - name string - scope *Scope - complete bool - imports []*Package - fake bool // scope lookup errors are silently dropped if package is fake (internal use only) -} - -// NewPackage returns a new Package for the given package path and name. -// The package is not complete and contains no explicit imports. -func NewPackage(path, name string) *Package { - scope := NewScope(Universe, token.NoPos, token.NoPos, fmt.Sprintf("package %q", path)) - return &Package{path: path, name: name, scope: scope} -} - -// Path returns the package path. -func (pkg *Package) Path() string { return pkg.path } - -// Name returns the package name. -func (pkg *Package) Name() string { return pkg.name } - -// SetName sets the package name. -func (pkg *Package) SetName(name string) { pkg.name = name } - -// Scope returns the (complete or incomplete) package scope -// holding the objects declared at package level (TypeNames, -// Consts, Vars, and Funcs). -func (pkg *Package) Scope() *Scope { return pkg.scope } - -// A package is complete if its scope contains (at least) all -// exported objects; otherwise it is incomplete. -func (pkg *Package) Complete() bool { return pkg.complete } - -// MarkComplete marks a package as complete. -func (pkg *Package) MarkComplete() { pkg.complete = true } - -// Imports returns the list of packages directly imported by -// pkg; the list is in source order. -// -// If pkg was loaded from export data, Imports includes packages that -// provide package-level objects referenced by pkg. This may be more or -// less than the set of packages directly imported by pkg's source code. -func (pkg *Package) Imports() []*Package { return pkg.imports } - -// SetImports sets the list of explicitly imported packages to list. -// It is the caller's responsibility to make sure list elements are unique. -func (pkg *Package) SetImports(list []*Package) { pkg.imports = list } - -func (pkg *Package) String() string { - return fmt.Sprintf("package %s (%q)", pkg.name, pkg.path) -} diff --git a/third_party/forked/golang/go/types/predicates.go b/third_party/forked/golang/go/types/predicates.go deleted file mode 100644 index 1ca146f59049b..0000000000000 --- a/third_party/forked/golang/go/types/predicates.go +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements commonly used type predicates. - -package types - -import "sort" - -func isNamed(typ Type) bool { - if _, ok := typ.(*Basic); ok { - return ok - } - _, ok := typ.(*Named) - return ok -} - -func isBoolean(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsBoolean != 0 -} - -func isInteger(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsInteger != 0 -} - -func isUnsigned(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsUnsigned != 0 -} - -func isFloat(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsFloat != 0 -} - -func isComplex(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsComplex != 0 -} - -func isNumeric(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsNumeric != 0 -} - -func isString(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsString != 0 -} - -func isTyped(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return !ok || t.info&IsUntyped == 0 -} - -func isUntyped(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsUntyped != 0 -} - -func isOrdered(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsOrdered != 0 -} - -func isConstType(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsConstType != 0 -} - -// IsInterface reports whether typ is an interface type. -func IsInterface(typ Type) bool { - _, ok := typ.Underlying().(*Interface) - return ok -} - -// Comparable reports whether values of type T are comparable. -func Comparable(T Type) bool { - switch t := T.Underlying().(type) { - case *Basic: - // assume invalid types to be comparable - // to avoid follow-up errors - return t.kind != UntypedNil - case *Pointer, *Interface, *Chan: - return true - case *Struct: - for _, f := range t.fields { - if !Comparable(f.typ) { - return false - } - } - return true - case *Array: - return Comparable(t.elem) - } - return false -} - -// hasNil reports whether a type includes the nil value. -func hasNil(typ Type) bool { - switch t := typ.Underlying().(type) { - case *Basic: - return t.kind == UnsafePointer - case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan: - return true - } - return false -} - -// Identical reports whether x and y are identical types. -// Receivers of Signature types are ignored. -func Identical(x, y Type) bool { - return identical(x, y, true, nil) -} - -// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored. -// Receivers of Signature types are ignored. -func IdenticalIgnoreTags(x, y Type) bool { - return identical(x, y, false, nil) -} - -// An ifacePair is a node in a stack of interface type pairs compared for identity. -type ifacePair struct { - x, y *Interface - prev *ifacePair -} - -func (p *ifacePair) identical(q *ifacePair) bool { - return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x -} - -func identical(x, y Type, cmpTags bool, p *ifacePair) bool { - if x == y { - return true - } - - switch x := x.(type) { - case *Basic: - // Basic types are singletons except for the rune and byte - // aliases, thus we cannot solely rely on the x == y check - // above. See also comment in TypeName.IsAlias. - if y, ok := y.(*Basic); ok { - return x.kind == y.kind - } - - case *Array: - // Two array types are identical if they have identical element types - // and the same array length. - if y, ok := y.(*Array); ok { - // If one or both array lengths are unknown (< 0) due to some error, - // assume they are the same to avoid spurious follow-on errors. - return (x.len < 0 || y.len < 0 || x.len == y.len) && identical(x.elem, y.elem, cmpTags, p) - } - - case *Slice: - // Two slice types are identical if they have identical element types. - if y, ok := y.(*Slice); ok { - return identical(x.elem, y.elem, cmpTags, p) - } - - case *Struct: - // Two struct types are identical if they have the same sequence of fields, - // and if corresponding fields have the same names, and identical types, - // and identical tags. Two anonymous fields are considered to have the same - // name. Lower-case field names from different packages are always different. - if y, ok := y.(*Struct); ok { - if x.NumFields() == y.NumFields() { - for i, f := range x.fields { - g := y.fields[i] - if f.anonymous != g.anonymous || - cmpTags && x.Tag(i) != y.Tag(i) || - !f.sameId(g.pkg, g.name) || - !identical(f.typ, g.typ, cmpTags, p) { - return false - } - } - return true - } - } - - case *Pointer: - // Two pointer types are identical if they have identical base types. - if y, ok := y.(*Pointer); ok { - return identical(x.base, y.base, cmpTags, p) - } - - case *Tuple: - // Two tuples types are identical if they have the same number of elements - // and corresponding elements have identical types. - if y, ok := y.(*Tuple); ok { - if x.Len() == y.Len() { - if x != nil { - for i, v := range x.vars { - w := y.vars[i] - if !identical(v.typ, w.typ, cmpTags, p) { - return false - } - } - } - return true - } - } - - case *Signature: - // Two function types are identical if they have the same number of parameters - // and result values, corresponding parameter and result types are identical, - // and either both functions are variadic or neither is. Parameter and result - // names are not required to match. - if y, ok := y.(*Signature); ok { - return x.variadic == y.variadic && - identical(x.params, y.params, cmpTags, p) && - identical(x.results, y.results, cmpTags, p) - } - - case *Interface: - // Two interface types are identical if they have the same set of methods with - // the same names and identical function types. Lower-case method names from - // different packages are always different. The order of the methods is irrelevant. - if y, ok := y.(*Interface); ok { - a := x.allMethods - b := y.allMethods - if len(a) == len(b) { - // Interface types are the only types where cycles can occur - // that are not "terminated" via named types; and such cycles - // can only be created via method parameter types that are - // anonymous interfaces (directly or indirectly) embedding - // the current interface. Example: - // - // type T interface { - // m() interface{T} - // } - // - // If two such (differently named) interfaces are compared, - // endless recursion occurs if the cycle is not detected. - // - // If x and y were compared before, they must be equal - // (if they were not, the recursion would have stopped); - // search the ifacePair stack for the same pair. - // - // This is a quadratic algorithm, but in practice these stacks - // are extremely short (bounded by the nesting depth of interface - // type declarations that recur via parameter types, an extremely - // rare occurrence). An alternative implementation might use a - // "visited" map, but that is probably less efficient overall. - q := &ifacePair{x, y, p} - for p != nil { - if p.identical(q) { - return true // same pair was compared before - } - p = p.prev - } - if debug { - assert(sort.IsSorted(byUniqueMethodName(a))) - assert(sort.IsSorted(byUniqueMethodName(b))) - } - for i, f := range a { - g := b[i] - if f.Id() != g.Id() || !identical(f.typ, g.typ, cmpTags, q) { - return false - } - } - return true - } - } - - case *Map: - // Two map types are identical if they have identical key and value types. - if y, ok := y.(*Map); ok { - return identical(x.key, y.key, cmpTags, p) && identical(x.elem, y.elem, cmpTags, p) - } - - case *Chan: - // Two channel types are identical if they have identical value types - // and the same direction. - if y, ok := y.(*Chan); ok { - return x.dir == y.dir && identical(x.elem, y.elem, cmpTags, p) - } - - case *Named: - // Two named types are identical if their type names originate - // in the same type declaration. - if y, ok := y.(*Named); ok { - return x.obj == y.obj - } - - case nil: - - default: - unreachable() - } - - return false -} - -// Default returns the default "typed" type for an "untyped" type; -// it returns the incoming type for all other types. The default type -// for untyped nil is untyped nil. -// -func Default(typ Type) Type { - if t, ok := typ.(*Basic); ok { - switch t.kind { - case UntypedBool: - return Typ[Bool] - case UntypedInt: - return Typ[Int] - case UntypedRune: - return universeRune // use 'rune' name - case UntypedFloat: - return Typ[Float64] - case UntypedComplex: - return Typ[Complex128] - case UntypedString: - return Typ[String] - } - } - return typ -} diff --git a/third_party/forked/golang/go/types/resolver.go b/third_party/forked/golang/go/types/resolver.go deleted file mode 100644 index d03c1799af939..0000000000000 --- a/third_party/forked/golang/go/types/resolver.go +++ /dev/null @@ -1,542 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "strconv" - "strings" - "unicode" -) - -// A declInfo describes a package-level const, type, var, or func declaration. -type declInfo struct { - file *Scope // scope of file containing this declaration - lhs []*Var // lhs of n:1 variable declarations, or nil - typ ast.Expr // type, or nil - init ast.Expr // init/orig expression, or nil - fdecl *ast.FuncDecl // func declaration, or nil - alias bool // type alias declaration - - // The deps field tracks initialization expression dependencies. - // As a special (overloaded) case, it also tracks dependencies of - // interface types on embedded interfaces (see ordering.go). - deps objSet // lazily initialized -} - -// An objSet is simply a set of objects. -type objSet map[Object]bool - -// hasInitializer reports whether the declared object has an initialization -// expression or function body. -func (d *declInfo) hasInitializer() bool { - return d.init != nil || d.fdecl != nil && d.fdecl.Body != nil -} - -// addDep adds obj to the set of objects d's init expression depends on. -func (d *declInfo) addDep(obj Object) { - m := d.deps - if m == nil { - m = make(objSet) - d.deps = m - } - m[obj] = true -} - -// arityMatch checks that the lhs and rhs of a const or var decl -// have the appropriate number of names and init exprs. For const -// decls, init is the value spec providing the init exprs; for -// var decls, init is nil (the init exprs are in s in this case). -func (check *Checker) arityMatch(s, init *ast.ValueSpec) { - l := len(s.Names) - r := len(s.Values) - if init != nil { - r = len(init.Values) - } - - switch { - case init == nil && r == 0: - // var decl w/o init expr - if s.Type == nil { - check.errorf(s.Pos(), "missing type or init expr") - } - case l < r: - if l < len(s.Values) { - // init exprs from s - n := s.Values[l] - check.errorf(n.Pos(), "extra init expr %s", n) - // TODO(gri) avoid declared but not used error here - } else { - // init exprs "inherited" - check.errorf(s.Pos(), "extra init expr at %s", check.fset.Position(init.Pos())) - // TODO(gri) avoid declared but not used error here - } - case l > r && (init != nil || r != 1): - n := s.Names[r] - check.errorf(n.Pos(), "missing init expr for %s", n) - } -} - -func validatedImportPath(path string) (string, error) { - s, err := strconv.Unquote(path) - if err != nil { - return "", err - } - if s == "" { - return "", fmt.Errorf("empty string") - } - const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" - for _, r := range s { - if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { - return s, fmt.Errorf("invalid character %#U", r) - } - } - return s, nil -} - -// declarePkgObj declares obj in the package scope, records its ident -> obj mapping, -// and updates check.objMap. The object must not be a function or method. -func (check *Checker) declarePkgObj(ident *ast.Ident, obj Object, d *declInfo) { - assert(ident.Name == obj.Name()) - - // spec: "A package-scope or file-scope identifier with name init - // may only be declared to be a function with this (func()) signature." - if ident.Name == "init" { - check.errorf(ident.Pos(), "cannot declare init - must be func") - return - } - - // spec: "The main package must have package name main and declare - // a function main that takes no arguments and returns no value." - if ident.Name == "main" && check.pkg.name == "main" { - check.errorf(ident.Pos(), "cannot declare main - must be func") - return - } - - check.declare(check.pkg.scope, ident, obj, token.NoPos) - check.objMap[obj] = d - obj.setOrder(uint32(len(check.objMap))) -} - -// filename returns a filename suitable for debugging output. -func (check *Checker) filename(fileNo int) string { - file := check.files[fileNo] - if pos := file.Pos(); pos.IsValid() { - return check.fset.File(pos).Name() - } - return fmt.Sprintf("file[%d]", fileNo) -} - -func (check *Checker) importPackage(pos token.Pos, path, dir string) *Package { - // If we already have a package for the given (path, dir) - // pair, use it instead of doing a full import. - // Checker.impMap only caches packages that are marked Complete - // or fake (dummy packages for failed imports). Incomplete but - // non-fake packages do require an import to complete them. - key := importKey{path, dir} - imp := check.impMap[key] - if imp != nil { - return imp - } - - // no package yet => import it - if path == "C" && check.conf.FakeImportC { - imp = NewPackage("C", "C") - imp.fake = true - } else { - // ordinary import - var err error - if importer := check.conf.Importer; importer == nil { - err = fmt.Errorf("Config.Importer not installed") - } else if importerFrom, ok := importer.(ImporterFrom); ok { - imp, err = importerFrom.ImportFrom(path, dir, 0) - if imp == nil && err == nil { - err = fmt.Errorf("Config.Importer.ImportFrom(%s, %s, 0) returned nil but no error", path, dir) - } - } else { - imp, err = importer.Import(path) - if imp == nil && err == nil { - err = fmt.Errorf("Config.Importer.Import(%s) returned nil but no error", path) - } - } - // make sure we have a valid package name - // (errors here can only happen through manipulation of packages after creation) - if err == nil && imp != nil && (imp.name == "_" || imp.name == "") { - err = fmt.Errorf("invalid package name: %q", imp.name) - imp = nil // create fake package below - } - if err != nil { - check.errorf(pos, "could not import %s (%s)", path, err) - if imp == nil { - // create a new fake package - // come up with a sensible package name (heuristic) - name := path - if i := len(name); i > 0 && name[i-1] == '/' { - name = name[:i-1] - } - if i := strings.LastIndex(name, "/"); i >= 0 { - name = name[i+1:] - } - imp = NewPackage(path, name) - } - // continue to use the package as best as we can - imp.fake = true // avoid follow-up lookup failures - } - } - - // package should be complete or marked fake, but be cautious - if imp.complete || imp.fake { - check.impMap[key] = imp - return imp - } - - // something went wrong (importer may have returned incomplete package without error) - return nil -} - -// collectObjects collects all file and package objects and inserts them -// into their respective scopes. It also performs imports and associates -// methods with receiver base type names. -func (check *Checker) collectObjects() { - pkg := check.pkg - - // pkgImports is the set of packages already imported by any package file seen - // so far. Used to avoid duplicate entries in pkg.imports. Allocate and populate - // it (pkg.imports may not be empty if we are checking test files incrementally). - // Note that pkgImports is keyed by package (and thus package path), not by an - // importKey value. Two different importKey values may map to the same package - // which is why we cannot use the check.impMap here. - var pkgImports = make(map[*Package]bool) - for _, imp := range pkg.imports { - pkgImports[imp] = true - } - - for fileNo, file := range check.files { - // The package identifier denotes the current package, - // but there is no corresponding package object. - check.recordDef(file.Name, nil) - - // Use the actual source file extent rather than *ast.File extent since the - // latter doesn't include comments which appear at the start or end of the file. - // Be conservative and use the *ast.File extent if we don't have a *token.File. - pos, end := file.Pos(), file.End() - if f := check.fset.File(file.Pos()); f != nil { - pos, end = token.Pos(f.Base()), token.Pos(f.Base()+f.Size()) - } - fileScope := NewScope(check.pkg.scope, pos, end, check.filename(fileNo)) - check.recordScope(file, fileScope) - - // determine file directory, necessary to resolve imports - // FileName may be "" (typically for tests) in which case - // we get "." as the directory which is what we would want. - fileDir := dir(check.fset.Position(file.Name.Pos()).Filename) - - for _, decl := range file.Decls { - switch d := decl.(type) { - case *ast.BadDecl: - // ignore - - case *ast.GenDecl: - var last *ast.ValueSpec // last ValueSpec with type or init exprs seen - for iota, spec := range d.Specs { - switch s := spec.(type) { - case *ast.ImportSpec: - // import package - path, err := validatedImportPath(s.Path.Value) - if err != nil { - check.errorf(s.Path.Pos(), "invalid import path (%s)", err) - continue - } - - imp := check.importPackage(s.Path.Pos(), path, fileDir) - if imp == nil { - continue - } - - // add package to list of explicit imports - // (this functionality is provided as a convenience - // for clients; it is not needed for type-checking) - if !pkgImports[imp] { - pkgImports[imp] = true - pkg.imports = append(pkg.imports, imp) - } - - // local name overrides imported package name - name := imp.name - if s.Name != nil { - name = s.Name.Name - if path == "C" { - // match cmd/compile (not prescribed by spec) - check.errorf(s.Name.Pos(), `cannot rename import "C"`) - continue - } - if name == "init" { - check.errorf(s.Name.Pos(), "cannot declare init - must be func") - continue - } - } - - obj := NewPkgName(s.Pos(), pkg, name, imp) - if s.Name != nil { - // in a dot-import, the dot represents the package - check.recordDef(s.Name, obj) - } else { - check.recordImplicit(s, obj) - } - - if path == "C" { - // match cmd/compile (not prescribed by spec) - obj.used = true - } - - // add import to file scope - if name == "." { - // merge imported scope with file scope - for _, obj := range imp.scope.elems { - // A package scope may contain non-exported objects, - // do not import them! - if obj.Exported() { - // TODO(gri) When we import a package, we create - // a new local package object. We should do the - // same for each dot-imported object. That way - // they can have correct position information. - // (We must not modify their existing position - // information because the same package - found - // via Config.Packages - may be dot-imported in - // another package!) - check.declare(fileScope, nil, obj, token.NoPos) - } - } - // add position to set of dot-import positions for this file - // (this is only needed for "imported but not used" errors) - check.addUnusedDotImport(fileScope, imp, s.Pos()) - } else { - // declare imported package object in file scope - check.declare(fileScope, nil, obj, token.NoPos) - } - - case *ast.ValueSpec: - switch d.Tok { - case token.CONST: - // determine which initialization expressions to use - switch { - case s.Type != nil || len(s.Values) > 0: - last = s - case last == nil: - last = new(ast.ValueSpec) // make sure last exists - } - - // declare all constants - for i, name := range s.Names { - obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) - - var init ast.Expr - if i < len(last.Values) { - init = last.Values[i] - } - - d := &declInfo{file: fileScope, typ: last.Type, init: init} - check.declarePkgObj(name, obj, d) - } - - check.arityMatch(s, last) - - case token.VAR: - lhs := make([]*Var, len(s.Names)) - // If there's exactly one rhs initializer, use - // the same declInfo d1 for all lhs variables - // so that each lhs variable depends on the same - // rhs initializer (n:1 var declaration). - var d1 *declInfo - if len(s.Values) == 1 { - // The lhs elements are only set up after the for loop below, - // but that's ok because declareVar only collects the declInfo - // for a later phase. - d1 = &declInfo{file: fileScope, lhs: lhs, typ: s.Type, init: s.Values[0]} - } - - // declare all variables - for i, name := range s.Names { - obj := NewVar(name.Pos(), pkg, name.Name, nil) - lhs[i] = obj - - d := d1 - if d == nil { - // individual assignments - var init ast.Expr - if i < len(s.Values) { - init = s.Values[i] - } - d = &declInfo{file: fileScope, typ: s.Type, init: init} - } - - check.declarePkgObj(name, obj, d) - } - - check.arityMatch(s, nil) - - default: - check.invalidAST(s.Pos(), "invalid token %s", d.Tok) - } - - case *ast.TypeSpec: - obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) - check.declarePkgObj(s.Name, obj, &declInfo{file: fileScope, typ: s.Type, alias: s.Assign.IsValid()}) - - default: - check.invalidAST(s.Pos(), "unknown ast.Spec node %T", s) - } - } - - case *ast.FuncDecl: - name := d.Name.Name - obj := NewFunc(d.Name.Pos(), pkg, name, nil) - if d.Recv == nil { - // regular function - if name == "init" { - // don't declare init functions in the package scope - they are invisible - obj.parent = pkg.scope - check.recordDef(d.Name, obj) - // init functions must have a body - if d.Body == nil { - check.softErrorf(obj.pos, "missing function body") - } - } else { - check.declare(pkg.scope, d.Name, obj, token.NoPos) - } - } else { - // method - check.recordDef(d.Name, obj) - // Associate method with receiver base type name, if possible. - // Ignore methods that have an invalid receiver, or a blank _ - // receiver name. They will be type-checked later, with regular - // functions. - if list := d.Recv.List; len(list) > 0 { - typ := unparen(list[0].Type) - if ptr, _ := typ.(*ast.StarExpr); ptr != nil { - typ = unparen(ptr.X) - } - if base, _ := typ.(*ast.Ident); base != nil && base.Name != "_" { - check.assocMethod(base.Name, obj) - } - } - } - info := &declInfo{file: fileScope, fdecl: d} - check.objMap[obj] = info - obj.setOrder(uint32(len(check.objMap))) - - default: - check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) - } - } - } - - // verify that objects in package and file scopes have different names - for _, scope := range check.pkg.scope.children /* file scopes */ { - for _, obj := range scope.elems { - if alt := pkg.scope.Lookup(obj.Name()); alt != nil { - if pkg, ok := obj.(*PkgName); ok { - check.errorf(alt.Pos(), "%s already declared through import of %s", alt.Name(), pkg.Imported()) - check.reportAltDecl(pkg) - } else { - check.errorf(alt.Pos(), "%s already declared through dot-import of %s", alt.Name(), obj.Pkg()) - // TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything - check.reportAltDecl(obj) - } - } - } - } -} - -// packageObjects typechecks all package objects in objList, but not function bodies. -func (check *Checker) packageObjects(objList []Object) { - // add new methods to already type-checked types (from a prior Checker.Files call) - for _, obj := range objList { - if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil { - check.addMethodDecls(obj) - } - } - - // pre-allocate space for type declaration paths so that the underlying array is reused - typePath := make([]*TypeName, 0, 8) - - for _, obj := range objList { - check.objDecl(obj, nil, typePath) - } - - // At this point we may have a non-empty check.methods map; this means that not all - // entries were deleted at the end of typeDecl because the respective receiver base - // types were not found. In that case, an error was reported when declaring those - // methods. We can now safely discard this map. - check.methods = nil -} - -// functionBodies typechecks all function bodies. -func (check *Checker) functionBodies() { - for _, f := range check.funcs { - check.funcBody(f.decl, f.name, f.sig, f.body) - } -} - -// unusedImports checks for unused imports. -func (check *Checker) unusedImports() { - // if function bodies are not checked, packages' uses are likely missing - don't check - if check.conf.IgnoreFuncBodies { - return - } - - // spec: "It is illegal (...) to directly import a package without referring to - // any of its exported identifiers. To import a package solely for its side-effects - // (initialization), use the blank identifier as explicit package name." - - // check use of regular imported packages - for _, scope := range check.pkg.scope.children /* file scopes */ { - for _, obj := range scope.elems { - if obj, ok := obj.(*PkgName); ok { - // Unused "blank imports" are automatically ignored - // since _ identifiers are not entered into scopes. - if !obj.used { - path := obj.imported.path - base := pkgName(path) - if obj.name == base { - check.softErrorf(obj.pos, "%q imported but not used", path) - } else { - check.softErrorf(obj.pos, "%q imported but not used as %s", path, obj.name) - } - } - } - } - } - - // check use of dot-imported packages - for _, unusedDotImports := range check.unusedDotImports { - for pkg, pos := range unusedDotImports { - check.softErrorf(pos, "%q imported but not used", pkg.path) - } - } -} - -// pkgName returns the package name (last element) of an import path. -func pkgName(path string) string { - if i := strings.LastIndex(path, "/"); i >= 0 { - path = path[i+1:] - } - return path -} - -// dir makes a good-faith attempt to return the directory -// portion of path. If path is empty, the result is ".". -// (Per the go/build package dependency tests, we cannot import -// path/filepath and simply use filepath.Dir.) -func dir(path string) string { - if i := strings.LastIndexAny(path, `/\`); i > 0 { - return path[:i] - } - // i <= 0 - return "." -} diff --git a/third_party/forked/golang/go/types/return.go b/third_party/forked/golang/go/types/return.go deleted file mode 100644 index 0c1447f89b3d9..0000000000000 --- a/third_party/forked/golang/go/types/return.go +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements isTerminating. - -package types - -import ( - "go/ast" - "go/token" -) - -// isTerminating reports if s is a terminating statement. -// If s is labeled, label is the label name; otherwise s -// is "". -func (check *Checker) isTerminating(s ast.Stmt, label string) bool { - switch s := s.(type) { - default: - unreachable() - - case *ast.BadStmt, *ast.DeclStmt, *ast.EmptyStmt, *ast.SendStmt, - *ast.IncDecStmt, *ast.AssignStmt, *ast.GoStmt, *ast.DeferStmt, - *ast.RangeStmt: - // no chance - - case *ast.LabeledStmt: - return check.isTerminating(s.Stmt, s.Label.Name) - - case *ast.ExprStmt: - // the predeclared (possibly parenthesized) panic() function is terminating - if call, _ := unparen(s.X).(*ast.CallExpr); call != nil { - if id, _ := call.Fun.(*ast.Ident); id != nil { - if _, obj := check.scope.LookupParent(id.Name, token.NoPos); obj != nil { - if b, _ := obj.(*Builtin); b != nil && b.id == _Panic { - return true - } - } - } - } - - case *ast.ReturnStmt: - return true - - case *ast.BranchStmt: - if s.Tok == token.GOTO || s.Tok == token.FALLTHROUGH { - return true - } - - case *ast.BlockStmt: - return check.isTerminatingList(s.List, "") - - case *ast.IfStmt: - if s.Else != nil && - check.isTerminating(s.Body, "") && - check.isTerminating(s.Else, "") { - return true - } - - case *ast.SwitchStmt: - return check.isTerminatingSwitch(s.Body, label) - - case *ast.TypeSwitchStmt: - return check.isTerminatingSwitch(s.Body, label) - - case *ast.SelectStmt: - for _, s := range s.Body.List { - cc := s.(*ast.CommClause) - if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) { - return false - } - - } - return true - - case *ast.ForStmt: - if s.Cond == nil && !hasBreak(s.Body, label, true) { - return true - } - } - - return false -} - -func (check *Checker) isTerminatingList(list []ast.Stmt, label string) bool { - // trailing empty statements are permitted - skip them - for i := len(list) - 1; i >= 0; i-- { - if _, ok := list[i].(*ast.EmptyStmt); !ok { - return check.isTerminating(list[i], label) - } - } - return false // all statements are empty -} - -func (check *Checker) isTerminatingSwitch(body *ast.BlockStmt, label string) bool { - hasDefault := false - for _, s := range body.List { - cc := s.(*ast.CaseClause) - if cc.List == nil { - hasDefault = true - } - if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) { - return false - } - } - return hasDefault -} - -// TODO(gri) For nested breakable statements, the current implementation of hasBreak -// will traverse the same subtree repeatedly, once for each label. Replace -// with a single-pass label/break matching phase. - -// hasBreak reports if s is or contains a break statement -// referring to the label-ed statement or implicit-ly the -// closest outer breakable statement. -func hasBreak(s ast.Stmt, label string, implicit bool) bool { - switch s := s.(type) { - default: - unreachable() - - case *ast.BadStmt, *ast.DeclStmt, *ast.EmptyStmt, *ast.ExprStmt, - *ast.SendStmt, *ast.IncDecStmt, *ast.AssignStmt, *ast.GoStmt, - *ast.DeferStmt, *ast.ReturnStmt: - // no chance - - case *ast.LabeledStmt: - return hasBreak(s.Stmt, label, implicit) - - case *ast.BranchStmt: - if s.Tok == token.BREAK { - if s.Label == nil { - return implicit - } - if s.Label.Name == label { - return true - } - } - - case *ast.BlockStmt: - return hasBreakList(s.List, label, implicit) - - case *ast.IfStmt: - if hasBreak(s.Body, label, implicit) || - s.Else != nil && hasBreak(s.Else, label, implicit) { - return true - } - - case *ast.CaseClause: - return hasBreakList(s.Body, label, implicit) - - case *ast.SwitchStmt: - if label != "" && hasBreak(s.Body, label, false) { - return true - } - - case *ast.TypeSwitchStmt: - if label != "" && hasBreak(s.Body, label, false) { - return true - } - - case *ast.CommClause: - return hasBreakList(s.Body, label, implicit) - - case *ast.SelectStmt: - if label != "" && hasBreak(s.Body, label, false) { - return true - } - - case *ast.ForStmt: - if label != "" && hasBreak(s.Body, label, false) { - return true - } - - case *ast.RangeStmt: - if label != "" && hasBreak(s.Body, label, false) { - return true - } - } - - return false -} - -func hasBreakList(list []ast.Stmt, label string, implicit bool) bool { - for _, s := range list { - if hasBreak(s, label, implicit) { - return true - } - } - return false -} diff --git a/third_party/forked/golang/go/types/scope.go b/third_party/forked/golang/go/types/scope.go deleted file mode 100644 index 39e42d758add8..0000000000000 --- a/third_party/forked/golang/go/types/scope.go +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements Scopes. - -package types - -import ( - "bytes" - "fmt" - "go/token" - "io" - "sort" - "strings" -) - -// TODO(gri) Provide scopes with a name or other mechanism so that -// objects can use that information for better printing. - -// A Scope maintains a set of objects and links to its containing -// (parent) and contained (children) scopes. Objects may be inserted -// and looked up by name. The zero value for Scope is a ready-to-use -// empty scope. -type Scope struct { - parent *Scope - children []*Scope - elems map[string]Object // lazily allocated - pos, end token.Pos // scope extent; may be invalid - comment string // for debugging only - isFunc bool // set if this is a function scope (internal use only) -} - -// NewScope returns a new, empty scope contained in the given parent -// scope, if any. The comment is for debugging only. -func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope { - s := &Scope{parent, nil, nil, pos, end, comment, false} - // don't add children to Universe scope! - if parent != nil && parent != Universe { - parent.children = append(parent.children, s) - } - return s -} - -// Parent returns the scope's containing (parent) scope. -func (s *Scope) Parent() *Scope { return s.parent } - -// Len() returns the number of scope elements. -func (s *Scope) Len() int { return len(s.elems) } - -// Names returns the scope's element names in sorted order. -func (s *Scope) Names() []string { - names := make([]string, len(s.elems)) - i := 0 - for name := range s.elems { - names[i] = name - i++ - } - sort.Strings(names) - return names -} - -// NumChildren() returns the number of scopes nested in s. -func (s *Scope) NumChildren() int { return len(s.children) } - -// Child returns the i'th child scope for 0 <= i < NumChildren(). -func (s *Scope) Child(i int) *Scope { return s.children[i] } - -// Lookup returns the object in scope s with the given name if such an -// object exists; otherwise the result is nil. -func (s *Scope) Lookup(name string) Object { - return s.elems[name] -} - -// LookupParent follows the parent chain of scopes starting with s until -// it finds a scope where Lookup(name) returns a non-nil object, and then -// returns that scope and object. If a valid position pos is provided, -// only objects that were declared at or before pos are considered. -// If no such scope and object exists, the result is (nil, nil). -// -// Note that obj.Parent() may be different from the returned scope if the -// object was inserted into the scope and already had a parent at that -// time (see Insert, below). This can only happen for dot-imported objects -// whose scope is the scope of the package that exported them. -func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object) { - for ; s != nil; s = s.parent { - if obj := s.elems[name]; obj != nil && (!pos.IsValid() || obj.scopePos() <= pos) { - return s, obj - } - } - return nil, nil -} - -// Insert attempts to insert an object obj into scope s. -// If s already contains an alternative object alt with -// the same name, Insert leaves s unchanged and returns alt. -// Otherwise it inserts obj, sets the object's parent scope -// if not already set, and returns nil. -func (s *Scope) Insert(obj Object) Object { - name := obj.Name() - if alt := s.elems[name]; alt != nil { - return alt - } - if s.elems == nil { - s.elems = make(map[string]Object) - } - s.elems[name] = obj - if obj.Parent() == nil { - obj.setParent(s) - } - return nil -} - -// Pos and End describe the scope's source code extent [pos, end). -// The results are guaranteed to be valid only if the type-checked -// AST has complete position information. The extent is undefined -// for Universe and package scopes. -func (s *Scope) Pos() token.Pos { return s.pos } -func (s *Scope) End() token.Pos { return s.end } - -// Contains returns true if pos is within the scope's extent. -// The result is guaranteed to be valid only if the type-checked -// AST has complete position information. -func (s *Scope) Contains(pos token.Pos) bool { - return s.pos <= pos && pos < s.end -} - -// Innermost returns the innermost (child) scope containing -// pos. If pos is not within any scope, the result is nil. -// The result is also nil for the Universe scope. -// The result is guaranteed to be valid only if the type-checked -// AST has complete position information. -func (s *Scope) Innermost(pos token.Pos) *Scope { - // Package scopes do not have extents since they may be - // discontiguous, so iterate over the package's files. - if s.parent == Universe { - for _, s := range s.children { - if inner := s.Innermost(pos); inner != nil { - return inner - } - } - } - - if s.Contains(pos) { - for _, s := range s.children { - if s.Contains(pos) { - return s.Innermost(pos) - } - } - return s - } - return nil -} - -// WriteTo writes a string representation of the scope to w, -// with the scope elements sorted by name. -// The level of indentation is controlled by n >= 0, with -// n == 0 for no indentation. -// If recurse is set, it also writes nested (children) scopes. -func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) { - const ind = ". " - indn := strings.Repeat(ind, n) - - fmt.Fprintf(w, "%s%s scope %p {", indn, s.comment, s) - if len(s.elems) == 0 { - fmt.Fprintf(w, "}\n") - return - } - - fmt.Fprintln(w) - indn1 := indn + ind - for _, name := range s.Names() { - fmt.Fprintf(w, "%s%s\n", indn1, s.elems[name]) - } - - if recurse { - for _, s := range s.children { - fmt.Fprintln(w) - s.WriteTo(w, n+1, recurse) - } - } - - fmt.Fprintf(w, "%s}", indn) -} - -// String returns a string representation of the scope, for debugging. -func (s *Scope) String() string { - var buf bytes.Buffer - s.WriteTo(&buf, 0, false) - return buf.String() -} diff --git a/third_party/forked/golang/go/types/selection.go b/third_party/forked/golang/go/types/selection.go deleted file mode 100644 index 124e0d39f02b9..0000000000000 --- a/third_party/forked/golang/go/types/selection.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements Selections. - -package types - -import ( - "bytes" - "fmt" -) - -// SelectionKind describes the kind of a selector expression x.f -// (excluding qualified identifiers). -type SelectionKind int - -const ( - FieldVal SelectionKind = iota // x.f is a struct field selector - MethodVal // x.f is a method selector - MethodExpr // x.f is a method expression -) - -// A Selection describes a selector expression x.f. -// For the declarations: -// -// type T struct{ x int; E } -// type E struct{} -// func (e E) m() {} -// var p *T -// -// the following relations exist: -// -// Selector Kind Recv Obj Type Index Indirect -// -// p.x FieldVal T x int {0} true -// p.m MethodVal *T m func (e *T) m() {1, 0} true -// T.m MethodExpr T m func m(_ T) {1, 0} false -// -type Selection struct { - kind SelectionKind - recv Type // type of x - obj Object // object denoted by x.f - index []int // path from x to x.f - indirect bool // set if there was any pointer indirection on the path -} - -// Kind returns the selection kind. -func (s *Selection) Kind() SelectionKind { return s.kind } - -// Recv returns the type of x in x.f. -func (s *Selection) Recv() Type { return s.recv } - -// Obj returns the object denoted by x.f; a *Var for -// a field selection, and a *Func in all other cases. -func (s *Selection) Obj() Object { return s.obj } - -// Type returns the type of x.f, which may be different from the type of f. -// See Selection for more information. -func (s *Selection) Type() Type { - switch s.kind { - case MethodVal: - // The type of x.f is a method with its receiver type set - // to the type of x. - sig := *s.obj.(*Func).typ.(*Signature) - recv := *sig.recv - recv.typ = s.recv - sig.recv = &recv - return &sig - - case MethodExpr: - // The type of x.f is a function (without receiver) - // and an additional first argument with the same type as x. - // TODO(gri) Similar code is already in call.go - factor! - // TODO(gri) Compute this eagerly to avoid allocations. - sig := *s.obj.(*Func).typ.(*Signature) - arg0 := *sig.recv - sig.recv = nil - arg0.typ = s.recv - var params []*Var - if sig.params != nil { - params = sig.params.vars - } - sig.params = NewTuple(append([]*Var{&arg0}, params...)...) - return &sig - } - - // In all other cases, the type of x.f is the type of x. - return s.obj.Type() -} - -// Index describes the path from x to f in x.f. -// The last index entry is the field or method index of the type declaring f; -// either: -// -// 1) the list of declared methods of a named type; or -// 2) the list of methods of an interface type; or -// 3) the list of fields of a struct type. -// -// The earlier index entries are the indices of the embedded fields implicitly -// traversed to get from (the type of) x to f, starting at embedding depth 0. -func (s *Selection) Index() []int { return s.index } - -// Indirect reports whether any pointer indirection was required to get from -// x to f in x.f. -func (s *Selection) Indirect() bool { return s.indirect } - -func (s *Selection) String() string { return SelectionString(s, nil) } - -// SelectionString returns the string form of s. -// The Qualifier controls the printing of -// package-level objects, and may be nil. -// -// Examples: -// "field (T) f int" -// "method (T) f(X) Y" -// "method expr (T) f(X) Y" -// -func SelectionString(s *Selection, qf Qualifier) string { - var k string - switch s.kind { - case FieldVal: - k = "field " - case MethodVal: - k = "method " - case MethodExpr: - k = "method expr " - default: - unreachable() - } - var buf bytes.Buffer - buf.WriteString(k) - buf.WriteByte('(') - WriteType(&buf, s.Recv(), qf) - fmt.Fprintf(&buf, ") %s", s.obj.Name()) - if T := s.Type(); s.kind == FieldVal { - buf.WriteByte(' ') - WriteType(&buf, T, qf) - } else { - WriteSignature(&buf, T.(*Signature), qf) - } - return buf.String() -} diff --git a/third_party/forked/golang/go/types/sizes.go b/third_party/forked/golang/go/types/sizes.go deleted file mode 100644 index eb274799f42e9..0000000000000 --- a/third_party/forked/golang/go/types/sizes.go +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements Sizes. - -package types - -// Sizes defines the sizing functions for package unsafe. -type Sizes interface { - // Alignof returns the alignment of a variable of type T. - // Alignof must implement the alignment guarantees required by the spec. - Alignof(T Type) int64 - - // Offsetsof returns the offsets of the given struct fields, in bytes. - // Offsetsof must implement the offset guarantees required by the spec. - Offsetsof(fields []*Var) []int64 - - // Sizeof returns the size of a variable of type T. - // Sizeof must implement the size guarantees required by the spec. - Sizeof(T Type) int64 -} - -// StdSizes is a convenience type for creating commonly used Sizes. -// It makes the following simplifying assumptions: -// -// - The size of explicitly sized basic types (int16, etc.) is the -// specified size. -// - The size of strings and interfaces is 2*WordSize. -// - The size of slices is 3*WordSize. -// - The size of an array of n elements corresponds to the size of -// a struct of n consecutive fields of the array's element type. -// - The size of a struct is the offset of the last field plus that -// field's size. As with all element types, if the struct is used -// in an array its size must first be aligned to a multiple of the -// struct's alignment. -// - All other types have size WordSize. -// - Arrays and structs are aligned per spec definition; all other -// types are naturally aligned with a maximum alignment MaxAlign. -// -// *StdSizes implements Sizes. -// -type StdSizes struct { - WordSize int64 // word size in bytes - must be >= 4 (32bits) - MaxAlign int64 // maximum alignment in bytes - must be >= 1 -} - -func (s *StdSizes) Alignof(T Type) int64 { - // For arrays and structs, alignment is defined in terms - // of alignment of the elements and fields, respectively. - switch t := T.Underlying().(type) { - case *Array: - // spec: "For a variable x of array type: unsafe.Alignof(x) - // is the same as unsafe.Alignof(x[0]), but at least 1." - return s.Alignof(t.elem) - case *Struct: - // spec: "For a variable x of struct type: unsafe.Alignof(x) - // is the largest of the values unsafe.Alignof(x.f) for each - // field f of x, but at least 1." - max := int64(1) - for _, f := range t.fields { - if a := s.Alignof(f.typ); a > max { - max = a - } - } - return max - case *Slice, *Interface: - // Multiword data structures are effectively structs - // in which each element has size WordSize. - return s.WordSize - case *Basic: - // Strings are like slices and interfaces. - if t.Info()&IsString != 0 { - return s.WordSize - } - } - a := s.Sizeof(T) // may be 0 - // spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1." - if a < 1 { - return 1 - } - // complex{64,128} are aligned like [2]float{32,64}. - if isComplex(T) { - a /= 2 - } - if a > s.MaxAlign { - return s.MaxAlign - } - return a -} - -func (s *StdSizes) Offsetsof(fields []*Var) []int64 { - offsets := make([]int64, len(fields)) - var o int64 - for i, f := range fields { - a := s.Alignof(f.typ) - o = align(o, a) - offsets[i] = o - o += s.Sizeof(f.typ) - } - return offsets -} - -var basicSizes = [...]byte{ - Bool: 1, - Int8: 1, - Int16: 2, - Int32: 4, - Int64: 8, - Uint8: 1, - Uint16: 2, - Uint32: 4, - Uint64: 8, - Float32: 4, - Float64: 8, - Complex64: 8, - Complex128: 16, -} - -func (s *StdSizes) Sizeof(T Type) int64 { - switch t := T.Underlying().(type) { - case *Basic: - assert(isTyped(T)) - k := t.kind - if int(k) < len(basicSizes) { - if s := basicSizes[k]; s > 0 { - return int64(s) - } - } - if k == String { - return s.WordSize * 2 - } - case *Array: - n := t.len - if n <= 0 { - return 0 - } - // n > 0 - a := s.Alignof(t.elem) - z := s.Sizeof(t.elem) - return align(z, a)*(n-1) + z - case *Slice: - return s.WordSize * 3 - case *Struct: - n := t.NumFields() - if n == 0 { - return 0 - } - offsets := s.Offsetsof(t.fields) - return offsets[n-1] + s.Sizeof(t.fields[n-1].typ) - case *Interface: - return s.WordSize * 2 - } - return s.WordSize // catch-all -} - -// common architecture word sizes and alignments -var gcArchSizes = map[string]*StdSizes{ - "386": {4, 4}, - "arm": {4, 4}, - "arm64": {8, 8}, - "amd64": {8, 8}, - "amd64p32": {4, 8}, - "mips": {4, 4}, - "mipsle": {4, 4}, - "mips64": {8, 8}, - "mips64le": {8, 8}, - "ppc64": {8, 8}, - "ppc64le": {8, 8}, - "s390x": {8, 8}, - // When adding more architectures here, - // update the doc string of SizesFor below. -} - -// SizesFor returns the Sizes used by a compiler for an architecture. -// The result is nil if a compiler/architecture pair is not known. -// -// Supported architectures for compiler "gc": -// "386", "arm", "arm64", "amd64", "amd64p32", "mips", "mipsle", -// "mips64", "mips64le", "ppc64", "ppc64le", "s390x". -func SizesFor(compiler, arch string) Sizes { - if compiler != "gc" { - return nil - } - s, ok := gcArchSizes[arch] - if !ok { - return nil - } - return s -} - -// stdSizes is used if Config.Sizes == nil. -var stdSizes = SizesFor("gc", "amd64") - -func (conf *Config) alignof(T Type) int64 { - if s := conf.Sizes; s != nil { - if a := s.Alignof(T); a >= 1 { - return a - } - panic("Config.Sizes.Alignof returned an alignment < 1") - } - return stdSizes.Alignof(T) -} - -func (conf *Config) offsetsof(T *Struct) []int64 { - var offsets []int64 - if T.NumFields() > 0 { - // compute offsets on demand - if s := conf.Sizes; s != nil { - offsets = s.Offsetsof(T.fields) - // sanity checks - if len(offsets) != T.NumFields() { - panic("Config.Sizes.Offsetsof returned the wrong number of offsets") - } - for _, o := range offsets { - if o < 0 { - panic("Config.Sizes.Offsetsof returned an offset < 0") - } - } - } else { - offsets = stdSizes.Offsetsof(T.fields) - } - } - return offsets -} - -// offsetof returns the offset of the field specified via -// the index sequence relative to typ. All embedded fields -// must be structs (rather than pointer to structs). -func (conf *Config) offsetof(typ Type, index []int) int64 { - var o int64 - for _, i := range index { - s := typ.Underlying().(*Struct) - o += conf.offsetsof(s)[i] - typ = s.fields[i].typ - } - return o -} - -func (conf *Config) sizeof(T Type) int64 { - if s := conf.Sizes; s != nil { - if z := s.Sizeof(T); z >= 0 { - return z - } - panic("Config.Sizes.Sizeof returned a size < 0") - } - return stdSizes.Sizeof(T) -} - -// align returns the smallest y >= x such that y % a == 0. -func align(x, a int64) int64 { - y := x + a - 1 - return y - y%a -} diff --git a/third_party/forked/golang/go/types/stmt.go b/third_party/forked/golang/go/types/stmt.go deleted file mode 100644 index 5221bcc7c1288..0000000000000 --- a/third_party/forked/golang/go/types/stmt.go +++ /dev/null @@ -1,870 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements typechecking of statements. - -package types - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "sort" -) - -func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt) { - if trace { - if name == "" { - name = "" - } - fmt.Printf("--- %s: %s {\n", name, sig) - defer fmt.Println("--- ") - } - - // set function scope extent - sig.scope.pos = body.Pos() - sig.scope.end = body.End() - - // save/restore current context and setup function context - // (and use 0 indentation at function start) - defer func(ctxt context, indent int) { - check.context = ctxt - check.indent = indent - }(check.context, check.indent) - check.context = context{ - decl: decl, - scope: sig.scope, - sig: sig, - } - check.indent = 0 - - check.stmtList(0, body.List) - - if check.hasLabel { - check.labels(body) - } - - if sig.results.Len() > 0 && !check.isTerminating(body, "") { - check.error(body.Rbrace, "missing return") - } - - // spec: "Implementation restriction: A compiler may make it illegal to - // declare a variable inside a function body if the variable is never used." - // (One could check each scope after use, but that distributes this check - // over several places because CloseScope is not always called explicitly.) - check.usage(sig.scope) -} - -func (check *Checker) usage(scope *Scope) { - var unused []*Var - for _, elem := range scope.elems { - if v, _ := elem.(*Var); v != nil && !v.used { - unused = append(unused, v) - } - } - sort.Slice(unused, func(i, j int) bool { - return unused[i].pos < unused[j].pos - }) - for _, v := range unused { - check.softErrorf(v.pos, "%s declared but not used", v.name) - } - - for _, scope := range scope.children { - // Don't go inside closure scopes a second time; - // they are handled explicitly by funcBody. - if !scope.isFunc { - check.usage(scope) - } - } -} - -// stmtContext is a bitset describing which -// control-flow statements are permissible, -// and provides additional context information -// for better error messages. -type stmtContext uint - -const ( - // permissible control-flow statements - breakOk stmtContext = 1 << iota - continueOk - fallthroughOk - - // additional context information - finalSwitchCase -) - -func (check *Checker) simpleStmt(s ast.Stmt) { - if s != nil { - check.stmt(0, s) - } -} - -func trimTrailingEmptyStmts(list []ast.Stmt) []ast.Stmt { - for i := len(list); i > 0; i-- { - if _, ok := list[i-1].(*ast.EmptyStmt); !ok { - return list[:i] - } - } - return nil -} - -func (check *Checker) stmtList(ctxt stmtContext, list []ast.Stmt) { - ok := ctxt&fallthroughOk != 0 - inner := ctxt &^ fallthroughOk - list = trimTrailingEmptyStmts(list) // trailing empty statements are "invisible" to fallthrough analysis - for i, s := range list { - inner := inner - if ok && i+1 == len(list) { - inner |= fallthroughOk - } - check.stmt(inner, s) - } -} - -func (check *Checker) multipleDefaults(list []ast.Stmt) { - var first ast.Stmt - for _, s := range list { - var d ast.Stmt - switch c := s.(type) { - case *ast.CaseClause: - if len(c.List) == 0 { - d = s - } - case *ast.CommClause: - if c.Comm == nil { - d = s - } - default: - check.invalidAST(s.Pos(), "case/communication clause expected") - } - if d != nil { - if first != nil { - check.errorf(d.Pos(), "multiple defaults (first at %s)", check.fset.Position(first.Pos())) - } else { - first = d - } - } - } -} - -func (check *Checker) openScope(s ast.Stmt, comment string) { - scope := NewScope(check.scope, s.Pos(), s.End(), comment) - check.recordScope(s, scope) - check.scope = scope -} - -func (check *Checker) closeScope() { - check.scope = check.scope.Parent() -} - -func assignOp(op token.Token) token.Token { - // token_test.go verifies the token ordering this function relies on - if token.ADD_ASSIGN <= op && op <= token.AND_NOT_ASSIGN { - return op + (token.ADD - token.ADD_ASSIGN) - } - return token.ILLEGAL -} - -func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) { - var x operand - var msg string - switch check.rawExpr(&x, call, nil) { - case conversion: - msg = "requires function call, not conversion" - case expression: - msg = "discards result of" - case statement: - return - default: - unreachable() - } - check.errorf(x.pos(), "%s %s %s", keyword, msg, &x) -} - -// goVal returns the Go value for val, or nil. -func goVal(val constant.Value) interface{} { - // val should exist, but be conservative and check - if val == nil { - return nil - } - // Match implementation restriction of other compilers. - // gc only checks duplicates for integer, floating-point - // and string values, so only create Go values for these - // types. - switch val.Kind() { - case constant.Int: - if x, ok := constant.Int64Val(val); ok { - return x - } - if x, ok := constant.Uint64Val(val); ok { - return x - } - case constant.Float: - if x, ok := constant.Float64Val(val); ok { - return x - } - case constant.String: - return constant.StringVal(val) - } - return nil -} - -// A valueMap maps a case value (of a basic Go type) to a list of positions -// where the same case value appeared, together with the corresponding case -// types. -// Since two case values may have the same "underlying" value but different -// types we need to also check the value's types (e.g., byte(1) vs myByte(1)) -// when the switch expression is of interface type. -type ( - valueMap map[interface{}][]valueType // underlying Go value -> valueType - valueType struct { - pos token.Pos - typ Type - } -) - -func (check *Checker) caseValues(x *operand, values []ast.Expr, seen valueMap) { -L: - for _, e := range values { - var v operand - check.expr(&v, e) - if x.mode == invalid || v.mode == invalid { - continue L - } - check.convertUntyped(&v, x.typ) - if v.mode == invalid { - continue L - } - // Order matters: By comparing v against x, error positions are at the case values. - res := v // keep original v unchanged - check.comparison(&res, x, token.EQL) - if res.mode == invalid { - continue L - } - if v.mode != constant_ { - continue L // we're done - } - // look for duplicate values - if val := goVal(v.val); val != nil { - // look for duplicate types for a given value - // (quadratic algorithm, but these lists tend to be very short) - for _, vt := range seen[val] { - if Identical(v.typ, vt.typ) { - check.errorf(v.pos(), "duplicate case %s in expression switch", &v) - check.error(vt.pos, "\tprevious case") // secondary error, \t indented - continue L - } - } - seen[val] = append(seen[val], valueType{v.pos(), v.typ}) - } - } -} - -func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]token.Pos) (T Type) { -L: - for _, e := range types { - T = check.typOrNil(e) - if T == Typ[Invalid] { - continue L - } - // look for duplicate types - // (quadratic algorithm, but type switches tend to be reasonably small) - for t, pos := range seen { - if T == nil && t == nil || T != nil && t != nil && Identical(T, t) { - // talk about "case" rather than "type" because of nil case - Ts := "nil" - if T != nil { - Ts = T.String() - } - check.errorf(e.Pos(), "duplicate case %s in type switch", Ts) - check.error(pos, "\tprevious case") // secondary error, \t indented - continue L - } - } - seen[T] = e.Pos() - if T != nil { - check.typeAssertion(e.Pos(), x, xtyp, T) - } - } - return -} - -// stmt typechecks statement s. -func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { - // statements cannot use iota in general - // (constant declarations set it explicitly) - assert(check.iota == nil) - - // statements must end with the same top scope as they started with - if debug { - defer func(scope *Scope) { - // don't check if code is panicking - if p := recover(); p != nil { - panic(p) - } - assert(scope == check.scope) - }(check.scope) - } - - inner := ctxt &^ (fallthroughOk | finalSwitchCase) - switch s := s.(type) { - case *ast.BadStmt, *ast.EmptyStmt: - // ignore - - case *ast.DeclStmt: - check.declStmt(s.Decl) - - case *ast.LabeledStmt: - check.hasLabel = true - check.stmt(ctxt, s.Stmt) - - case *ast.ExprStmt: - // spec: "With the exception of specific built-in functions, - // function and method calls and receive operations can appear - // in statement context. Such statements may be parenthesized." - var x operand - kind := check.rawExpr(&x, s.X, nil) - var msg string - switch x.mode { - default: - if kind == statement { - return - } - msg = "is not used" - case builtin: - msg = "must be called" - case typexpr: - msg = "is not an expression" - } - check.errorf(x.pos(), "%s %s", &x, msg) - - case *ast.SendStmt: - var ch, x operand - check.expr(&ch, s.Chan) - check.expr(&x, s.Value) - if ch.mode == invalid || x.mode == invalid { - return - } - - tch, ok := ch.typ.Underlying().(*Chan) - if !ok { - check.invalidOp(s.Arrow, "cannot send to non-chan type %s", ch.typ) - return - } - - if tch.dir == RecvOnly { - check.invalidOp(s.Arrow, "cannot send to receive-only type %s", tch) - return - } - - check.assignment(&x, tch.elem, "send") - - case *ast.IncDecStmt: - var op token.Token - switch s.Tok { - case token.INC: - op = token.ADD - case token.DEC: - op = token.SUB - default: - check.invalidAST(s.TokPos, "unknown inc/dec operation %s", s.Tok) - return - } - - var x operand - check.expr(&x, s.X) - if x.mode == invalid { - return - } - if !isNumeric(x.typ) { - check.invalidOp(s.X.Pos(), "%s%s (non-numeric type %s)", s.X, s.Tok, x.typ) - return - } - - Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position - check.binary(&x, nil, s.X, Y, op) - if x.mode == invalid { - return - } - check.assignVar(s.X, &x) - - case *ast.AssignStmt: - switch s.Tok { - case token.ASSIGN, token.DEFINE: - if len(s.Lhs) == 0 { - check.invalidAST(s.Pos(), "missing lhs in assignment") - return - } - if s.Tok == token.DEFINE { - check.shortVarDecl(s.TokPos, s.Lhs, s.Rhs) - } else { - // regular assignment - check.assignVars(s.Lhs, s.Rhs) - } - - default: - // assignment operations - if len(s.Lhs) != 1 || len(s.Rhs) != 1 { - check.errorf(s.TokPos, "assignment operation %s requires single-valued expressions", s.Tok) - return - } - op := assignOp(s.Tok) - if op == token.ILLEGAL { - check.invalidAST(s.TokPos, "unknown assignment operation %s", s.Tok) - return - } - var x operand - check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op) - if x.mode == invalid { - return - } - check.assignVar(s.Lhs[0], &x) - } - - case *ast.GoStmt: - check.suspendedCall("go", s.Call) - - case *ast.DeferStmt: - check.suspendedCall("defer", s.Call) - - case *ast.ReturnStmt: - res := check.sig.results - if res.Len() > 0 { - // function returns results - // (if one, say the first, result parameter is named, all of them are named) - if len(s.Results) == 0 && res.vars[0].name != "" { - // spec: "Implementation restriction: A compiler may disallow an empty expression - // list in a "return" statement if a different entity (constant, type, or variable) - // with the same name as a result parameter is in scope at the place of the return." - for _, obj := range res.vars { - if _, alt := check.scope.LookupParent(obj.name, check.pos); alt != nil && alt != obj { - check.errorf(s.Pos(), "result parameter %s not in scope at return", obj.name) - check.errorf(alt.Pos(), "\tinner declaration of %s", obj) - // ok to continue - } - } - } else { - // return has results or result parameters are unnamed - check.initVars(res.vars, s.Results, s.Return) - } - } else if len(s.Results) > 0 { - check.error(s.Results[0].Pos(), "no result values expected") - check.use(s.Results...) - } - - case *ast.BranchStmt: - if s.Label != nil { - check.hasLabel = true - return // checked in 2nd pass (check.labels) - } - switch s.Tok { - case token.BREAK: - if ctxt&breakOk == 0 { - check.error(s.Pos(), "break not in for, switch, or select statement") - } - case token.CONTINUE: - if ctxt&continueOk == 0 { - check.error(s.Pos(), "continue not in for statement") - } - case token.FALLTHROUGH: - if ctxt&fallthroughOk == 0 { - msg := "fallthrough statement out of place" - if ctxt&finalSwitchCase != 0 { - msg = "cannot fallthrough final case in switch" - } - check.error(s.Pos(), msg) - } - default: - check.invalidAST(s.Pos(), "branch statement: %s", s.Tok) - } - - case *ast.BlockStmt: - check.openScope(s, "block") - defer check.closeScope() - - check.stmtList(inner, s.List) - - case *ast.IfStmt: - check.openScope(s, "if") - defer check.closeScope() - - check.simpleStmt(s.Init) - var x operand - check.expr(&x, s.Cond) - if x.mode != invalid && !isBoolean(x.typ) { - check.error(s.Cond.Pos(), "non-boolean condition in if statement") - } - check.stmt(inner, s.Body) - // The parser produces a correct AST but if it was modified - // elsewhere the else branch may be invalid. Check again. - switch s.Else.(type) { - case nil, *ast.BadStmt: - // valid or error already reported - case *ast.IfStmt, *ast.BlockStmt: - check.stmt(inner, s.Else) - default: - check.error(s.Else.Pos(), "invalid else branch in if statement") - } - - case *ast.SwitchStmt: - inner |= breakOk - check.openScope(s, "switch") - defer check.closeScope() - - check.simpleStmt(s.Init) - var x operand - if s.Tag != nil { - check.expr(&x, s.Tag) - // By checking assignment of x to an invisible temporary - // (as a compiler would), we get all the relevant checks. - check.assignment(&x, nil, "switch expression") - } else { - // spec: "A missing switch expression is - // equivalent to the boolean value true." - x.mode = constant_ - x.typ = Typ[Bool] - x.val = constant.MakeBool(true) - x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"} - } - - check.multipleDefaults(s.Body.List) - - seen := make(valueMap) // map of seen case values to positions and types - for i, c := range s.Body.List { - clause, _ := c.(*ast.CaseClause) - if clause == nil { - check.invalidAST(c.Pos(), "incorrect expression switch case") - continue - } - check.caseValues(&x, clause.List, seen) - check.openScope(clause, "case") - inner := inner - if i+1 < len(s.Body.List) { - inner |= fallthroughOk - } else { - inner |= finalSwitchCase - } - check.stmtList(inner, clause.Body) - check.closeScope() - } - - case *ast.TypeSwitchStmt: - inner |= breakOk - check.openScope(s, "type switch") - defer check.closeScope() - - check.simpleStmt(s.Init) - - // A type switch guard must be of the form: - // - // TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" . - // - // The parser is checking syntactic correctness; - // remaining syntactic errors are considered AST errors here. - // TODO(gri) better factoring of error handling (invalid ASTs) - // - var lhs *ast.Ident // lhs identifier or nil - var rhs ast.Expr - switch guard := s.Assign.(type) { - case *ast.ExprStmt: - rhs = guard.X - case *ast.AssignStmt: - if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 { - check.invalidAST(s.Pos(), "incorrect form of type switch guard") - return - } - - lhs, _ = guard.Lhs[0].(*ast.Ident) - if lhs == nil { - check.invalidAST(s.Pos(), "incorrect form of type switch guard") - return - } - - if lhs.Name == "_" { - // _ := x.(type) is an invalid short variable declaration - check.softErrorf(lhs.Pos(), "no new variable on left side of :=") - lhs = nil // avoid declared but not used error below - } else { - check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause - } - - rhs = guard.Rhs[0] - - default: - check.invalidAST(s.Pos(), "incorrect form of type switch guard") - return - } - - // rhs must be of the form: expr.(type) and expr must be an interface - expr, _ := rhs.(*ast.TypeAssertExpr) - if expr == nil || expr.Type != nil { - check.invalidAST(s.Pos(), "incorrect form of type switch guard") - return - } - var x operand - check.expr(&x, expr.X) - if x.mode == invalid { - return - } - xtyp, _ := x.typ.Underlying().(*Interface) - if xtyp == nil { - check.errorf(x.pos(), "%s is not an interface", &x) - return - } - - check.multipleDefaults(s.Body.List) - - var lhsVars []*Var // list of implicitly declared lhs variables - seen := make(map[Type]token.Pos) // map of seen types to positions - for _, s := range s.Body.List { - clause, _ := s.(*ast.CaseClause) - if clause == nil { - check.invalidAST(s.Pos(), "incorrect type switch case") - continue - } - // Check each type in this type switch case. - T := check.caseTypes(&x, xtyp, clause.List, seen) - check.openScope(clause, "case") - // If lhs exists, declare a corresponding variable in the case-local scope. - if lhs != nil { - // spec: "The TypeSwitchGuard may include a short variable declaration. - // When that form is used, the variable is declared at the beginning of - // the implicit block in each clause. In clauses with a case listing - // exactly one type, the variable has that type; otherwise, the variable - // has the type of the expression in the TypeSwitchGuard." - if len(clause.List) != 1 || T == nil { - T = x.typ - } - obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T) - scopePos := clause.Pos() + token.Pos(len("default")) // for default clause (len(List) == 0) - if n := len(clause.List); n > 0 { - scopePos = clause.List[n-1].End() - } - check.declare(check.scope, nil, obj, scopePos) - check.recordImplicit(clause, obj) - // For the "declared but not used" error, all lhs variables act as - // one; i.e., if any one of them is 'used', all of them are 'used'. - // Collect them for later analysis. - lhsVars = append(lhsVars, obj) - } - check.stmtList(inner, clause.Body) - check.closeScope() - } - - // If lhs exists, we must have at least one lhs variable that was used. - if lhs != nil { - var used bool - for _, v := range lhsVars { - if v.used { - used = true - } - v.used = true // avoid usage error when checking entire function - } - if !used { - check.softErrorf(lhs.Pos(), "%s declared but not used", lhs.Name) - } - } - - case *ast.SelectStmt: - inner |= breakOk - - check.multipleDefaults(s.Body.List) - - for _, s := range s.Body.List { - clause, _ := s.(*ast.CommClause) - if clause == nil { - continue // error reported before - } - - // clause.Comm must be a SendStmt, RecvStmt, or default case - valid := false - var rhs ast.Expr // rhs of RecvStmt, or nil - switch s := clause.Comm.(type) { - case nil, *ast.SendStmt: - valid = true - case *ast.AssignStmt: - if len(s.Rhs) == 1 { - rhs = s.Rhs[0] - } - case *ast.ExprStmt: - rhs = s.X - } - - // if present, rhs must be a receive operation - if rhs != nil { - if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW { - valid = true - } - } - - if !valid { - check.error(clause.Comm.Pos(), "select case must be send or receive (possibly with assignment)") - continue - } - - check.openScope(s, "case") - if clause.Comm != nil { - check.stmt(inner, clause.Comm) - } - check.stmtList(inner, clause.Body) - check.closeScope() - } - - case *ast.ForStmt: - inner |= breakOk | continueOk - check.openScope(s, "for") - defer check.closeScope() - - check.simpleStmt(s.Init) - if s.Cond != nil { - var x operand - check.expr(&x, s.Cond) - if x.mode != invalid && !isBoolean(x.typ) { - check.error(s.Cond.Pos(), "non-boolean condition in for statement") - } - } - check.simpleStmt(s.Post) - // spec: "The init statement may be a short variable - // declaration, but the post statement must not." - if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE { - check.softErrorf(s.Pos(), "cannot declare in post statement") - // Don't call useLHS here because we want to use the lhs in - // this erroneous statement so that we don't get errors about - // these lhs variables being declared but not used. - check.use(s.Lhs...) // avoid follow-up errors - } - check.stmt(inner, s.Body) - - case *ast.RangeStmt: - inner |= breakOk | continueOk - check.openScope(s, "for") - defer check.closeScope() - - // check expression to iterate over - var x operand - check.expr(&x, s.X) - - // determine key/value types - var key, val Type - if x.mode != invalid { - switch typ := x.typ.Underlying().(type) { - case *Basic: - if isString(typ) { - key = Typ[Int] - val = universeRune // use 'rune' name - } - case *Array: - key = Typ[Int] - val = typ.elem - case *Slice: - key = Typ[Int] - val = typ.elem - case *Pointer: - if typ, _ := typ.base.Underlying().(*Array); typ != nil { - key = Typ[Int] - val = typ.elem - } - case *Map: - key = typ.key - val = typ.elem - case *Chan: - key = typ.elem - val = Typ[Invalid] - if typ.dir == SendOnly { - check.errorf(x.pos(), "cannot range over send-only channel %s", &x) - // ok to continue - } - if s.Value != nil { - check.errorf(s.Value.Pos(), "iteration over %s permits only one iteration variable", &x) - // ok to continue - } - } - } - - if key == nil { - check.errorf(x.pos(), "cannot range over %s", &x) - // ok to continue - } - - // check assignment to/declaration of iteration variables - // (irregular assignment, cannot easily map to existing assignment checks) - - // lhs expressions and initialization value (rhs) types - lhs := [2]ast.Expr{s.Key, s.Value} - rhs := [2]Type{key, val} // key, val may be nil - - if s.Tok == token.DEFINE { - // short variable declaration; variable scope starts after the range clause - // (the for loop opens a new scope, so variables on the lhs never redeclare - // previously declared variables) - var vars []*Var - for i, lhs := range lhs { - if lhs == nil { - continue - } - - // determine lhs variable - var obj *Var - if ident, _ := lhs.(*ast.Ident); ident != nil { - // declare new variable - name := ident.Name - obj = NewVar(ident.Pos(), check.pkg, name, nil) - check.recordDef(ident, obj) - // _ variables don't count as new variables - if name != "_" { - vars = append(vars, obj) - } - } else { - check.errorf(lhs.Pos(), "cannot declare %s", lhs) - obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable - } - - // initialize lhs variable - if typ := rhs[i]; typ != nil { - x.mode = value - x.expr = lhs // we don't have a better rhs expression to use here - x.typ = typ - check.initVar(obj, &x, "range clause") - } else { - obj.typ = Typ[Invalid] - obj.used = true // don't complain about unused variable - } - } - - // declare variables - if len(vars) > 0 { - scopePos := s.X.End() - for _, obj := range vars { - // spec: "The scope of a constant or variable identifier declared inside - // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl - // for short variable declarations) and ends at the end of the innermost - // containing block." - check.declare(check.scope, nil /* recordDef already called */, obj, scopePos) - } - } else { - check.error(s.TokPos, "no new variables on left side of :=") - } - } else { - // ordinary assignment - for i, lhs := range lhs { - if lhs == nil { - continue - } - if typ := rhs[i]; typ != nil { - x.mode = value - x.expr = lhs // we don't have a better rhs expression to use here - x.typ = typ - check.assignVar(lhs, &x) - } - } - } - - check.stmt(inner, s.Body) - - default: - check.error(s.Pos(), "invalid statement") - } -} diff --git a/third_party/forked/golang/go/types/type.go b/third_party/forked/golang/go/types/type.go deleted file mode 100644 index 5db03f8f0ca77..0000000000000 --- a/third_party/forked/golang/go/types/type.go +++ /dev/null @@ -1,464 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -import "sort" - -// A Type represents a type of Go. -// All types implement the Type interface. -type Type interface { - // Underlying returns the underlying type of a type. - Underlying() Type - - // String returns a string representation of a type. - String() string -} - -// BasicKind describes the kind of basic type. -type BasicKind int - -const ( - Invalid BasicKind = iota // type is invalid - - // predeclared types - Bool - Int - Int8 - Int16 - Int32 - Int64 - Uint - Uint8 - Uint16 - Uint32 - Uint64 - Uintptr - Float32 - Float64 - Complex64 - Complex128 - String - UnsafePointer - - // types for untyped values - UntypedBool - UntypedInt - UntypedRune - UntypedFloat - UntypedComplex - UntypedString - UntypedNil - - // aliases - Byte = Uint8 - Rune = Int32 -) - -// BasicInfo is a set of flags describing properties of a basic type. -type BasicInfo int - -// Properties of basic types. -const ( - IsBoolean BasicInfo = 1 << iota - IsInteger - IsUnsigned - IsFloat - IsComplex - IsString - IsUntyped - - IsOrdered = IsInteger | IsFloat | IsString - IsNumeric = IsInteger | IsFloat | IsComplex - IsConstType = IsBoolean | IsNumeric | IsString -) - -// A Basic represents a basic type. -type Basic struct { - kind BasicKind - info BasicInfo - name string -} - -// Kind returns the kind of basic type b. -func (b *Basic) Kind() BasicKind { return b.kind } - -// Info returns information about properties of basic type b. -func (b *Basic) Info() BasicInfo { return b.info } - -// Name returns the name of basic type b. -func (b *Basic) Name() string { return b.name } - -// An Array represents an array type. -type Array struct { - len int64 - elem Type -} - -// NewArray returns a new array type for the given element type and length. -// A negative length indicates an unknown length. -func NewArray(elem Type, len int64) *Array { return &Array{len, elem} } - -// Len returns the length of array a. -// A negative result indicates an unknown length. -func (a *Array) Len() int64 { return a.len } - -// Elem returns element type of array a. -func (a *Array) Elem() Type { return a.elem } - -// A Slice represents a slice type. -type Slice struct { - elem Type -} - -// NewSlice returns a new slice type for the given element type. -func NewSlice(elem Type) *Slice { return &Slice{elem} } - -// Elem returns the element type of slice s. -func (s *Slice) Elem() Type { return s.elem } - -// A Struct represents a struct type. -type Struct struct { - fields []*Var - tags []string // field tags; nil if there are no tags -} - -// NewStruct returns a new struct with the given fields and corresponding field tags. -// If a field with index i has a tag, tags[i] must be that tag, but len(tags) may be -// only as long as required to hold the tag with the largest index i. Consequently, -// if no field has a tag, tags may be nil. -func NewStruct(fields []*Var, tags []string) *Struct { - var fset objset - for _, f := range fields { - if f.name != "_" && fset.insert(f) != nil { - panic("multiple fields with the same name") - } - } - if len(tags) > len(fields) { - panic("more tags than fields") - } - return &Struct{fields: fields, tags: tags} -} - -// NumFields returns the number of fields in the struct (including blank and anonymous fields). -func (s *Struct) NumFields() int { return len(s.fields) } - -// Field returns the i'th field for 0 <= i < NumFields(). -func (s *Struct) Field(i int) *Var { return s.fields[i] } - -// Tag returns the i'th field tag for 0 <= i < NumFields(). -func (s *Struct) Tag(i int) string { - if i < len(s.tags) { - return s.tags[i] - } - return "" -} - -// A Pointer represents a pointer type. -type Pointer struct { - base Type // element type -} - -// NewPointer returns a new pointer type for the given element (base) type. -func NewPointer(elem Type) *Pointer { return &Pointer{base: elem} } - -// Elem returns the element type for the given pointer p. -func (p *Pointer) Elem() Type { return p.base } - -// A Tuple represents an ordered list of variables; a nil *Tuple is a valid (empty) tuple. -// Tuples are used as components of signatures and to represent the type of multiple -// assignments; they are not first class types of Go. -type Tuple struct { - vars []*Var -} - -// NewTuple returns a new tuple for the given variables. -func NewTuple(x ...*Var) *Tuple { - if len(x) > 0 { - return &Tuple{x} - } - return nil -} - -// Len returns the number variables of tuple t. -func (t *Tuple) Len() int { - if t != nil { - return len(t.vars) - } - return 0 -} - -// At returns the i'th variable of tuple t. -func (t *Tuple) At(i int) *Var { return t.vars[i] } - -// A Signature represents a (non-builtin) function or method type. -// The receiver is ignored when comparing signatures for identity. -type Signature struct { - // We need to keep the scope in Signature (rather than passing it around - // and store it in the Func Object) because when type-checking a function - // literal we call the general type checker which returns a general Type. - // We then unpack the *Signature and use the scope for the literal body. - scope *Scope // function scope, present for package-local signatures - recv *Var // nil if not a method - params *Tuple // (incoming) parameters from left to right; or nil - results *Tuple // (outgoing) results from left to right; or nil - variadic bool // true if the last parameter's type is of the form ...T (or string, for append built-in only) -} - -// NewSignature returns a new function type for the given receiver, parameters, -// and results, either of which may be nil. If variadic is set, the function -// is variadic, it must have at least one parameter, and the last parameter -// must be of unnamed slice type. -func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature { - if variadic { - n := params.Len() - if n == 0 { - panic("types.NewSignature: variadic function must have at least one parameter") - } - if _, ok := params.At(n - 1).typ.(*Slice); !ok { - panic("types.NewSignature: variadic parameter must be of unnamed slice type") - } - } - return &Signature{nil, recv, params, results, variadic} -} - -// Recv returns the receiver of signature s (if a method), or nil if a -// function. It is ignored when comparing signatures for identity. -// -// For an abstract method, Recv returns the enclosing interface either -// as a *Named or an *Interface. Due to embedding, an interface may -// contain methods whose receiver type is a different interface. -func (s *Signature) Recv() *Var { return s.recv } - -// Params returns the parameters of signature s, or nil. -func (s *Signature) Params() *Tuple { return s.params } - -// Results returns the results of signature s, or nil. -func (s *Signature) Results() *Tuple { return s.results } - -// Variadic reports whether the signature s is variadic. -func (s *Signature) Variadic() bool { return s.variadic } - -// An Interface represents an interface type. -type Interface struct { - methods []*Func // ordered list of explicitly declared methods - embeddeds []*Named // ordered list of explicitly embedded types - - allMethods []*Func // ordered list of methods declared with or embedded in this interface (TODO(gri): replace with mset) -} - -// emptyInterface represents the empty (completed) interface -var emptyInterface = Interface{allMethods: markComplete} - -// markComplete is used to mark an empty interface as completely -// set up by setting the allMethods field to a non-nil empty slice. -var markComplete = make([]*Func, 0) - -// NewInterface returns a new (incomplete) interface for the given methods and embedded types. -// To compute the method set of the interface, Complete must be called. -func NewInterface(methods []*Func, embeddeds []*Named) *Interface { - typ := new(Interface) - - if len(methods) == 0 && len(embeddeds) == 0 { - return typ - } - - var mset objset - for _, m := range methods { - if mset.insert(m) != nil { - panic("multiple methods with the same name") - } - // set receiver - // TODO(gri) Ideally, we should use a named type here instead of - // typ, for less verbose printing of interface method signatures. - m.typ.(*Signature).recv = NewVar(m.pos, m.pkg, "", typ) - } - sort.Sort(byUniqueMethodName(methods)) - - if embeddeds != nil { - sort.Sort(byUniqueTypeName(embeddeds)) - } - - typ.methods = methods - typ.embeddeds = embeddeds - return typ -} - -// NumExplicitMethods returns the number of explicitly declared methods of interface t. -func (t *Interface) NumExplicitMethods() int { return len(t.methods) } - -// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods(). -// The methods are ordered by their unique Id. -func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] } - -// NumEmbeddeds returns the number of embedded types in interface t. -func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) } - -// Embedded returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds(). -// The types are ordered by the corresponding TypeName's unique Id. -func (t *Interface) Embedded(i int) *Named { return t.embeddeds[i] } - -// NumMethods returns the total number of methods of interface t. -func (t *Interface) NumMethods() int { return len(t.allMethods) } - -// Method returns the i'th method of interface t for 0 <= i < t.NumMethods(). -// The methods are ordered by their unique Id. -func (t *Interface) Method(i int) *Func { return t.allMethods[i] } - -// Empty returns true if t is the empty interface. -func (t *Interface) Empty() bool { return len(t.allMethods) == 0 } - -// Complete computes the interface's method set. It must be called by users of -// NewInterface after the interface's embedded types are fully defined and -// before using the interface type in any way other than to form other types. -// Complete returns the receiver. -func (t *Interface) Complete() *Interface { - if t.allMethods != nil { - return t - } - - var allMethods []*Func - if t.embeddeds == nil { - if t.methods == nil { - allMethods = make([]*Func, 0, 1) - } else { - allMethods = t.methods - } - } else { - allMethods = append(allMethods, t.methods...) - for _, et := range t.embeddeds { - it := et.Underlying().(*Interface) - it.Complete() - for _, tm := range it.allMethods { - // Make a copy of the method and adjust its receiver type. - newm := *tm - newmtyp := *tm.typ.(*Signature) - newm.typ = &newmtyp - newmtyp.recv = NewVar(newm.pos, newm.pkg, "", t) - allMethods = append(allMethods, &newm) - } - } - sort.Sort(byUniqueMethodName(allMethods)) - } - t.allMethods = allMethods - - return t -} - -// A Map represents a map type. -type Map struct { - key, elem Type -} - -// NewMap returns a new map for the given key and element types. -func NewMap(key, elem Type) *Map { - return &Map{key, elem} -} - -// Key returns the key type of map m. -func (m *Map) Key() Type { return m.key } - -// Elem returns the element type of map m. -func (m *Map) Elem() Type { return m.elem } - -// A Chan represents a channel type. -type Chan struct { - dir ChanDir - elem Type -} - -// A ChanDir value indicates a channel direction. -type ChanDir int - -// The direction of a channel is indicated by one of these constants. -const ( - SendRecv ChanDir = iota - SendOnly - RecvOnly -) - -// NewChan returns a new channel type for the given direction and element type. -func NewChan(dir ChanDir, elem Type) *Chan { - return &Chan{dir, elem} -} - -// Dir returns the direction of channel c. -func (c *Chan) Dir() ChanDir { return c.dir } - -// Elem returns the element type of channel c. -func (c *Chan) Elem() Type { return c.elem } - -// A Named represents a named type. -type Named struct { - obj *TypeName // corresponding declared object - underlying Type // possibly a *Named during setup; never a *Named once set up completely - methods []*Func // methods declared for this type (not the method set of this type) -} - -// NewNamed returns a new named type for the given type name, underlying type, and associated methods. -// If the given type name obj doesn't have a type yet, its type is set to the returned named type. -// The underlying type must not be a *Named. -func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named { - if _, ok := underlying.(*Named); ok { - panic("types.NewNamed: underlying type must not be *Named") - } - typ := &Named{obj: obj, underlying: underlying, methods: methods} - if obj.typ == nil { - obj.typ = typ - } - return typ -} - -// Obj returns the type name for the named type t. -func (t *Named) Obj() *TypeName { return t.obj } - -// NumMethods returns the number of explicit methods whose receiver is named type t. -func (t *Named) NumMethods() int { return len(t.methods) } - -// Method returns the i'th method of named type t for 0 <= i < t.NumMethods(). -func (t *Named) Method(i int) *Func { return t.methods[i] } - -// SetUnderlying sets the underlying type and marks t as complete. -func (t *Named) SetUnderlying(underlying Type) { - if underlying == nil { - panic("types.Named.SetUnderlying: underlying type must not be nil") - } - if _, ok := underlying.(*Named); ok { - panic("types.Named.SetUnderlying: underlying type must not be *Named") - } - t.underlying = underlying -} - -// AddMethod adds method m unless it is already in the method list. -func (t *Named) AddMethod(m *Func) { - if i, _ := lookupMethod(t.methods, m.pkg, m.name); i < 0 { - t.methods = append(t.methods, m) - } -} - -// Implementations for Type methods. - -func (t *Basic) Underlying() Type { return t } -func (t *Array) Underlying() Type { return t } -func (t *Slice) Underlying() Type { return t } -func (t *Struct) Underlying() Type { return t } -func (t *Pointer) Underlying() Type { return t } -func (t *Tuple) Underlying() Type { return t } -func (t *Signature) Underlying() Type { return t } -func (t *Interface) Underlying() Type { return t } -func (t *Map) Underlying() Type { return t } -func (t *Chan) Underlying() Type { return t } -func (t *Named) Underlying() Type { return t.underlying } - -func (t *Basic) String() string { return TypeString(t, nil) } -func (t *Array) String() string { return TypeString(t, nil) } -func (t *Slice) String() string { return TypeString(t, nil) } -func (t *Struct) String() string { return TypeString(t, nil) } -func (t *Pointer) String() string { return TypeString(t, nil) } -func (t *Tuple) String() string { return TypeString(t, nil) } -func (t *Signature) String() string { return TypeString(t, nil) } -func (t *Interface) String() string { return TypeString(t, nil) } -func (t *Map) String() string { return TypeString(t, nil) } -func (t *Chan) String() string { return TypeString(t, nil) } -func (t *Named) String() string { return TypeString(t, nil) } diff --git a/third_party/forked/golang/go/types/typestring.go b/third_party/forked/golang/go/types/typestring.go deleted file mode 100644 index a9c0bfde1f918..0000000000000 --- a/third_party/forked/golang/go/types/typestring.go +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements printing of types. - -package types - -import ( - "bytes" - "fmt" -) - -// A Qualifier controls how named package-level objects are printed in -// calls to TypeString, ObjectString, and SelectionString. -// -// These three formatting routines call the Qualifier for each -// package-level object O, and if the Qualifier returns a non-empty -// string p, the object is printed in the form p.O. -// If it returns an empty string, only the object name O is printed. -// -// Using a nil Qualifier is equivalent to using (*Package).Path: the -// object is qualified by the import path, e.g., "encoding/json.Marshal". -// -type Qualifier func(*Package) string - -// RelativeTo(pkg) returns a Qualifier that fully qualifies members of -// all packages other than pkg. -func RelativeTo(pkg *Package) Qualifier { - if pkg == nil { - return nil - } - return func(other *Package) string { - if pkg == other { - return "" // same package; unqualified - } - return other.Path() - } -} - -// If gcCompatibilityMode is set, printing of types is modified -// to match the representation of some types in the gc compiler: -// -// - byte and rune lose their alias name and simply stand for -// uint8 and int32 respectively -// - embedded interfaces get flattened (the embedding info is lost, -// and certain recursive interface types cannot be printed anymore) -// -// This makes it easier to compare packages computed with the type- -// checker vs packages imported from gc export data. -// -// Caution: This flag affects all uses of WriteType, globally. -// It is only provided for testing in conjunction with -// gc-generated data. -// -// This flag is exported in the x/tools/go/types package. We don't -// need it at the moment in the std repo and so we don't export it -// anymore. We should eventually try to remove it altogether. -// TODO(gri) remove this -var gcCompatibilityMode bool - -// TypeString returns the string representation of typ. -// The Qualifier controls the printing of -// package-level objects, and may be nil. -func TypeString(typ Type, qf Qualifier) string { - var buf bytes.Buffer - WriteType(&buf, typ, qf) - return buf.String() -} - -// WriteType writes the string representation of typ to buf. -// The Qualifier controls the printing of -// package-level objects, and may be nil. -func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) { - writeType(buf, typ, qf, make([]Type, 0, 8)) -} - -func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) { - // Theoretically, this is a quadratic lookup algorithm, but in - // practice deeply nested composite types with unnamed component - // types are uncommon. This code is likely more efficient than - // using a map. - for _, t := range visited { - if t == typ { - fmt.Fprintf(buf, "○%T", typ) // cycle to typ - return - } - } - visited = append(visited, typ) - - switch t := typ.(type) { - case nil: - buf.WriteString("") - - case *Basic: - if t.kind == UnsafePointer { - buf.WriteString("unsafe.") - } - if gcCompatibilityMode { - // forget the alias names - switch t.kind { - case Byte: - t = Typ[Uint8] - case Rune: - t = Typ[Int32] - } - } - buf.WriteString(t.name) - - case *Array: - fmt.Fprintf(buf, "[%d]", t.len) - writeType(buf, t.elem, qf, visited) - - case *Slice: - buf.WriteString("[]") - writeType(buf, t.elem, qf, visited) - - case *Struct: - buf.WriteString("struct{") - for i, f := range t.fields { - if i > 0 { - buf.WriteString("; ") - } - if !f.anonymous { - buf.WriteString(f.name) - buf.WriteByte(' ') - } - writeType(buf, f.typ, qf, visited) - if tag := t.Tag(i); tag != "" { - fmt.Fprintf(buf, " %q", tag) - } - } - buf.WriteByte('}') - - case *Pointer: - buf.WriteByte('*') - writeType(buf, t.base, qf, visited) - - case *Tuple: - writeTuple(buf, t, false, qf, visited) - - case *Signature: - buf.WriteString("func") - writeSignature(buf, t, qf, visited) - - case *Interface: - // We write the source-level methods and embedded types rather - // than the actual method set since resolved method signatures - // may have non-printable cycles if parameters have anonymous - // interface types that (directly or indirectly) embed the - // current interface. For instance, consider the result type - // of m: - // - // type T interface{ - // m() interface{ T } - // } - // - buf.WriteString("interface{") - empty := true - if gcCompatibilityMode { - // print flattened interface - // (useful to compare against gc-generated interfaces) - for i, m := range t.allMethods { - if i > 0 { - buf.WriteString("; ") - } - buf.WriteString(m.name) - writeSignature(buf, m.typ.(*Signature), qf, visited) - empty = false - } - } else { - // print explicit interface methods and embedded types - for i, m := range t.methods { - if i > 0 { - buf.WriteString("; ") - } - buf.WriteString(m.name) - writeSignature(buf, m.typ.(*Signature), qf, visited) - empty = false - } - for i, typ := range t.embeddeds { - if i > 0 || len(t.methods) > 0 { - buf.WriteString("; ") - } - writeType(buf, typ, qf, visited) - empty = false - } - } - if t.allMethods == nil || len(t.methods) > len(t.allMethods) { - if !empty { - buf.WriteByte(' ') - } - buf.WriteString("/* incomplete */") - } - buf.WriteByte('}') - - case *Map: - buf.WriteString("map[") - writeType(buf, t.key, qf, visited) - buf.WriteByte(']') - writeType(buf, t.elem, qf, visited) - - case *Chan: - var s string - var parens bool - switch t.dir { - case SendRecv: - s = "chan " - // chan (<-chan T) requires parentheses - if c, _ := t.elem.(*Chan); c != nil && c.dir == RecvOnly { - parens = true - } - case SendOnly: - s = "chan<- " - case RecvOnly: - s = "<-chan " - default: - panic("unreachable") - } - buf.WriteString(s) - if parens { - buf.WriteByte('(') - } - writeType(buf, t.elem, qf, visited) - if parens { - buf.WriteByte(')') - } - - case *Named: - s := "" - if obj := t.obj; obj != nil { - if obj.pkg != nil { - writePackage(buf, obj.pkg, qf) - } - // TODO(gri): function-local named types should be displayed - // differently from named types at package level to avoid - // ambiguity. - s = obj.name - } - buf.WriteString(s) - - default: - // For externally defined implementations of Type. - buf.WriteString(t.String()) - } -} - -func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) { - buf.WriteByte('(') - if tup != nil { - for i, v := range tup.vars { - if i > 0 { - buf.WriteString(", ") - } - if v.name != "" { - buf.WriteString(v.name) - buf.WriteByte(' ') - } - typ := v.typ - if variadic && i == len(tup.vars)-1 { - if s, ok := typ.(*Slice); ok { - buf.WriteString("...") - typ = s.elem - } else { - // special case: - // append(s, "foo"...) leads to signature func([]byte, string...) - if t, ok := typ.Underlying().(*Basic); !ok || t.kind != String { - panic("internal error: string type expected") - } - writeType(buf, typ, qf, visited) - buf.WriteString("...") - continue - } - } - writeType(buf, typ, qf, visited) - } - } - buf.WriteByte(')') -} - -// WriteSignature writes the representation of the signature sig to buf, -// without a leading "func" keyword. -// The Qualifier controls the printing of -// package-level objects, and may be nil. -func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) { - writeSignature(buf, sig, qf, make([]Type, 0, 8)) -} - -func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []Type) { - writeTuple(buf, sig.params, sig.variadic, qf, visited) - - n := sig.results.Len() - if n == 0 { - // no result - return - } - - buf.WriteByte(' ') - if n == 1 && sig.results.vars[0].name == "" { - // single unnamed result - writeType(buf, sig.results.vars[0].typ, qf, visited) - return - } - - // multiple or named result(s) - writeTuple(buf, sig.results, false, qf, visited) -} diff --git a/third_party/forked/golang/go/types/typexpr.go b/third_party/forked/golang/go/types/typexpr.go deleted file mode 100644 index e4e42e7993b2a..0000000000000 --- a/third_party/forked/golang/go/types/typexpr.go +++ /dev/null @@ -1,722 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements type-checking of identifiers and type expressions. - -package types - -import ( - "go/ast" - "go/constant" - "go/token" - "sort" - "strconv" -) - -// ident type-checks identifier e and initializes x with the value or type of e. -// If an error occurred, x.mode is set to invalid. -// For the meaning of def and path, see check.typ, below. -// -func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, path []*TypeName) { - x.mode = invalid - x.expr = e - - scope, obj := check.scope.LookupParent(e.Name, check.pos) - if obj == nil { - if e.Name == "_" { - check.errorf(e.Pos(), "cannot use _ as value or type") - } else { - check.errorf(e.Pos(), "undeclared name: %s", e.Name) - } - return - } - check.recordUse(e, obj) - - check.objDecl(obj, def, path) - typ := obj.Type() - assert(typ != nil) - - // The object may be dot-imported: If so, remove its package from - // the map of unused dot imports for the respective file scope. - // (This code is only needed for dot-imports. Without them, - // we only have to mark variables, see *Var case below). - if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil { - delete(check.unusedDotImports[scope], pkg) - } - - switch obj := obj.(type) { - case *PkgName: - check.errorf(e.Pos(), "use of package %s not in selector", obj.name) - return - - case *Const: - check.addDeclDep(obj) - if typ == Typ[Invalid] { - return - } - if obj == universeIota { - if check.iota == nil { - check.errorf(e.Pos(), "cannot use iota outside constant declaration") - return - } - x.val = check.iota - } else { - x.val = obj.val - } - assert(x.val != nil) - x.mode = constant_ - - case *TypeName: - x.mode = typexpr - // check for cycle - // (it's ok to iterate forward because each named type appears at most once in path) - for i, prev := range path { - if prev == obj { - check.errorf(obj.pos, "illegal cycle in declaration of %s", obj.name) - // print cycle - for _, obj := range path[i:] { - check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented - } - check.errorf(obj.Pos(), "\t%s", obj.Name()) - // maintain x.mode == typexpr despite error - typ = Typ[Invalid] - break - } - } - - case *Var: - // It's ok to mark non-local variables, but ignore variables - // from other packages to avoid potential race conditions with - // dot-imported variables. - if obj.pkg == check.pkg { - obj.used = true - } - check.addDeclDep(obj) - if typ == Typ[Invalid] { - return - } - x.mode = variable - - case *Func: - check.addDeclDep(obj) - x.mode = value - - case *Builtin: - x.id = obj.id - x.mode = builtin - - case *Nil: - x.mode = value - - default: - unreachable() - } - - x.typ = typ -} - -// typExpr type-checks the type expression e and returns its type, or Typ[Invalid]. -// If def != nil, e is the type specification for the named type def, declared -// in a type declaration, and def.underlying will be set to the type of e before -// any components of e are type-checked. Path contains the path of named types -// referring to this type. -// -func (check *Checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type) { - if trace { - check.trace(e.Pos(), "%s", e) - check.indent++ - defer func() { - check.indent-- - check.trace(e.Pos(), "=> %s", T) - }() - } - - T = check.typExprInternal(e, def, path) - assert(isTyped(T)) - check.recordTypeAndValue(e, typexpr, T, nil) - - return -} - -func (check *Checker) typ(e ast.Expr) Type { - return check.typExpr(e, nil, nil) -} - -// funcType type-checks a function or method type. -func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) { - scope := NewScope(check.scope, token.NoPos, token.NoPos, "function") - scope.isFunc = true - check.recordScope(ftyp, scope) - - recvList, _ := check.collectParams(scope, recvPar, false) - params, variadic := check.collectParams(scope, ftyp.Params, true) - results, _ := check.collectParams(scope, ftyp.Results, false) - - if recvPar != nil { - // recv parameter list present (may be empty) - // spec: "The receiver is specified via an extra parameter section preceding the - // method name. That parameter section must declare a single parameter, the receiver." - var recv *Var - switch len(recvList) { - case 0: - check.error(recvPar.Pos(), "method is missing receiver") - recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below - default: - // more than one receiver - check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver") - fallthrough // continue with first receiver - case 1: - recv = recvList[0] - } - // spec: "The receiver type must be of the form T or *T where T is a type name." - // (ignore invalid types - error was reported before) - if t, _ := deref(recv.typ); t != Typ[Invalid] { - var err string - if T, _ := t.(*Named); T != nil { - // spec: "The type denoted by T is called the receiver base type; it must not - // be a pointer or interface type and it must be declared in the same package - // as the method." - if T.obj.pkg != check.pkg { - err = "type not defined in this package" - } else { - // TODO(gri) This is not correct if the underlying type is unknown yet. - switch u := T.underlying.(type) { - case *Basic: - // unsafe.Pointer is treated like a regular pointer - if u.kind == UnsafePointer { - err = "unsafe.Pointer" - } - case *Pointer, *Interface: - err = "pointer or interface type" - } - } - } else { - err = "basic or unnamed type" - } - if err != "" { - check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err) - // ok to continue - } - } - sig.recv = recv - } - - sig.scope = scope - sig.params = NewTuple(params...) - sig.results = NewTuple(results...) - sig.variadic = variadic -} - -// typExprInternal drives type checking of types. -// Must only be called by typExpr. -// -func (check *Checker) typExprInternal(e ast.Expr, def *Named, path []*TypeName) Type { - switch e := e.(type) { - case *ast.BadExpr: - // ignore - error reported before - - case *ast.Ident: - var x operand - check.ident(&x, e, def, path) - - switch x.mode { - case typexpr: - typ := x.typ - def.setUnderlying(typ) - return typ - case invalid: - // ignore - error reported before - case novalue: - check.errorf(x.pos(), "%s used as type", &x) - default: - check.errorf(x.pos(), "%s is not a type", &x) - } - - case *ast.SelectorExpr: - var x operand - check.selector(&x, e) - - switch x.mode { - case typexpr: - typ := x.typ - def.setUnderlying(typ) - return typ - case invalid: - // ignore - error reported before - case novalue: - check.errorf(x.pos(), "%s used as type", &x) - default: - check.errorf(x.pos(), "%s is not a type", &x) - } - - case *ast.ParenExpr: - return check.typExpr(e.X, def, path) - - case *ast.ArrayType: - if e.Len != nil { - typ := new(Array) - def.setUnderlying(typ) - typ.len = check.arrayLength(e.Len) - typ.elem = check.typExpr(e.Elt, nil, path) - return typ - - } else { - typ := new(Slice) - def.setUnderlying(typ) - typ.elem = check.typ(e.Elt) - return typ - } - - case *ast.StructType: - typ := new(Struct) - def.setUnderlying(typ) - check.structType(typ, e, path) - return typ - - case *ast.StarExpr: - typ := new(Pointer) - def.setUnderlying(typ) - typ.base = check.typ(e.X) - return typ - - case *ast.FuncType: - typ := new(Signature) - def.setUnderlying(typ) - check.funcType(typ, nil, e) - return typ - - case *ast.InterfaceType: - typ := new(Interface) - def.setUnderlying(typ) - check.interfaceType(typ, e, def, path) - return typ - - case *ast.MapType: - typ := new(Map) - def.setUnderlying(typ) - - typ.key = check.typ(e.Key) - typ.elem = check.typ(e.Value) - - // spec: "The comparison operators == and != must be fully defined - // for operands of the key type; thus the key type must not be a - // function, map, or slice." - // - // Delay this check because it requires fully setup types; - // it is safe to continue in any case (was issue 6667). - check.delay(func() { - if !Comparable(typ.key) { - check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key) - } - }) - - return typ - - case *ast.ChanType: - typ := new(Chan) - def.setUnderlying(typ) - - dir := SendRecv - switch e.Dir { - case ast.SEND | ast.RECV: - // nothing to do - case ast.SEND: - dir = SendOnly - case ast.RECV: - dir = RecvOnly - default: - check.invalidAST(e.Pos(), "unknown channel direction %d", e.Dir) - // ok to continue - } - - typ.dir = dir - typ.elem = check.typ(e.Value) - return typ - - default: - check.errorf(e.Pos(), "%s is not a type", e) - } - - typ := Typ[Invalid] - def.setUnderlying(typ) - return typ -} - -// typeOrNil type-checks the type expression (or nil value) e -// and returns the typ of e, or nil. -// If e is neither a type nor nil, typOrNil returns Typ[Invalid]. -// -func (check *Checker) typOrNil(e ast.Expr) Type { - var x operand - check.rawExpr(&x, e, nil) - switch x.mode { - case invalid: - // ignore - error reported before - case novalue: - check.errorf(x.pos(), "%s used as type", &x) - case typexpr: - return x.typ - case value: - if x.isNil() { - return nil - } - fallthrough - default: - check.errorf(x.pos(), "%s is not a type", &x) - } - return Typ[Invalid] -} - -// arrayLength type-checks the array length expression e -// and returns the constant length >= 0, or a value < 0 -// to indicate an error (and thus an unknown length). -func (check *Checker) arrayLength(e ast.Expr) int64 { - var x operand - check.expr(&x, e) - if x.mode != constant_ { - if x.mode != invalid { - check.errorf(x.pos(), "array length %s must be constant", &x) - } - return -1 - } - if isUntyped(x.typ) || isInteger(x.typ) { - if val := constant.ToInt(x.val); val.Kind() == constant.Int { - if representableConst(val, check.conf, Typ[Int], nil) { - if n, ok := constant.Int64Val(val); ok && n >= 0 { - return n - } - check.errorf(x.pos(), "invalid array length %s", &x) - return -1 - } - } - } - check.errorf(x.pos(), "array length %s must be integer", &x) - return -1 -} - -func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) { - if list == nil { - return - } - - var named, anonymous bool - for i, field := range list.List { - ftype := field.Type - if t, _ := ftype.(*ast.Ellipsis); t != nil { - ftype = t.Elt - if variadicOk && i == len(list.List)-1 { - variadic = true - } else { - check.invalidAST(field.Pos(), "... not permitted") - // ignore ... and continue - } - } - typ := check.typ(ftype) - // The parser ensures that f.Tag is nil and we don't - // care if a constructed AST contains a non-nil tag. - if len(field.Names) > 0 { - // named parameter - for _, name := range field.Names { - if name.Name == "" { - check.invalidAST(name.Pos(), "anonymous parameter") - // ok to continue - } - par := NewParam(name.Pos(), check.pkg, name.Name, typ) - check.declare(scope, name, par, scope.pos) - params = append(params, par) - } - named = true - } else { - // anonymous parameter - par := NewParam(ftype.Pos(), check.pkg, "", typ) - check.recordImplicit(field, par) - params = append(params, par) - anonymous = true - } - } - - if named && anonymous { - check.invalidAST(list.Pos(), "list contains both named and anonymous parameters") - // ok to continue - } - - // For a variadic function, change the last parameter's type from T to []T. - if variadic && len(params) > 0 { - last := params[len(params)-1] - last.typ = &Slice{elem: last.typ} - } - - return -} - -func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool { - if alt := oset.insert(obj); alt != nil { - check.errorf(pos, "%s redeclared", obj.Name()) - check.reportAltDecl(alt) - return false - } - return true -} - -func (check *Checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, def *Named, path []*TypeName) { - // empty interface: common case - if ityp.Methods == nil { - return - } - - // The parser ensures that field tags are nil and we don't - // care if a constructed AST contains non-nil tags. - - // use named receiver type if available (for better error messages) - var recvTyp Type = iface - if def != nil { - recvTyp = def - } - - // Phase 1: Collect explicitly declared methods, the corresponding - // signature (AST) expressions, and the list of embedded - // type (AST) expressions. Do not resolve signatures or - // embedded types yet to avoid cycles referring to this - // interface. - - var ( - mset objset - signatures []ast.Expr // list of corresponding method signatures - embedded []ast.Expr // list of embedded types - ) - for _, f := range ityp.Methods.List { - if len(f.Names) > 0 { - // The parser ensures that there's only one method - // and we don't care if a constructed AST has more. - name := f.Names[0] - pos := name.Pos() - // spec: "As with all method sets, in an interface type, - // each method must have a unique non-blank name." - if name.Name == "_" { - check.errorf(pos, "invalid method name _") - continue - } - // Don't type-check signature yet - use an - // empty signature now and update it later. - // Since we know the receiver, set it up now - // (required to avoid crash in ptrRecv; see - // e.g. test case for issue 6638). - // TODO(gri) Consider marking methods signatures - // as incomplete, for better error messages. See - // also the T4 and T5 tests in testdata/cycles2.src. - sig := new(Signature) - sig.recv = NewVar(pos, check.pkg, "", recvTyp) - m := NewFunc(pos, check.pkg, name.Name, sig) - if check.declareInSet(&mset, pos, m) { - iface.methods = append(iface.methods, m) - iface.allMethods = append(iface.allMethods, m) - signatures = append(signatures, f.Type) - check.recordDef(name, m) - } - } else { - // embedded type - embedded = append(embedded, f.Type) - } - } - - // Phase 2: Resolve embedded interfaces. Because an interface must not - // embed itself (directly or indirectly), each embedded interface - // can be fully resolved without depending on any method of this - // interface (if there is a cycle or another error, the embedded - // type resolves to an invalid type and is ignored). - // In particular, the list of methods for each embedded interface - // must be complete (it cannot depend on this interface), and so - // those methods can be added to the list of all methods of this - // interface. - - for _, e := range embedded { - pos := e.Pos() - typ := check.typExpr(e, nil, path) - // Determine underlying embedded (possibly incomplete) type - // by following its forward chain. - named, _ := typ.(*Named) - under := underlying(named) - embed, _ := under.(*Interface) - if embed == nil { - if typ != Typ[Invalid] { - check.errorf(pos, "%s is not an interface", typ) - } - continue - } - iface.embeddeds = append(iface.embeddeds, named) - // collect embedded methods - if embed.allMethods == nil { - check.errorf(pos, "internal error: incomplete embedded interface %s (issue #18395)", named) - } - for _, m := range embed.allMethods { - if check.declareInSet(&mset, pos, m) { - iface.allMethods = append(iface.allMethods, m) - } - } - } - - // Phase 3: At this point all methods have been collected for this interface. - // It is now safe to type-check the signatures of all explicitly - // declared methods, even if they refer to this interface via a cycle - // and embed the methods of this interface in a parameter of interface - // type. - - for i, m := range iface.methods { - expr := signatures[i] - typ := check.typ(expr) - sig, _ := typ.(*Signature) - if sig == nil { - if typ != Typ[Invalid] { - check.invalidAST(expr.Pos(), "%s is not a method signature", typ) - } - continue // keep method with empty method signature - } - // update signature, but keep recv that was set up before - old := m.typ.(*Signature) - sig.recv = old.recv - *old = *sig // update signature (don't replace it!) - } - - // TODO(gri) The list of explicit methods is only sorted for now to - // produce the same Interface as NewInterface. We may be able to - // claim source order in the future. Revisit. - sort.Sort(byUniqueMethodName(iface.methods)) - - // TODO(gri) The list of embedded types is only sorted for now to - // produce the same Interface as NewInterface. We may be able to - // claim source order in the future. Revisit. - sort.Sort(byUniqueTypeName(iface.embeddeds)) - - if iface.allMethods == nil { - iface.allMethods = make([]*Func, 0) // mark interface as complete - } else { - sort.Sort(byUniqueMethodName(iface.allMethods)) - } -} - -// byUniqueTypeName named type lists can be sorted by their unique type names. -type byUniqueTypeName []*Named - -func (a byUniqueTypeName) Len() int { return len(a) } -func (a byUniqueTypeName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() } -func (a byUniqueTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -// byUniqueMethodName method lists can be sorted by their unique method names. -type byUniqueMethodName []*Func - -func (a byUniqueMethodName) Len() int { return len(a) } -func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() } -func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -func (check *Checker) tag(t *ast.BasicLit) string { - if t != nil { - if t.Kind == token.STRING { - if val, err := strconv.Unquote(t.Value); err == nil { - return val - } - } - check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value) - } - return "" -} - -func (check *Checker) structType(styp *Struct, e *ast.StructType, path []*TypeName) { - list := e.Fields - if list == nil { - return - } - - // struct fields and tags - var fields []*Var - var tags []string - - // for double-declaration checks - var fset objset - - // current field typ and tag - var typ Type - var tag string - add := func(ident *ast.Ident, anonymous bool, pos token.Pos) { - if tag != "" && tags == nil { - tags = make([]string, len(fields)) - } - if tags != nil { - tags = append(tags, tag) - } - - name := ident.Name - fld := NewField(pos, check.pkg, name, typ, anonymous) - // spec: "Within a struct, non-blank field names must be unique." - if name == "_" || check.declareInSet(&fset, pos, fld) { - fields = append(fields, fld) - check.recordDef(ident, fld) - } - } - - for _, f := range list.List { - typ = check.typExpr(f.Type, nil, path) - tag = check.tag(f.Tag) - if len(f.Names) > 0 { - // named fields - for _, name := range f.Names { - add(name, false, name.Pos()) - } - } else { - // anonymous field - // spec: "An embedded type must be specified as a type name T or as a pointer - // to a non-interface type name *T, and T itself may not be a pointer type." - pos := f.Type.Pos() - name := anonymousFieldIdent(f.Type) - if name == nil { - check.invalidAST(pos, "anonymous field type %s has no name", f.Type) - continue - } - t, isPtr := deref(typ) - // Because we have a name, typ must be of the form T or *T, where T is the name - // of a (named or alias) type, and t (= deref(typ)) must be the type of T. - switch t := t.Underlying().(type) { - case *Basic: - if t == Typ[Invalid] { - // error was reported before - continue - } - - // unsafe.Pointer is treated like a regular pointer - if t.kind == UnsafePointer { - check.errorf(pos, "anonymous field type cannot be unsafe.Pointer") - continue - } - - case *Pointer: - check.errorf(pos, "anonymous field type cannot be a pointer") - continue - - case *Interface: - if isPtr { - check.errorf(pos, "anonymous field type cannot be a pointer to an interface") - continue - } - } - add(name, true, pos) - } - } - - styp.fields = fields - styp.tags = tags -} - -func anonymousFieldIdent(e ast.Expr) *ast.Ident { - switch e := e.(type) { - case *ast.Ident: - return e - case *ast.StarExpr: - // *T is valid, but **T is not - if _, ok := e.X.(*ast.StarExpr); !ok { - return anonymousFieldIdent(e.X) - } - case *ast.SelectorExpr: - return e.Sel - } - return nil // invalid anonymous field -} diff --git a/third_party/forked/golang/go/types/universe.go b/third_party/forked/golang/go/types/universe.go deleted file mode 100644 index 07d7078ae25b7..0000000000000 --- a/third_party/forked/golang/go/types/universe.go +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file sets up the universe scope and the unsafe package. - -package types - -import ( - "go/constant" - "go/token" - "strings" -) - -var ( - Universe *Scope - Unsafe *Package - universeIota *Const - universeByte *Basic // uint8 alias, but has name "byte" - universeRune *Basic // int32 alias, but has name "rune" -) - -// Typ contains the predeclared *Basic types indexed by their -// corresponding BasicKind. -// -// The *Basic type for Typ[Byte] will have the name "uint8". -// Use Universe.Lookup("byte").Type() to obtain the specific -// alias basic type named "byte" (and analogous for "rune"). -var Typ = []*Basic{ - Invalid: {Invalid, 0, "invalid type"}, - - Bool: {Bool, IsBoolean, "bool"}, - Int: {Int, IsInteger, "int"}, - Int8: {Int8, IsInteger, "int8"}, - Int16: {Int16, IsInteger, "int16"}, - Int32: {Int32, IsInteger, "int32"}, - Int64: {Int64, IsInteger, "int64"}, - Uint: {Uint, IsInteger | IsUnsigned, "uint"}, - Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"}, - Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"}, - Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"}, - Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"}, - Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"}, - Float32: {Float32, IsFloat, "float32"}, - Float64: {Float64, IsFloat, "float64"}, - Complex64: {Complex64, IsComplex, "complex64"}, - Complex128: {Complex128, IsComplex, "complex128"}, - String: {String, IsString, "string"}, - UnsafePointer: {UnsafePointer, 0, "Pointer"}, - - UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"}, - UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"}, - UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"}, - UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"}, - UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"}, - UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"}, - UntypedNil: {UntypedNil, IsUntyped, "untyped nil"}, -} - -var aliases = [...]*Basic{ - {Byte, IsInteger | IsUnsigned, "byte"}, - {Rune, IsInteger, "rune"}, -} - -func defPredeclaredTypes() { - for _, t := range Typ { - def(NewTypeName(token.NoPos, nil, t.name, t)) - } - for _, t := range aliases { - def(NewTypeName(token.NoPos, nil, t.name, t)) - } - - // Error has a nil package in its qualified name since it is in no package - res := NewVar(token.NoPos, nil, "", Typ[String]) - sig := &Signature{results: NewTuple(res)} - err := NewFunc(token.NoPos, nil, "Error", sig) - typ := &Named{underlying: NewInterface([]*Func{err}, nil).Complete()} - sig.recv = NewVar(token.NoPos, nil, "", typ) - def(NewTypeName(token.NoPos, nil, "error", typ)) -} - -var predeclaredConsts = [...]struct { - name string - kind BasicKind - val constant.Value -}{ - {"true", UntypedBool, constant.MakeBool(true)}, - {"false", UntypedBool, constant.MakeBool(false)}, - {"iota", UntypedInt, constant.MakeInt64(0)}, -} - -func defPredeclaredConsts() { - for _, c := range predeclaredConsts { - def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val)) - } -} - -func defPredeclaredNil() { - def(&Nil{object{name: "nil", typ: Typ[UntypedNil]}}) -} - -// A builtinId is the id of a builtin function. -type builtinId int - -const ( - // universe scope - _Append builtinId = iota - _Cap - _Close - _Complex - _Copy - _Delete - _Imag - _Len - _Make - _New - _Panic - _Print - _Println - _Real - _Recover - - // package unsafe - _Alignof - _Offsetof - _Sizeof - - // testing support - _Assert - _Trace -) - -var predeclaredFuncs = [...]struct { - name string - nargs int - variadic bool - kind exprKind -}{ - _Append: {"append", 1, true, expression}, - _Cap: {"cap", 1, false, expression}, - _Close: {"close", 1, false, statement}, - _Complex: {"complex", 2, false, expression}, - _Copy: {"copy", 2, false, statement}, - _Delete: {"delete", 2, false, statement}, - _Imag: {"imag", 1, false, expression}, - _Len: {"len", 1, false, expression}, - _Make: {"make", 1, true, expression}, - _New: {"new", 1, false, expression}, - _Panic: {"panic", 1, false, statement}, - _Print: {"print", 0, true, statement}, - _Println: {"println", 0, true, statement}, - _Real: {"real", 1, false, expression}, - _Recover: {"recover", 0, false, statement}, - - _Alignof: {"Alignof", 1, false, expression}, - _Offsetof: {"Offsetof", 1, false, expression}, - _Sizeof: {"Sizeof", 1, false, expression}, - - _Assert: {"assert", 1, false, statement}, - _Trace: {"trace", 0, true, statement}, -} - -func defPredeclaredFuncs() { - for i := range predeclaredFuncs { - id := builtinId(i) - if id == _Assert || id == _Trace { - continue // only define these in testing environment - } - def(newBuiltin(id)) - } -} - -// DefPredeclaredTestFuncs defines the assert and trace built-ins. -// These built-ins are intended for debugging and testing of this -// package only. -func DefPredeclaredTestFuncs() { - if Universe.Lookup("assert") != nil { - return // already defined - } - def(newBuiltin(_Assert)) - def(newBuiltin(_Trace)) -} - -func init() { - Universe = NewScope(nil, token.NoPos, token.NoPos, "universe") - Unsafe = NewPackage("unsafe", "unsafe") - Unsafe.complete = true - - defPredeclaredTypes() - defPredeclaredConsts() - defPredeclaredNil() - defPredeclaredFuncs() - - universeIota = Universe.Lookup("iota").(*Const) - universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic) - universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic) -} - -// Objects with names containing blanks are internal and not entered into -// a scope. Objects with exported names are inserted in the unsafe package -// scope; other objects are inserted in the universe scope. -// -func def(obj Object) { - name := obj.Name() - if strings.Contains(name, " ") { - return // nothing to do - } - // fix Obj link for named types - if typ, ok := obj.Type().(*Named); ok { - typ.obj = obj.(*TypeName) - } - // exported identifiers go into package unsafe - scope := Universe - if obj.Exported() { - scope = Unsafe.scope - // set Pkg field - switch obj := obj.(type) { - case *TypeName: - obj.pkg = Unsafe - case *Builtin: - obj.pkg = Unsafe - default: - unreachable() - } - } - if scope.Insert(obj) != nil { - panic("internal error: double declaration") - } -} diff --git a/test/typecheck/srcimporter/BUILD b/third_party/go-srcimporter/BUILD similarity index 76% rename from test/typecheck/srcimporter/BUILD rename to third_party/go-srcimporter/BUILD index b28cfb53aa7ec..9ac17a8f3c5e4 100644 --- a/test/typecheck/srcimporter/BUILD +++ b/third_party/go-srcimporter/BUILD @@ -1,11 +1,12 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") +licenses(["notice"]) + go_library( name = "go_default_library", srcs = ["srcimporter.go"], - importpath = "k8s.io/kubernetes/test/typecheck/srcimporter", + importpath = "k8s.io/kubernetes/third_party/go-srcimporter", visibility = ["//visibility:public"], - deps = ["//third_party/forked/golang/go/types:go_default_library"], ) filegroup( diff --git a/third_party/go-srcimporter/LICENSE b/third_party/go-srcimporter/LICENSE new file mode 100644 index 0000000000000..6a66aea5eafe0 --- /dev/null +++ b/third_party/go-srcimporter/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/go-srcimporter/OWNERS b/third_party/go-srcimporter/OWNERS new file mode 100644 index 0000000000000..e40fb6bb55575 --- /dev/null +++ b/third_party/go-srcimporter/OWNERS @@ -0,0 +1,6 @@ +reviewers: + - cblecker + - rmmh +approvers: + - cblecker + - rmmh diff --git a/third_party/go-srcimporter/README.kubernetes b/third_party/go-srcimporter/README.kubernetes new file mode 100644 index 0000000000000..81f0a53023f53 --- /dev/null +++ b/third_party/go-srcimporter/README.kubernetes @@ -0,0 +1,4 @@ +Files copied from https://github.com/golang/go/blob/5f0a9ba1342674b3209c13035b5aa39a96dbd80c/src/go/internal/srcimporter/srcimporter.go at commit 5f0a9ba1342674b3209c13035b5aa39a96dbd80c. + +Used in k8s.io/kubernetes/test/typecheck. Need to copy here, as it's marked as a go/internal library. +Only modification is to remove the go/internal/srcimporter import alias. diff --git a/test/typecheck/srcimporter/srcimporter.go b/third_party/go-srcimporter/srcimporter.go similarity index 71% rename from test/typecheck/srcimporter/srcimporter.go rename to third_party/go-srcimporter/srcimporter.go index c9fd84af2fd8e..3743e078b931a 100644 --- a/test/typecheck/srcimporter/srcimporter.go +++ b/third_party/go-srcimporter/srcimporter.go @@ -1,21 +1,3 @@ -/* -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. -*/ - -// Forked from go's go/internal/srcimporter - // Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -30,10 +12,11 @@ import ( "go/build" "go/parser" "go/token" + "go/types" + "io" + "os" "path/filepath" "sync" - - "k8s.io/kubernetes/third_party/forked/golang/go/types" ) // An Importer provides the context for importing packages from source code. @@ -44,7 +27,7 @@ type Importer struct { packages map[string]*types.Package } -// New returns a new Importer for the given context, file set, and map +// NewImporter returns a new Importer for the given context, file set, and map // of packages. The context is used to resolve import paths to package paths, // and identifying the files belonging to the package. If the context provides // non-nil file system functions, they are used instead of the regular package @@ -63,9 +46,9 @@ func New(ctxt *build.Context, fset *token.FileSet, packages map[string]*types.Pa // for a package that is in the process of being imported. var importing types.Package -// Import (path) is a shortcut for ImportFrom(path, "", 0). +// Import(path) is a shortcut for ImportFrom(path, ".", 0). func (p *Importer) Import(path string) (*types.Package, error) { - return p.ImportFrom(path, "", 0) + return p.ImportFrom(path, ".", 0) // use "." rather than "" (see issue #24441) } // ImportFrom imports the package with the given import path resolved from the given srcDir, @@ -79,23 +62,10 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type panic("non-zero import mode") } - // determine package path (do vendor resolution) - var bp *build.Package - var err error - switch { - default: - if abs, err := p.absPath(srcDir); err == nil { // see issue #14282 - srcDir = abs - } - bp, err = p.ctxt.Import(path, srcDir, build.FindOnly) - - case build.IsLocalImport(path): - // "./x" -> "srcDir/x" - bp, err = p.ctxt.ImportDir(filepath.Join(srcDir, path), build.FindOnly) - - case p.isAbsPath(path): - return nil, fmt.Errorf("invalid absolute import path %q", path) + if abs, err := p.absPath(srcDir); err == nil { // see issue #14282 + srcDir = abs } + bp, err := p.ctxt.Import(path, srcDir, 0) if err != nil { return nil, err // err may be *build.NoGoError - return as is } @@ -132,11 +102,6 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type } }() - // collect package files - bp, err = p.ctxt.ImportDir(bp.Dir, 0) - if err != nil { - return nil, err // err may be *build.NoGoError - return as is - } var filenames []string filenames = append(filenames, bp.GoFiles...) filenames = append(filenames, bp.CgoFiles...) @@ -181,7 +146,11 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type } func (p *Importer) parseFiles(dir string, filenames []string) ([]*ast.File, error) { - open := p.ctxt.OpenFile // possibly nil + // use build.Context's OpenFile if there is one + open := p.ctxt.OpenFile + if open == nil { + open = func(name string) (io.ReadCloser, error) { return os.Open(name) } + } files := make([]*ast.File, len(filenames)) errors := make([]error, len(filenames)) @@ -191,22 +160,13 @@ func (p *Importer) parseFiles(dir string, filenames []string) ([]*ast.File, erro for i, filename := range filenames { go func(i int, filepath string) { defer wg.Done() - if open != nil { - src, err := open(filepath) - if err != nil { - errors[i] = fmt.Errorf("opening package file %s failed (%v)", filepath, err) - return - } - files[i], errors[i] = parser.ParseFile(p.fset, filepath, src, 0) - src.Close() // ignore Close error - parsing may have succeeded which is all we need - } else { - // Special-case when ctxt doesn't provide a custom OpenFile and use the - // parser's file reading mechanism directly. This appears to be quite a - // bit faster than opening the file and providing an io.ReaderCloser in - // both cases. - // TODO(gri) investigate performance difference (issue #19281) - files[i], errors[i] = parser.ParseFile(p.fset, filepath, nil, 0) + src, err := open(filepath) + if err != nil { + errors[i] = err // open provides operation and filename in error + return } + files[i], errors[i] = parser.ParseFile(p.fset, filepath, src, 0) + src.Close() // ignore Close error - parsing may have succeeded which is all we need }(i, p.joinPath(dir, filename)) } wg.Wait() diff --git a/vendor/BUILD b/vendor/BUILD index 6fe04641294d1..5d89686d802e9 100644 --- a/vendor/BUILD +++ b/vendor/BUILD @@ -16,6 +16,7 @@ filegroup( "//vendor/cloud.google.com/go/compute/metadata:all-srcs", "//vendor/cloud.google.com/go/internal:all-srcs", "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute:all-srcs", + "//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute:all-srcs", "//vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry:all-srcs", "//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network:all-srcs", "//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage:all-srcs", @@ -59,6 +60,7 @@ filegroup( "//vendor/github.com/bazelbuild/bazel-gazelle/internal/repos:all-srcs", "//vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve:all-srcs", "//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:all-srcs", + "//vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools:all-srcs", "//vendor/github.com/bazelbuild/bazel-gazelle/internal/version:all-srcs", "//vendor/github.com/bazelbuild/bazel-gazelle/internal/walk:all-srcs", "//vendor/github.com/bazelbuild/bazel-gazelle/internal/wspace:all-srcs", @@ -193,6 +195,8 @@ filegroup( "//vendor/github.com/fatih/camelcase:all-srcs", "//vendor/github.com/fsnotify/fsnotify:all-srcs", "//vendor/github.com/ghodss/yaml:all-srcs", + "//vendor/github.com/globalsign/mgo/bson:all-srcs", + "//vendor/github.com/globalsign/mgo/internal/json:all-srcs", "//vendor/github.com/go-ini/ini:all-srcs", "//vendor/github.com/go-openapi/analysis:all-srcs", "//vendor/github.com/go-openapi/errors:all-srcs", @@ -265,6 +269,7 @@ filegroup( "//vendor/github.com/gophercloud/gophercloud:all-srcs", "//vendor/github.com/gorilla/websocket:all-srcs", "//vendor/github.com/gregjones/httpcache:all-srcs", + "//vendor/github.com/grpc-ecosystem/go-grpc-middleware:all-srcs", "//vendor/github.com/grpc-ecosystem/go-grpc-prometheus:all-srcs", "//vendor/github.com/grpc-ecosystem/grpc-gateway/runtime:all-srcs", "//vendor/github.com/grpc-ecosystem/grpc-gateway/utilities:all-srcs", @@ -368,6 +373,9 @@ filegroup( "//vendor/github.com/vmware/photon-controller-go-sdk/photon:all-srcs", "//vendor/github.com/xanzy/go-cloudstack/cloudstack:all-srcs", "//vendor/github.com/xiang90/probing:all-srcs", + "//vendor/go.uber.org/atomic:all-srcs", + "//vendor/go.uber.org/multierr:all-srcs", + "//vendor/go.uber.org/zap:all-srcs", "//vendor/golang.org/x/crypto/bcrypt:all-srcs", "//vendor/golang.org/x/crypto/blowfish:all-srcs", "//vendor/golang.org/x/crypto/cryptobyte:all-srcs", diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/BUILD b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/BUILD index 6a9f486e61f53..6df04e38cd754 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/BUILD +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/BUILD @@ -1,42 +1,3 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "availabilitysets.go", - "client.go", - "disks.go", - "images.go", - "loganalytics.go", - "models.go", - "operations.go", - "snapshots.go", - "usage.go", - "version.go", - "virtualmachineextensionimages.go", - "virtualmachineextensions.go", - "virtualmachineimages.go", - "virtualmachineruncommands.go", - "virtualmachines.go", - "virtualmachinescalesetextensions.go", - "virtualmachinescalesetrollingupgrades.go", - "virtualmachinescalesets.go", - "virtualmachinescalesetvms.go", - "virtualmachinesizes.go", - ], - importmap = "k8s.io/kubernetes/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute", - importpath = "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/Azure/azure-sdk-for-go/version:go_default_library", - "//vendor/github.com/Azure/go-autorest/autorest:go_default_library", - "//vendor/github.com/Azure/go-autorest/autorest/azure:go_default_library", - "//vendor/github.com/Azure/go-autorest/autorest/date:go_default_library", - "//vendor/github.com/Azure/go-autorest/autorest/to:go_default_library", - "//vendor/github.com/Azure/go-autorest/autorest/validation:go_default_library", - ], -) - filegroup( name = "package-srcs", srcs = glob(["**"]), diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/BUILD b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/BUILD new file mode 100644 index 0000000000000..efa5d228da063 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/BUILD @@ -0,0 +1,57 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "availabilitysets.go", + "client.go", + "containerservices.go", + "disks.go", + "galleries.go", + "galleryimages.go", + "galleryimageversions.go", + "images.go", + "loganalytics.go", + "models.go", + "operations.go", + "resourceskus.go", + "snapshots.go", + "usage.go", + "version.go", + "virtualmachineextensionimages.go", + "virtualmachineextensions.go", + "virtualmachineimages.go", + "virtualmachineruncommands.go", + "virtualmachines.go", + "virtualmachinescalesetextensions.go", + "virtualmachinescalesetrollingupgrades.go", + "virtualmachinescalesets.go", + "virtualmachinescalesetvms.go", + "virtualmachinesizes.go", + ], + importmap = "k8s.io/kubernetes/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute", + importpath = "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/Azure/azure-sdk-for-go/version:go_default_library", + "//vendor/github.com/Azure/go-autorest/autorest:go_default_library", + "//vendor/github.com/Azure/go-autorest/autorest/azure:go_default_library", + "//vendor/github.com/Azure/go-autorest/autorest/date:go_default_library", + "//vendor/github.com/Azure/go-autorest/autorest/to:go_default_library", + "//vendor/github.com/Azure/go-autorest/autorest/validation: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/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/availabilitysets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/availabilitysets.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/availabilitysets.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/availabilitysets.go index 095954766e76a..afad9559b6d96 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/availabilitysets.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/availabilitysets.go @@ -74,7 +74,7 @@ func (client AvailabilitySetsClient) CreateOrUpdatePreparer(ctx context.Context, "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -143,7 +143,7 @@ func (client AvailabilitySetsClient) DeletePreparer(ctx context.Context, resourc "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -209,7 +209,7 @@ func (client AvailabilitySetsClient) GetPreparer(ctx context.Context, resourceGr "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -275,7 +275,7 @@ func (client AvailabilitySetsClient) ListPreparer(ctx context.Context, resourceG "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -370,7 +370,7 @@ func (client AvailabilitySetsClient) ListAvailableSizesPreparer(ctx context.Cont "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -433,7 +433,7 @@ func (client AvailabilitySetsClient) ListBySubscriptionPreparer(ctx context.Cont "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -528,7 +528,7 @@ func (client AvailabilitySetsClient) UpdatePreparer(ctx context.Context, resourc "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/client.go similarity index 98% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/client.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/client.go index 49391ea5dd026..b23c9ca74268d 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/client.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/client.go @@ -1,4 +1,4 @@ -// Package compute implements the Azure ARM Compute service API version 2018-04-01. +// Package compute implements the Azure ARM Compute service API version . // // Compute Client package compute diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/containerservices.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/containerservices.go new file mode 100644 index 0000000000000..b16788bfa558c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/containerservices.go @@ -0,0 +1,475 @@ +package compute + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// ContainerServicesClient is the compute Client +type ContainerServicesClient struct { + BaseClient +} + +// NewContainerServicesClient creates an instance of the ContainerServicesClient client. +func NewContainerServicesClient(subscriptionID string) ContainerServicesClient { + return NewContainerServicesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewContainerServicesClientWithBaseURI creates an instance of the ContainerServicesClient client. +func NewContainerServicesClientWithBaseURI(baseURI string, subscriptionID string) ContainerServicesClient { + return ContainerServicesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a container service with the specified configuration of orchestrator, masters, and +// agents. +// Parameters: +// resourceGroupName - the name of the resource group. +// containerServiceName - the name of the container service in the specified subscription and resource group. +// parameters - parameters supplied to the Create or Update a Container Service operation. +func (client ContainerServicesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, containerServiceName string, parameters ContainerService) (result ContainerServicesCreateOrUpdateFuture, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.ContainerServiceProperties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.CustomProfile", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.CustomProfile.Orchestrator", Name: validation.Null, Rule: true, Chain: nil}}}, + {Target: "parameters.ContainerServiceProperties.ServicePrincipalProfile", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.ServicePrincipalProfile.ClientID", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.ContainerServiceProperties.ServicePrincipalProfile.Secret", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "parameters.ContainerServiceProperties.MasterProfile", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.MasterProfile.DNSPrefix", Name: validation.Null, Rule: true, Chain: nil}}}, + {Target: "parameters.ContainerServiceProperties.AgentPoolProfiles", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.ContainerServiceProperties.WindowsProfile", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.WindowsProfile.AdminUsername", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.WindowsProfile.AdminUsername", Name: validation.Pattern, Rule: `^[a-zA-Z0-9]+([._]?[a-zA-Z0-9]+)*$`, Chain: nil}}}, + {Target: "parameters.ContainerServiceProperties.WindowsProfile.AdminPassword", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "parameters.ContainerServiceProperties.LinuxProfile", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.LinuxProfile.AdminUsername", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.LinuxProfile.AdminUsername", Name: validation.Pattern, Rule: `^[a-z][a-z0-9_-]*$`, Chain: nil}}}, + {Target: "parameters.ContainerServiceProperties.LinuxProfile.SSH", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.LinuxProfile.SSH.PublicKeys", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + {Target: "parameters.ContainerServiceProperties.DiagnosticsProfile", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.DiagnosticsProfile.VMDiagnostics", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.ContainerServiceProperties.DiagnosticsProfile.VMDiagnostics.Enabled", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + }}}}}); err != nil { + return result, validation.NewError("compute.ContainerServicesClient", "CreateOrUpdate", err.Error()) + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, containerServiceName, parameters) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + result, err = client.CreateOrUpdateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "CreateOrUpdate", result.Response(), "Failure sending request") + return + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ContainerServicesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, containerServiceName string, parameters ContainerService) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "containerServiceName": autorest.Encode("path", containerServiceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-01-31" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerService/containerServices/{containerServiceName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerServicesClient) CreateOrUpdateSender(req *http.Request) (future ContainerServicesCreateOrUpdateFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ContainerServicesClient) CreateOrUpdateResponder(resp *http.Response) (result ContainerService, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes the specified container service in the specified subscription and resource group. The operation does +// not delete other resources created as part of creating a container service, including storage accounts, VMs, and +// availability sets. All the other resources created with the container service are part of the same resource group +// and can be deleted individually. +// Parameters: +// resourceGroupName - the name of the resource group. +// containerServiceName - the name of the container service in the specified subscription and resource group. +func (client ContainerServicesClient) Delete(ctx context.Context, resourceGroupName string, containerServiceName string) (result ContainerServicesDeleteFuture, err error) { + req, err := client.DeletePreparer(ctx, resourceGroupName, containerServiceName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = client.DeleteSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "Delete", result.Response(), "Failure sending request") + return + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ContainerServicesClient) DeletePreparer(ctx context.Context, resourceGroupName string, containerServiceName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "containerServiceName": autorest.Encode("path", containerServiceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-01-31" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerService/containerServices/{containerServiceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerServicesClient) DeleteSender(req *http.Request) (future ContainerServicesDeleteFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ContainerServicesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets the properties of the specified container service in the specified subscription and resource group. The +// operation returns the properties including state, orchestrator, number of masters and agents, and FQDNs of masters +// and agents. +// Parameters: +// resourceGroupName - the name of the resource group. +// containerServiceName - the name of the container service in the specified subscription and resource group. +func (client ContainerServicesClient) Get(ctx context.Context, resourceGroupName string, containerServiceName string) (result ContainerService, err error) { + req, err := client.GetPreparer(ctx, resourceGroupName, containerServiceName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ContainerServicesClient) GetPreparer(ctx context.Context, resourceGroupName string, containerServiceName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "containerServiceName": autorest.Encode("path", containerServiceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-01-31" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerService/containerServices/{containerServiceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerServicesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ContainerServicesClient) GetResponder(resp *http.Response) (result ContainerService, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of container services in the specified subscription. The operation returns properties of each +// container service including state, orchestrator, number of masters and agents, and FQDNs of masters and agents. +func (client ContainerServicesClient) List(ctx context.Context) (result ContainerServiceListResultPage, err error) { + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.cslr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "List", resp, "Failure sending request") + return + } + + result.cslr, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ContainerServicesClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-01-31" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.ContainerService/containerServices", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerServicesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ContainerServicesClient) ListResponder(resp *http.Response) (result ContainerServiceListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client ContainerServicesClient) listNextResults(lastResults ContainerServiceListResult) (result ContainerServiceListResult, err error) { + req, err := lastResults.containerServiceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client ContainerServicesClient) ListComplete(ctx context.Context) (result ContainerServiceListResultIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// ListByResourceGroup gets a list of container services in the specified subscription and resource group. The +// operation returns properties of each container service including state, orchestrator, number of masters and agents, +// and FQDNs of masters and agents. +// Parameters: +// resourceGroupName - the name of the resource group. +func (client ContainerServicesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result ContainerServiceListResultPage, err error) { + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.cslr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result.cslr, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client ContainerServicesClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-01-31" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerService/containerServices", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerServicesClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client ContainerServicesClient) ListByResourceGroupResponder(resp *http.Response) (result ContainerServiceListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client ContainerServicesClient) listByResourceGroupNextResults(lastResults ContainerServiceListResult) (result ContainerServiceListResult, err error) { + req, err := lastResults.containerServiceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client ContainerServicesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string) (result ContainerServiceListResultIterator, err error) { + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/disks.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/disks.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/disks.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/disks.go index cdc570377d011..9cbbd79fd6fc4 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/disks.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/disks.go @@ -92,7 +92,7 @@ func (client DisksClient) CreateOrUpdatePreparer(ctx context.Context, resourceGr "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -167,7 +167,7 @@ func (client DisksClient) DeletePreparer(ctx context.Context, resourceGroupName "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -245,7 +245,7 @@ func (client DisksClient) GetPreparer(ctx context.Context, resourceGroupName str "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -315,7 +315,7 @@ func (client DisksClient) GrantAccessPreparer(ctx context.Context, resourceGroup "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -390,7 +390,7 @@ func (client DisksClient) ListPreparer(ctx context.Context) (*http.Request, erro "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -483,7 +483,7 @@ func (client DisksClient) ListByResourceGroupPreparer(ctx context.Context, resou "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -573,7 +573,7 @@ func (client DisksClient) RevokeAccessPreparer(ctx context.Context, resourceGrou "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -646,7 +646,7 @@ func (client DisksClient) UpdatePreparer(ctx context.Context, resourceGroupName "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleries.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleries.go new file mode 100644 index 0000000000000..bc550686859f2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleries.go @@ -0,0 +1,435 @@ +package compute + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// GalleriesClient is the compute Client +type GalleriesClient struct { + BaseClient +} + +// NewGalleriesClient creates an instance of the GalleriesClient client. +func NewGalleriesClient(subscriptionID string) GalleriesClient { + return NewGalleriesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewGalleriesClientWithBaseURI creates an instance of the GalleriesClient client. +func NewGalleriesClientWithBaseURI(baseURI string, subscriptionID string) GalleriesClient { + return GalleriesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate create or update a Shared Image Gallery. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery. The allowed characters are alphabets and numbers with +// dots and periods allowed in the middle. The maximum length is 80 characters. +// gallery - parameters supplied to the create or update Shared Image Gallery operation. +func (client GalleriesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, galleryName string, gallery Gallery) (result GalleriesCreateOrUpdateFuture, err error) { + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, galleryName, gallery) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + result, err = client.CreateOrUpdateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "CreateOrUpdate", result.Response(), "Failure sending request") + return + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client GalleriesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, galleryName string, gallery Gallery) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}", pathParameters), + autorest.WithJSON(gallery), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client GalleriesClient) CreateOrUpdateSender(req *http.Request) (future GalleriesCreateOrUpdateFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client GalleriesClient) CreateOrUpdateResponder(resp *http.Response) (result Gallery, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete delete a Shared Image Gallery. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery to be deleted. +func (client GalleriesClient) Delete(ctx context.Context, resourceGroupName string, galleryName string) (result GalleriesDeleteFuture, err error) { + req, err := client.DeletePreparer(ctx, resourceGroupName, galleryName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = client.DeleteSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "Delete", result.Response(), "Failure sending request") + return + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client GalleriesClient) DeletePreparer(ctx context.Context, resourceGroupName string, galleryName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client GalleriesClient) DeleteSender(req *http.Request) (future GalleriesDeleteFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client GalleriesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get retrieves information about a Shared Image Gallery. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery. +func (client GalleriesClient) Get(ctx context.Context, resourceGroupName string, galleryName string) (result Gallery, err error) { + req, err := client.GetPreparer(ctx, resourceGroupName, galleryName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client GalleriesClient) GetPreparer(ctx context.Context, resourceGroupName string, galleryName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client GalleriesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client GalleriesClient) GetResponder(resp *http.Response) (result Gallery, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List list galleries under a subscription. +func (client GalleriesClient) List(ctx context.Context) (result GalleryListPage, err error) { + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.gl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "List", resp, "Failure sending request") + return + } + + result.gl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client GalleriesClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/galleries", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client GalleriesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client GalleriesClient) ListResponder(resp *http.Response) (result GalleryList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client GalleriesClient) listNextResults(lastResults GalleryList) (result GalleryList, err error) { + req, err := lastResults.galleryListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.GalleriesClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.GalleriesClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client GalleriesClient) ListComplete(ctx context.Context) (result GalleryListIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// ListByResourceGroup list galleries under a resource group. +// Parameters: +// resourceGroupName - the name of the resource group. +func (client GalleriesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result GalleryListPage, err error) { + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.gl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result.gl, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client GalleriesClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client GalleriesClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client GalleriesClient) ListByResourceGroupResponder(resp *http.Response) (result GalleryList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client GalleriesClient) listByResourceGroupNextResults(lastResults GalleryList) (result GalleryList, err error) { + req, err := lastResults.galleryListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.GalleriesClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.GalleriesClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client GalleriesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string) (result GalleryListIterator, err error) { + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleryimages.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleryimages.go new file mode 100644 index 0000000000000..670ea7ee29a3d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleryimages.go @@ -0,0 +1,367 @@ +package compute + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// GalleryImagesClient is the compute Client +type GalleryImagesClient struct { + BaseClient +} + +// NewGalleryImagesClient creates an instance of the GalleryImagesClient client. +func NewGalleryImagesClient(subscriptionID string) GalleryImagesClient { + return NewGalleryImagesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewGalleryImagesClientWithBaseURI creates an instance of the GalleryImagesClient client. +func NewGalleryImagesClientWithBaseURI(baseURI string, subscriptionID string) GalleryImagesClient { + return GalleryImagesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate create or update a gallery Image Definition. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery in which the Image Definition is to be created. +// galleryImageName - the name of the gallery Image Definition to be created or updated. The allowed characters +// are alphabets and numbers with dots, dashes, and periods allowed in the middle. The maximum length is 80 +// characters. +// galleryImage - parameters supplied to the create or update gallery image operation. +func (client GalleryImagesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string, galleryImage GalleryImage) (result GalleryImagesCreateOrUpdateFuture, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: galleryImage, + Constraints: []validation.Constraint{{Target: "galleryImage.GalleryImageProperties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "galleryImage.GalleryImageProperties.Identifier", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "galleryImage.GalleryImageProperties.Identifier.Publisher", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "galleryImage.GalleryImageProperties.Identifier.Offer", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "galleryImage.GalleryImageProperties.Identifier.Sku", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}}}}); err != nil { + return result, validation.NewError("compute.GalleryImagesClient", "CreateOrUpdate", err.Error()) + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, galleryName, galleryImageName, galleryImage) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + result, err = client.CreateOrUpdateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "CreateOrUpdate", result.Response(), "Failure sending request") + return + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client GalleryImagesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string, galleryImage GalleryImage) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryImageName": autorest.Encode("path", galleryImageName), + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{galleryImageName}", pathParameters), + autorest.WithJSON(galleryImage), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client GalleryImagesClient) CreateOrUpdateSender(req *http.Request) (future GalleryImagesCreateOrUpdateFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client GalleryImagesClient) CreateOrUpdateResponder(resp *http.Response) (result GalleryImage, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete delete a gallery image. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery in which the Image Definition is to be deleted. +// galleryImageName - the name of the gallery Image Definition to be deleted. +func (client GalleryImagesClient) Delete(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string) (result GalleryImagesDeleteFuture, err error) { + req, err := client.DeletePreparer(ctx, resourceGroupName, galleryName, galleryImageName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = client.DeleteSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "Delete", result.Response(), "Failure sending request") + return + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client GalleryImagesClient) DeletePreparer(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryImageName": autorest.Encode("path", galleryImageName), + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{galleryImageName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client GalleryImagesClient) DeleteSender(req *http.Request) (future GalleryImagesDeleteFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client GalleryImagesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get retrieves information about a gallery Image Definition. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery from which the Image Definitions are to be retrieved. +// galleryImageName - the name of the gallery Image Definition to be retrieved. +func (client GalleryImagesClient) Get(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string) (result GalleryImage, err error) { + req, err := client.GetPreparer(ctx, resourceGroupName, galleryName, galleryImageName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client GalleryImagesClient) GetPreparer(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryImageName": autorest.Encode("path", galleryImageName), + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{galleryImageName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client GalleryImagesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client GalleryImagesClient) GetResponder(resp *http.Response) (result GalleryImage, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByGallery list gallery Image Definitions in a gallery. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery from which Image Definitions are to be listed. +func (client GalleryImagesClient) ListByGallery(ctx context.Context, resourceGroupName string, galleryName string) (result GalleryImageListPage, err error) { + result.fn = client.listByGalleryNextResults + req, err := client.ListByGalleryPreparer(ctx, resourceGroupName, galleryName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "ListByGallery", nil, "Failure preparing request") + return + } + + resp, err := client.ListByGallerySender(req) + if err != nil { + result.gil.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "ListByGallery", resp, "Failure sending request") + return + } + + result.gil, err = client.ListByGalleryResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "ListByGallery", resp, "Failure responding to request") + } + + return +} + +// ListByGalleryPreparer prepares the ListByGallery request. +func (client GalleryImagesClient) ListByGalleryPreparer(ctx context.Context, resourceGroupName string, galleryName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/images", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByGallerySender sends the ListByGallery request. The method will close the +// http.Response Body if it receives an error. +func (client GalleryImagesClient) ListByGallerySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByGalleryResponder handles the response to the ListByGallery request. The method always +// closes the http.Response Body. +func (client GalleryImagesClient) ListByGalleryResponder(resp *http.Response) (result GalleryImageList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByGalleryNextResults retrieves the next set of results, if any. +func (client GalleryImagesClient) listByGalleryNextResults(lastResults GalleryImageList) (result GalleryImageList, err error) { + req, err := lastResults.galleryImageListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "listByGalleryNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByGallerySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "listByGalleryNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByGalleryResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesClient", "listByGalleryNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByGalleryComplete enumerates all values, automatically crossing page boundaries as required. +func (client GalleryImagesClient) ListByGalleryComplete(ctx context.Context, resourceGroupName string, galleryName string) (result GalleryImageListIterator, err error) { + result.page, err = client.ListByGallery(ctx, resourceGroupName, galleryName) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleryimageversions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleryimageversions.go new file mode 100644 index 0000000000000..d179443ade515 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/galleryimageversions.go @@ -0,0 +1,375 @@ +package compute + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// GalleryImageVersionsClient is the compute Client +type GalleryImageVersionsClient struct { + BaseClient +} + +// NewGalleryImageVersionsClient creates an instance of the GalleryImageVersionsClient client. +func NewGalleryImageVersionsClient(subscriptionID string) GalleryImageVersionsClient { + return NewGalleryImageVersionsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewGalleryImageVersionsClientWithBaseURI creates an instance of the GalleryImageVersionsClient client. +func NewGalleryImageVersionsClientWithBaseURI(baseURI string, subscriptionID string) GalleryImageVersionsClient { + return GalleryImageVersionsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate create or update a gallery Image Version. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery in which the Image Definition resides. +// galleryImageName - the name of the gallery Image Definition in which the Image Version is to be created. +// galleryImageVersionName - the name of the gallery Image Version to be created. Needs to follow semantic +// version name pattern: The allowed characters are digit and period. Digits must be within the range of a +// 32-bit integer. Format: .. +// galleryImageVersion - parameters supplied to the create or update gallery Image Version operation. +func (client GalleryImageVersionsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string, galleryImageVersionName string, galleryImageVersion GalleryImageVersion) (result GalleryImageVersionsCreateOrUpdateFuture, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: galleryImageVersion, + Constraints: []validation.Constraint{{Target: "galleryImageVersion.GalleryImageVersionProperties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "galleryImageVersion.GalleryImageVersionProperties.PublishingProfile", Name: validation.Null, Rule: true, Chain: nil}}}}}}); err != nil { + return result, validation.NewError("compute.GalleryImageVersionsClient", "CreateOrUpdate", err.Error()) + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, galleryName, galleryImageName, galleryImageVersionName, galleryImageVersion) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + result, err = client.CreateOrUpdateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "CreateOrUpdate", result.Response(), "Failure sending request") + return + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client GalleryImageVersionsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string, galleryImageVersionName string, galleryImageVersion GalleryImageVersion) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryImageName": autorest.Encode("path", galleryImageName), + "galleryImageVersionName": autorest.Encode("path", galleryImageVersionName), + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{galleryImageName}/versions/{galleryImageVersionName}", pathParameters), + autorest.WithJSON(galleryImageVersion), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client GalleryImageVersionsClient) CreateOrUpdateSender(req *http.Request) (future GalleryImageVersionsCreateOrUpdateFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client GalleryImageVersionsClient) CreateOrUpdateResponder(resp *http.Response) (result GalleryImageVersion, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete delete a gallery Image Version. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery in which the Image Definition resides. +// galleryImageName - the name of the gallery Image Definition in which the Image Version resides. +// galleryImageVersionName - the name of the gallery Image Version to be deleted. +func (client GalleryImageVersionsClient) Delete(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string, galleryImageVersionName string) (result GalleryImageVersionsDeleteFuture, err error) { + req, err := client.DeletePreparer(ctx, resourceGroupName, galleryName, galleryImageName, galleryImageVersionName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = client.DeleteSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "Delete", result.Response(), "Failure sending request") + return + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client GalleryImageVersionsClient) DeletePreparer(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string, galleryImageVersionName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryImageName": autorest.Encode("path", galleryImageName), + "galleryImageVersionName": autorest.Encode("path", galleryImageVersionName), + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{galleryImageName}/versions/{galleryImageVersionName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client GalleryImageVersionsClient) DeleteSender(req *http.Request) (future GalleryImageVersionsDeleteFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client GalleryImageVersionsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get retrieves information about a gallery Image Version. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery in which the Image Definition resides. +// galleryImageName - the name of the gallery Image Definition in which the Image Version resides. +// galleryImageVersionName - the name of the gallery Image Version to be retrieved. +// expand - the expand expression to apply on the operation. +func (client GalleryImageVersionsClient) Get(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string, galleryImageVersionName string, expand ReplicationStatusTypes) (result GalleryImageVersion, err error) { + req, err := client.GetPreparer(ctx, resourceGroupName, galleryName, galleryImageName, galleryImageVersionName, expand) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client GalleryImageVersionsClient) GetPreparer(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string, galleryImageVersionName string, expand ReplicationStatusTypes) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryImageName": autorest.Encode("path", galleryImageName), + "galleryImageVersionName": autorest.Encode("path", galleryImageVersionName), + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(string(expand)) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{galleryImageName}/versions/{galleryImageVersionName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client GalleryImageVersionsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client GalleryImageVersionsClient) GetResponder(resp *http.Response) (result GalleryImageVersion, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByGalleryImage list gallery Image Versions in a gallery Image Definition. +// Parameters: +// resourceGroupName - the name of the resource group. +// galleryName - the name of the Shared Image Gallery in which the Image Definition resides. +// galleryImageName - the name of the Shared Image Gallery Image Definition from which the Image Versions are +// to be listed. +func (client GalleryImageVersionsClient) ListByGalleryImage(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string) (result GalleryImageVersionListPage, err error) { + result.fn = client.listByGalleryImageNextResults + req, err := client.ListByGalleryImagePreparer(ctx, resourceGroupName, galleryName, galleryImageName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "ListByGalleryImage", nil, "Failure preparing request") + return + } + + resp, err := client.ListByGalleryImageSender(req) + if err != nil { + result.givl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "ListByGalleryImage", resp, "Failure sending request") + return + } + + result.givl, err = client.ListByGalleryImageResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "ListByGalleryImage", resp, "Failure responding to request") + } + + return +} + +// ListByGalleryImagePreparer prepares the ListByGalleryImage request. +func (client GalleryImageVersionsClient) ListByGalleryImagePreparer(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "galleryImageName": autorest.Encode("path", galleryImageName), + "galleryName": autorest.Encode("path", galleryName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2018-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{galleryImageName}/versions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByGalleryImageSender sends the ListByGalleryImage request. The method will close the +// http.Response Body if it receives an error. +func (client GalleryImageVersionsClient) ListByGalleryImageSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByGalleryImageResponder handles the response to the ListByGalleryImage request. The method always +// closes the http.Response Body. +func (client GalleryImageVersionsClient) ListByGalleryImageResponder(resp *http.Response) (result GalleryImageVersionList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByGalleryImageNextResults retrieves the next set of results, if any. +func (client GalleryImageVersionsClient) listByGalleryImageNextResults(lastResults GalleryImageVersionList) (result GalleryImageVersionList, err error) { + req, err := lastResults.galleryImageVersionListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "listByGalleryImageNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByGalleryImageSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "listByGalleryImageNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByGalleryImageResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsClient", "listByGalleryImageNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByGalleryImageComplete enumerates all values, automatically crossing page boundaries as required. +func (client GalleryImageVersionsClient) ListByGalleryImageComplete(ctx context.Context, resourceGroupName string, galleryName string, galleryImageName string) (result GalleryImageVersionListIterator, err error) { + result.page, err = client.ListByGalleryImage(ctx, resourceGroupName, galleryName, galleryImageName) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/images.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/images.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/images.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/images.go index f468d6fd0c3f8..2afe53551f0bc 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/images.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/images.go @@ -68,7 +68,7 @@ func (client ImagesClient) CreateOrUpdatePreparer(ctx context.Context, resourceG "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -141,7 +141,7 @@ func (client ImagesClient) DeletePreparer(ctx context.Context, resourceGroupName "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -218,7 +218,7 @@ func (client ImagesClient) GetPreparer(ctx context.Context, resourceGroupName st "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -285,7 +285,7 @@ func (client ImagesClient) ListPreparer(ctx context.Context) (*http.Request, err "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -378,7 +378,7 @@ func (client ImagesClient) ListByResourceGroupPreparer(ctx context.Context, reso "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -467,7 +467,7 @@ func (client ImagesClient) UpdatePreparer(ctx context.Context, resourceGroupName "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/loganalytics.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/loganalytics.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/loganalytics.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/loganalytics.go index e958f84b10033..f72c02202e3c0 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/loganalytics.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/loganalytics.go @@ -74,7 +74,7 @@ func (client LogAnalyticsClient) ExportRequestRateByIntervalPreparer(ctx context "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -153,7 +153,7 @@ func (client LogAnalyticsClient) ExportThrottledRequestsPreparer(ctx context.Con "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/models.go similarity index 71% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/models.go index cc4bc867323ba..6499e4d052a35 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/models.go @@ -41,6 +41,40 @@ func PossibleAccessLevelValues() []AccessLevel { return []AccessLevel{None, Read} } +// AggregatedReplicationState enumerates the values for aggregated replication state. +type AggregatedReplicationState string + +const ( + // Completed ... + Completed AggregatedReplicationState = "Completed" + // Failed ... + Failed AggregatedReplicationState = "Failed" + // InProgress ... + InProgress AggregatedReplicationState = "InProgress" + // Unknown ... + Unknown AggregatedReplicationState = "Unknown" +) + +// PossibleAggregatedReplicationStateValues returns an array of possible values for the AggregatedReplicationState const type. +func PossibleAggregatedReplicationStateValues() []AggregatedReplicationState { + return []AggregatedReplicationState{Completed, Failed, InProgress, Unknown} +} + +// AvailabilitySetSkuTypes enumerates the values for availability set sku types. +type AvailabilitySetSkuTypes string + +const ( + // Aligned ... + Aligned AvailabilitySetSkuTypes = "Aligned" + // Classic ... + Classic AvailabilitySetSkuTypes = "Classic" +) + +// PossibleAvailabilitySetSkuTypesValues returns an array of possible values for the AvailabilitySetSkuTypes const type. +func PossibleAvailabilitySetSkuTypesValues() []AvailabilitySetSkuTypes { + return []AvailabilitySetSkuTypes{Aligned, Classic} +} + // CachingTypes enumerates the values for caching types. type CachingTypes string @@ -71,6 +105,143 @@ func PossibleComponentNamesValues() []ComponentNames { return []ComponentNames{MicrosoftWindowsShellSetup} } +// ContainerServiceOrchestratorTypes enumerates the values for container service orchestrator types. +type ContainerServiceOrchestratorTypes string + +const ( + // Custom ... + Custom ContainerServiceOrchestratorTypes = "Custom" + // DCOS ... + DCOS ContainerServiceOrchestratorTypes = "DCOS" + // Kubernetes ... + Kubernetes ContainerServiceOrchestratorTypes = "Kubernetes" + // Swarm ... + Swarm ContainerServiceOrchestratorTypes = "Swarm" +) + +// PossibleContainerServiceOrchestratorTypesValues returns an array of possible values for the ContainerServiceOrchestratorTypes const type. +func PossibleContainerServiceOrchestratorTypesValues() []ContainerServiceOrchestratorTypes { + return []ContainerServiceOrchestratorTypes{Custom, DCOS, Kubernetes, Swarm} +} + +// ContainerServiceVMSizeTypes enumerates the values for container service vm size types. +type ContainerServiceVMSizeTypes string + +const ( + // StandardA0 ... + StandardA0 ContainerServiceVMSizeTypes = "Standard_A0" + // StandardA1 ... + StandardA1 ContainerServiceVMSizeTypes = "Standard_A1" + // StandardA10 ... + StandardA10 ContainerServiceVMSizeTypes = "Standard_A10" + // StandardA11 ... + StandardA11 ContainerServiceVMSizeTypes = "Standard_A11" + // StandardA2 ... + StandardA2 ContainerServiceVMSizeTypes = "Standard_A2" + // StandardA3 ... + StandardA3 ContainerServiceVMSizeTypes = "Standard_A3" + // StandardA4 ... + StandardA4 ContainerServiceVMSizeTypes = "Standard_A4" + // StandardA5 ... + StandardA5 ContainerServiceVMSizeTypes = "Standard_A5" + // StandardA6 ... + StandardA6 ContainerServiceVMSizeTypes = "Standard_A6" + // StandardA7 ... + StandardA7 ContainerServiceVMSizeTypes = "Standard_A7" + // StandardA8 ... + StandardA8 ContainerServiceVMSizeTypes = "Standard_A8" + // StandardA9 ... + StandardA9 ContainerServiceVMSizeTypes = "Standard_A9" + // StandardD1 ... + StandardD1 ContainerServiceVMSizeTypes = "Standard_D1" + // StandardD11 ... + StandardD11 ContainerServiceVMSizeTypes = "Standard_D11" + // StandardD11V2 ... + StandardD11V2 ContainerServiceVMSizeTypes = "Standard_D11_v2" + // StandardD12 ... + StandardD12 ContainerServiceVMSizeTypes = "Standard_D12" + // StandardD12V2 ... + StandardD12V2 ContainerServiceVMSizeTypes = "Standard_D12_v2" + // StandardD13 ... + StandardD13 ContainerServiceVMSizeTypes = "Standard_D13" + // StandardD13V2 ... + StandardD13V2 ContainerServiceVMSizeTypes = "Standard_D13_v2" + // StandardD14 ... + StandardD14 ContainerServiceVMSizeTypes = "Standard_D14" + // StandardD14V2 ... + StandardD14V2 ContainerServiceVMSizeTypes = "Standard_D14_v2" + // StandardD1V2 ... + StandardD1V2 ContainerServiceVMSizeTypes = "Standard_D1_v2" + // StandardD2 ... + StandardD2 ContainerServiceVMSizeTypes = "Standard_D2" + // StandardD2V2 ... + StandardD2V2 ContainerServiceVMSizeTypes = "Standard_D2_v2" + // StandardD3 ... + StandardD3 ContainerServiceVMSizeTypes = "Standard_D3" + // StandardD3V2 ... + StandardD3V2 ContainerServiceVMSizeTypes = "Standard_D3_v2" + // StandardD4 ... + StandardD4 ContainerServiceVMSizeTypes = "Standard_D4" + // StandardD4V2 ... + StandardD4V2 ContainerServiceVMSizeTypes = "Standard_D4_v2" + // StandardD5V2 ... + StandardD5V2 ContainerServiceVMSizeTypes = "Standard_D5_v2" + // StandardDS1 ... + StandardDS1 ContainerServiceVMSizeTypes = "Standard_DS1" + // StandardDS11 ... + StandardDS11 ContainerServiceVMSizeTypes = "Standard_DS11" + // StandardDS12 ... + StandardDS12 ContainerServiceVMSizeTypes = "Standard_DS12" + // StandardDS13 ... + StandardDS13 ContainerServiceVMSizeTypes = "Standard_DS13" + // StandardDS14 ... + StandardDS14 ContainerServiceVMSizeTypes = "Standard_DS14" + // StandardDS2 ... + StandardDS2 ContainerServiceVMSizeTypes = "Standard_DS2" + // StandardDS3 ... + StandardDS3 ContainerServiceVMSizeTypes = "Standard_DS3" + // StandardDS4 ... + StandardDS4 ContainerServiceVMSizeTypes = "Standard_DS4" + // StandardG1 ... + StandardG1 ContainerServiceVMSizeTypes = "Standard_G1" + // StandardG2 ... + StandardG2 ContainerServiceVMSizeTypes = "Standard_G2" + // StandardG3 ... + StandardG3 ContainerServiceVMSizeTypes = "Standard_G3" + // StandardG4 ... + StandardG4 ContainerServiceVMSizeTypes = "Standard_G4" + // StandardG5 ... + StandardG5 ContainerServiceVMSizeTypes = "Standard_G5" + // StandardGS1 ... + StandardGS1 ContainerServiceVMSizeTypes = "Standard_GS1" + // StandardGS2 ... + StandardGS2 ContainerServiceVMSizeTypes = "Standard_GS2" + // StandardGS3 ... + StandardGS3 ContainerServiceVMSizeTypes = "Standard_GS3" + // StandardGS4 ... + StandardGS4 ContainerServiceVMSizeTypes = "Standard_GS4" + // StandardGS5 ... + StandardGS5 ContainerServiceVMSizeTypes = "Standard_GS5" +) + +// PossibleContainerServiceVMSizeTypesValues returns an array of possible values for the ContainerServiceVMSizeTypes const type. +func PossibleContainerServiceVMSizeTypesValues() []ContainerServiceVMSizeTypes { + return []ContainerServiceVMSizeTypes{StandardA0, StandardA1, StandardA10, StandardA11, StandardA2, StandardA3, StandardA4, StandardA5, StandardA6, StandardA7, StandardA8, StandardA9, StandardD1, StandardD11, StandardD11V2, StandardD12, StandardD12V2, StandardD13, StandardD13V2, StandardD14, StandardD14V2, StandardD1V2, StandardD2, StandardD2V2, StandardD3, StandardD3V2, StandardD4, StandardD4V2, StandardD5V2, StandardDS1, StandardDS11, StandardDS12, StandardDS13, StandardDS14, StandardDS2, StandardDS3, StandardDS4, StandardG1, StandardG2, StandardG3, StandardG4, StandardG5, StandardGS1, StandardGS2, StandardGS3, StandardGS4, StandardGS5} +} + +// DiffDiskOptions enumerates the values for diff disk options. +type DiffDiskOptions string + +const ( + // Local ... + Local DiffDiskOptions = "Local" +) + +// PossibleDiffDiskOptionsValues returns an array of possible values for the DiffDiskOptions const type. +func PossibleDiffDiskOptionsValues() []DiffDiskOptions { + return []DiffDiskOptions{Local} +} + // DiskCreateOption enumerates the values for disk create option. type DiskCreateOption string @@ -111,6 +282,42 @@ func PossibleDiskCreateOptionTypesValues() []DiskCreateOptionTypes { return []DiskCreateOptionTypes{DiskCreateOptionTypesAttach, DiskCreateOptionTypesEmpty, DiskCreateOptionTypesFromImage} } +// DiskStorageAccountTypes enumerates the values for disk storage account types. +type DiskStorageAccountTypes string + +const ( + // PremiumLRS ... + PremiumLRS DiskStorageAccountTypes = "Premium_LRS" + // StandardLRS ... + StandardLRS DiskStorageAccountTypes = "Standard_LRS" + // StandardSSDLRS ... + StandardSSDLRS DiskStorageAccountTypes = "StandardSSD_LRS" + // UltraSSDLRS ... + UltraSSDLRS DiskStorageAccountTypes = "UltraSSD_LRS" +) + +// PossibleDiskStorageAccountTypesValues returns an array of possible values for the DiskStorageAccountTypes const type. +func PossibleDiskStorageAccountTypesValues() []DiskStorageAccountTypes { + return []DiskStorageAccountTypes{PremiumLRS, StandardLRS, StandardSSDLRS, UltraSSDLRS} +} + +// HostCaching enumerates the values for host caching. +type HostCaching string + +const ( + // HostCachingNone ... + HostCachingNone HostCaching = "None" + // HostCachingReadOnly ... + HostCachingReadOnly HostCaching = "ReadOnly" + // HostCachingReadWrite ... + HostCachingReadWrite HostCaching = "ReadWrite" +) + +// PossibleHostCachingValues returns an array of possible values for the HostCaching const type. +func PossibleHostCachingValues() []HostCaching { + return []HostCaching{HostCachingNone, HostCachingReadOnly, HostCachingReadWrite} +} + // InstanceViewTypes enumerates the values for instance view types. type InstanceViewTypes string @@ -235,6 +442,107 @@ func PossibleProtocolTypesValues() []ProtocolTypes { return []ProtocolTypes{HTTP, HTTPS} } +// ProvisioningState enumerates the values for provisioning state. +type ProvisioningState string + +const ( + // ProvisioningStateCreating ... + ProvisioningStateCreating ProvisioningState = "Creating" + // ProvisioningStateDeleting ... + ProvisioningStateDeleting ProvisioningState = "Deleting" + // ProvisioningStateFailed ... + ProvisioningStateFailed ProvisioningState = "Failed" + // ProvisioningStateMigrating ... + ProvisioningStateMigrating ProvisioningState = "Migrating" + // ProvisioningStateSucceeded ... + ProvisioningStateSucceeded ProvisioningState = "Succeeded" + // ProvisioningStateUpdating ... + ProvisioningStateUpdating ProvisioningState = "Updating" +) + +// PossibleProvisioningStateValues returns an array of possible values for the ProvisioningState const type. +func PossibleProvisioningStateValues() []ProvisioningState { + return []ProvisioningState{ProvisioningStateCreating, ProvisioningStateDeleting, ProvisioningStateFailed, ProvisioningStateMigrating, ProvisioningStateSucceeded, ProvisioningStateUpdating} +} + +// ProvisioningState1 enumerates the values for provisioning state 1. +type ProvisioningState1 string + +const ( + // ProvisioningState1Creating ... + ProvisioningState1Creating ProvisioningState1 = "Creating" + // ProvisioningState1Deleting ... + ProvisioningState1Deleting ProvisioningState1 = "Deleting" + // ProvisioningState1Failed ... + ProvisioningState1Failed ProvisioningState1 = "Failed" + // ProvisioningState1Migrating ... + ProvisioningState1Migrating ProvisioningState1 = "Migrating" + // ProvisioningState1Succeeded ... + ProvisioningState1Succeeded ProvisioningState1 = "Succeeded" + // ProvisioningState1Updating ... + ProvisioningState1Updating ProvisioningState1 = "Updating" +) + +// PossibleProvisioningState1Values returns an array of possible values for the ProvisioningState1 const type. +func PossibleProvisioningState1Values() []ProvisioningState1 { + return []ProvisioningState1{ProvisioningState1Creating, ProvisioningState1Deleting, ProvisioningState1Failed, ProvisioningState1Migrating, ProvisioningState1Succeeded, ProvisioningState1Updating} +} + +// ProvisioningState2 enumerates the values for provisioning state 2. +type ProvisioningState2 string + +const ( + // ProvisioningState2Creating ... + ProvisioningState2Creating ProvisioningState2 = "Creating" + // ProvisioningState2Deleting ... + ProvisioningState2Deleting ProvisioningState2 = "Deleting" + // ProvisioningState2Failed ... + ProvisioningState2Failed ProvisioningState2 = "Failed" + // ProvisioningState2Migrating ... + ProvisioningState2Migrating ProvisioningState2 = "Migrating" + // ProvisioningState2Succeeded ... + ProvisioningState2Succeeded ProvisioningState2 = "Succeeded" + // ProvisioningState2Updating ... + ProvisioningState2Updating ProvisioningState2 = "Updating" +) + +// PossibleProvisioningState2Values returns an array of possible values for the ProvisioningState2 const type. +func PossibleProvisioningState2Values() []ProvisioningState2 { + return []ProvisioningState2{ProvisioningState2Creating, ProvisioningState2Deleting, ProvisioningState2Failed, ProvisioningState2Migrating, ProvisioningState2Succeeded, ProvisioningState2Updating} +} + +// ReplicationState enumerates the values for replication state. +type ReplicationState string + +const ( + // ReplicationStateCompleted ... + ReplicationStateCompleted ReplicationState = "Completed" + // ReplicationStateFailed ... + ReplicationStateFailed ReplicationState = "Failed" + // ReplicationStateReplicating ... + ReplicationStateReplicating ReplicationState = "Replicating" + // ReplicationStateUnknown ... + ReplicationStateUnknown ReplicationState = "Unknown" +) + +// PossibleReplicationStateValues returns an array of possible values for the ReplicationState const type. +func PossibleReplicationStateValues() []ReplicationState { + return []ReplicationState{ReplicationStateCompleted, ReplicationStateFailed, ReplicationStateReplicating, ReplicationStateUnknown} +} + +// ReplicationStatusTypes enumerates the values for replication status types. +type ReplicationStatusTypes string + +const ( + // ReplicationStatusTypesReplicationStatus ... + ReplicationStatusTypesReplicationStatus ReplicationStatusTypes = "ReplicationStatus" +) + +// PossibleReplicationStatusTypesValues returns an array of possible values for the ReplicationStatusTypes const type. +func PossibleReplicationStatusTypesValues() []ReplicationStatusTypes { + return []ReplicationStatusTypes{ReplicationStatusTypesReplicationStatus} +} + // ResourceIdentityType enumerates the values for resource identity type. type ResourceIdentityType string @@ -254,6 +562,53 @@ func PossibleResourceIdentityTypeValues() []ResourceIdentityType { return []ResourceIdentityType{ResourceIdentityTypeNone, ResourceIdentityTypeSystemAssigned, ResourceIdentityTypeSystemAssignedUserAssigned, ResourceIdentityTypeUserAssigned} } +// ResourceSkuCapacityScaleType enumerates the values for resource sku capacity scale type. +type ResourceSkuCapacityScaleType string + +const ( + // ResourceSkuCapacityScaleTypeAutomatic ... + ResourceSkuCapacityScaleTypeAutomatic ResourceSkuCapacityScaleType = "Automatic" + // ResourceSkuCapacityScaleTypeManual ... + ResourceSkuCapacityScaleTypeManual ResourceSkuCapacityScaleType = "Manual" + // ResourceSkuCapacityScaleTypeNone ... + ResourceSkuCapacityScaleTypeNone ResourceSkuCapacityScaleType = "None" +) + +// PossibleResourceSkuCapacityScaleTypeValues returns an array of possible values for the ResourceSkuCapacityScaleType const type. +func PossibleResourceSkuCapacityScaleTypeValues() []ResourceSkuCapacityScaleType { + return []ResourceSkuCapacityScaleType{ResourceSkuCapacityScaleTypeAutomatic, ResourceSkuCapacityScaleTypeManual, ResourceSkuCapacityScaleTypeNone} +} + +// ResourceSkuRestrictionsReasonCode enumerates the values for resource sku restrictions reason code. +type ResourceSkuRestrictionsReasonCode string + +const ( + // NotAvailableForSubscription ... + NotAvailableForSubscription ResourceSkuRestrictionsReasonCode = "NotAvailableForSubscription" + // QuotaID ... + QuotaID ResourceSkuRestrictionsReasonCode = "QuotaId" +) + +// PossibleResourceSkuRestrictionsReasonCodeValues returns an array of possible values for the ResourceSkuRestrictionsReasonCode const type. +func PossibleResourceSkuRestrictionsReasonCodeValues() []ResourceSkuRestrictionsReasonCode { + return []ResourceSkuRestrictionsReasonCode{NotAvailableForSubscription, QuotaID} +} + +// ResourceSkuRestrictionsType enumerates the values for resource sku restrictions type. +type ResourceSkuRestrictionsType string + +const ( + // Location ... + Location ResourceSkuRestrictionsType = "Location" + // Zone ... + Zone ResourceSkuRestrictionsType = "Zone" +) + +// PossibleResourceSkuRestrictionsTypeValues returns an array of possible values for the ResourceSkuRestrictionsType const type. +func PossibleResourceSkuRestrictionsTypeValues() []ResourceSkuRestrictionsType { + return []ResourceSkuRestrictionsType{Location, Zone} +} + // RollingUpgradeActionType enumerates the values for rolling upgrade action type. type RollingUpgradeActionType string @@ -273,19 +628,19 @@ func PossibleRollingUpgradeActionTypeValues() []RollingUpgradeActionType { type RollingUpgradeStatusCode string const ( - // Cancelled ... - Cancelled RollingUpgradeStatusCode = "Cancelled" - // Completed ... - Completed RollingUpgradeStatusCode = "Completed" - // Faulted ... - Faulted RollingUpgradeStatusCode = "Faulted" - // RollingForward ... - RollingForward RollingUpgradeStatusCode = "RollingForward" + // RollingUpgradeStatusCodeCancelled ... + RollingUpgradeStatusCodeCancelled RollingUpgradeStatusCode = "Cancelled" + // RollingUpgradeStatusCodeCompleted ... + RollingUpgradeStatusCodeCompleted RollingUpgradeStatusCode = "Completed" + // RollingUpgradeStatusCodeFaulted ... + RollingUpgradeStatusCodeFaulted RollingUpgradeStatusCode = "Faulted" + // RollingUpgradeStatusCodeRollingForward ... + RollingUpgradeStatusCodeRollingForward RollingUpgradeStatusCode = "RollingForward" ) // PossibleRollingUpgradeStatusCodeValues returns an array of possible values for the RollingUpgradeStatusCode const type. func PossibleRollingUpgradeStatusCodeValues() []RollingUpgradeStatusCode { - return []RollingUpgradeStatusCode{Cancelled, Completed, Faulted, RollingForward} + return []RollingUpgradeStatusCode{RollingUpgradeStatusCodeCancelled, RollingUpgradeStatusCodeCompleted, RollingUpgradeStatusCodeFaulted, RollingUpgradeStatusCodeRollingForward} } // SettingNames enumerates the values for setting names. @@ -307,17 +662,17 @@ func PossibleSettingNamesValues() []SettingNames { type SnapshotStorageAccountTypes string const ( - // PremiumLRS ... - PremiumLRS SnapshotStorageAccountTypes = "Premium_LRS" - // StandardLRS ... - StandardLRS SnapshotStorageAccountTypes = "Standard_LRS" - // StandardZRS ... - StandardZRS SnapshotStorageAccountTypes = "Standard_ZRS" + // SnapshotStorageAccountTypesPremiumLRS ... + SnapshotStorageAccountTypesPremiumLRS SnapshotStorageAccountTypes = "Premium_LRS" + // SnapshotStorageAccountTypesStandardLRS ... + SnapshotStorageAccountTypesStandardLRS SnapshotStorageAccountTypes = "Standard_LRS" + // SnapshotStorageAccountTypesStandardZRS ... + SnapshotStorageAccountTypesStandardZRS SnapshotStorageAccountTypes = "Standard_ZRS" ) // PossibleSnapshotStorageAccountTypesValues returns an array of possible values for the SnapshotStorageAccountTypes const type. func PossibleSnapshotStorageAccountTypesValues() []SnapshotStorageAccountTypes { - return []SnapshotStorageAccountTypes{PremiumLRS, StandardLRS, StandardZRS} + return []SnapshotStorageAccountTypes{SnapshotStorageAccountTypesPremiumLRS, SnapshotStorageAccountTypesStandardLRS, SnapshotStorageAccountTypesStandardZRS} } // StatusLevelTypes enumerates the values for status level types. @@ -347,11 +702,13 @@ const ( StorageAccountTypesStandardLRS StorageAccountTypes = "Standard_LRS" // StorageAccountTypesStandardSSDLRS ... StorageAccountTypesStandardSSDLRS StorageAccountTypes = "StandardSSD_LRS" + // StorageAccountTypesUltraSSDLRS ... + StorageAccountTypesUltraSSDLRS StorageAccountTypes = "UltraSSD_LRS" ) // PossibleStorageAccountTypesValues returns an array of possible values for the StorageAccountTypes const type. func PossibleStorageAccountTypesValues() []StorageAccountTypes { - return []StorageAccountTypes{StorageAccountTypesPremiumLRS, StorageAccountTypesStandardLRS, StorageAccountTypesStandardSSDLRS} + return []StorageAccountTypes{StorageAccountTypesPremiumLRS, StorageAccountTypesStandardLRS, StorageAccountTypesStandardSSDLRS, StorageAccountTypesUltraSSDLRS} } // UpgradeMode enumerates the values for upgrade mode. @@ -375,17 +732,17 @@ func PossibleUpgradeModeValues() []UpgradeMode { type UpgradeOperationInvoker string const ( - // Platform ... - Platform UpgradeOperationInvoker = "Platform" - // Unknown ... - Unknown UpgradeOperationInvoker = "Unknown" - // User ... - User UpgradeOperationInvoker = "User" + // UpgradeOperationInvokerPlatform ... + UpgradeOperationInvokerPlatform UpgradeOperationInvoker = "Platform" + // UpgradeOperationInvokerUnknown ... + UpgradeOperationInvokerUnknown UpgradeOperationInvoker = "Unknown" + // UpgradeOperationInvokerUser ... + UpgradeOperationInvokerUser UpgradeOperationInvoker = "User" ) // PossibleUpgradeOperationInvokerValues returns an array of possible values for the UpgradeOperationInvoker const type. func PossibleUpgradeOperationInvokerValues() []UpgradeOperationInvoker { - return []UpgradeOperationInvoker{Platform, Unknown, User} + return []UpgradeOperationInvoker{UpgradeOperationInvokerPlatform, UpgradeOperationInvokerUnknown, UpgradeOperationInvokerUser} } // UpgradeState enumerates the values for upgrade state. @@ -456,343 +813,343 @@ func PossibleVirtualMachineScaleSetSkuScaleTypeValues() []VirtualMachineScaleSet type VirtualMachineSizeTypes string const ( - // BasicA0 ... - BasicA0 VirtualMachineSizeTypes = "Basic_A0" - // BasicA1 ... - BasicA1 VirtualMachineSizeTypes = "Basic_A1" - // BasicA2 ... - BasicA2 VirtualMachineSizeTypes = "Basic_A2" - // BasicA3 ... - BasicA3 VirtualMachineSizeTypes = "Basic_A3" - // BasicA4 ... - BasicA4 VirtualMachineSizeTypes = "Basic_A4" - // StandardA0 ... - StandardA0 VirtualMachineSizeTypes = "Standard_A0" - // StandardA1 ... - StandardA1 VirtualMachineSizeTypes = "Standard_A1" - // StandardA10 ... - StandardA10 VirtualMachineSizeTypes = "Standard_A10" - // StandardA11 ... - StandardA11 VirtualMachineSizeTypes = "Standard_A11" - // StandardA1V2 ... - StandardA1V2 VirtualMachineSizeTypes = "Standard_A1_v2" - // StandardA2 ... - StandardA2 VirtualMachineSizeTypes = "Standard_A2" - // StandardA2mV2 ... - StandardA2mV2 VirtualMachineSizeTypes = "Standard_A2m_v2" - // StandardA2V2 ... - StandardA2V2 VirtualMachineSizeTypes = "Standard_A2_v2" - // StandardA3 ... - StandardA3 VirtualMachineSizeTypes = "Standard_A3" - // StandardA4 ... - StandardA4 VirtualMachineSizeTypes = "Standard_A4" - // StandardA4mV2 ... - StandardA4mV2 VirtualMachineSizeTypes = "Standard_A4m_v2" - // StandardA4V2 ... - StandardA4V2 VirtualMachineSizeTypes = "Standard_A4_v2" - // StandardA5 ... - StandardA5 VirtualMachineSizeTypes = "Standard_A5" - // StandardA6 ... - StandardA6 VirtualMachineSizeTypes = "Standard_A6" - // StandardA7 ... - StandardA7 VirtualMachineSizeTypes = "Standard_A7" - // StandardA8 ... - StandardA8 VirtualMachineSizeTypes = "Standard_A8" - // StandardA8mV2 ... - StandardA8mV2 VirtualMachineSizeTypes = "Standard_A8m_v2" - // StandardA8V2 ... - StandardA8V2 VirtualMachineSizeTypes = "Standard_A8_v2" - // StandardA9 ... - StandardA9 VirtualMachineSizeTypes = "Standard_A9" - // StandardB1ms ... - StandardB1ms VirtualMachineSizeTypes = "Standard_B1ms" - // StandardB1s ... - StandardB1s VirtualMachineSizeTypes = "Standard_B1s" - // StandardB2ms ... - StandardB2ms VirtualMachineSizeTypes = "Standard_B2ms" - // StandardB2s ... - StandardB2s VirtualMachineSizeTypes = "Standard_B2s" - // StandardB4ms ... - StandardB4ms VirtualMachineSizeTypes = "Standard_B4ms" - // StandardB8ms ... - StandardB8ms VirtualMachineSizeTypes = "Standard_B8ms" - // StandardD1 ... - StandardD1 VirtualMachineSizeTypes = "Standard_D1" - // StandardD11 ... - StandardD11 VirtualMachineSizeTypes = "Standard_D11" - // StandardD11V2 ... - StandardD11V2 VirtualMachineSizeTypes = "Standard_D11_v2" - // StandardD12 ... - StandardD12 VirtualMachineSizeTypes = "Standard_D12" - // StandardD12V2 ... - StandardD12V2 VirtualMachineSizeTypes = "Standard_D12_v2" - // StandardD13 ... - StandardD13 VirtualMachineSizeTypes = "Standard_D13" - // StandardD13V2 ... - StandardD13V2 VirtualMachineSizeTypes = "Standard_D13_v2" - // StandardD14 ... - StandardD14 VirtualMachineSizeTypes = "Standard_D14" - // StandardD14V2 ... - StandardD14V2 VirtualMachineSizeTypes = "Standard_D14_v2" - // StandardD15V2 ... - StandardD15V2 VirtualMachineSizeTypes = "Standard_D15_v2" - // StandardD16sV3 ... - StandardD16sV3 VirtualMachineSizeTypes = "Standard_D16s_v3" - // StandardD16V3 ... - StandardD16V3 VirtualMachineSizeTypes = "Standard_D16_v3" - // StandardD1V2 ... - StandardD1V2 VirtualMachineSizeTypes = "Standard_D1_v2" - // StandardD2 ... - StandardD2 VirtualMachineSizeTypes = "Standard_D2" - // StandardD2sV3 ... - StandardD2sV3 VirtualMachineSizeTypes = "Standard_D2s_v3" - // StandardD2V2 ... - StandardD2V2 VirtualMachineSizeTypes = "Standard_D2_v2" - // StandardD2V3 ... - StandardD2V3 VirtualMachineSizeTypes = "Standard_D2_v3" - // StandardD3 ... - StandardD3 VirtualMachineSizeTypes = "Standard_D3" - // StandardD32sV3 ... - StandardD32sV3 VirtualMachineSizeTypes = "Standard_D32s_v3" - // StandardD32V3 ... - StandardD32V3 VirtualMachineSizeTypes = "Standard_D32_v3" - // StandardD3V2 ... - StandardD3V2 VirtualMachineSizeTypes = "Standard_D3_v2" - // StandardD4 ... - StandardD4 VirtualMachineSizeTypes = "Standard_D4" - // StandardD4sV3 ... - StandardD4sV3 VirtualMachineSizeTypes = "Standard_D4s_v3" - // StandardD4V2 ... - StandardD4V2 VirtualMachineSizeTypes = "Standard_D4_v2" - // StandardD4V3 ... - StandardD4V3 VirtualMachineSizeTypes = "Standard_D4_v3" - // StandardD5V2 ... - StandardD5V2 VirtualMachineSizeTypes = "Standard_D5_v2" - // StandardD64sV3 ... - StandardD64sV3 VirtualMachineSizeTypes = "Standard_D64s_v3" - // StandardD64V3 ... - StandardD64V3 VirtualMachineSizeTypes = "Standard_D64_v3" - // StandardD8sV3 ... - StandardD8sV3 VirtualMachineSizeTypes = "Standard_D8s_v3" - // StandardD8V3 ... - StandardD8V3 VirtualMachineSizeTypes = "Standard_D8_v3" - // StandardDS1 ... - StandardDS1 VirtualMachineSizeTypes = "Standard_DS1" - // StandardDS11 ... - StandardDS11 VirtualMachineSizeTypes = "Standard_DS11" - // StandardDS11V2 ... - StandardDS11V2 VirtualMachineSizeTypes = "Standard_DS11_v2" - // StandardDS12 ... - StandardDS12 VirtualMachineSizeTypes = "Standard_DS12" - // StandardDS12V2 ... - StandardDS12V2 VirtualMachineSizeTypes = "Standard_DS12_v2" - // StandardDS13 ... - StandardDS13 VirtualMachineSizeTypes = "Standard_DS13" - // StandardDS132V2 ... - StandardDS132V2 VirtualMachineSizeTypes = "Standard_DS13-2_v2" - // StandardDS134V2 ... - StandardDS134V2 VirtualMachineSizeTypes = "Standard_DS13-4_v2" - // StandardDS13V2 ... - StandardDS13V2 VirtualMachineSizeTypes = "Standard_DS13_v2" - // StandardDS14 ... - StandardDS14 VirtualMachineSizeTypes = "Standard_DS14" - // StandardDS144V2 ... - StandardDS144V2 VirtualMachineSizeTypes = "Standard_DS14-4_v2" - // StandardDS148V2 ... - StandardDS148V2 VirtualMachineSizeTypes = "Standard_DS14-8_v2" - // StandardDS14V2 ... - StandardDS14V2 VirtualMachineSizeTypes = "Standard_DS14_v2" - // StandardDS15V2 ... - StandardDS15V2 VirtualMachineSizeTypes = "Standard_DS15_v2" - // StandardDS1V2 ... - StandardDS1V2 VirtualMachineSizeTypes = "Standard_DS1_v2" - // StandardDS2 ... - StandardDS2 VirtualMachineSizeTypes = "Standard_DS2" - // StandardDS2V2 ... - StandardDS2V2 VirtualMachineSizeTypes = "Standard_DS2_v2" - // StandardDS3 ... - StandardDS3 VirtualMachineSizeTypes = "Standard_DS3" - // StandardDS3V2 ... - StandardDS3V2 VirtualMachineSizeTypes = "Standard_DS3_v2" - // StandardDS4 ... - StandardDS4 VirtualMachineSizeTypes = "Standard_DS4" - // StandardDS4V2 ... - StandardDS4V2 VirtualMachineSizeTypes = "Standard_DS4_v2" - // StandardDS5V2 ... - StandardDS5V2 VirtualMachineSizeTypes = "Standard_DS5_v2" - // StandardE16sV3 ... - StandardE16sV3 VirtualMachineSizeTypes = "Standard_E16s_v3" - // StandardE16V3 ... - StandardE16V3 VirtualMachineSizeTypes = "Standard_E16_v3" - // StandardE2sV3 ... - StandardE2sV3 VirtualMachineSizeTypes = "Standard_E2s_v3" - // StandardE2V3 ... - StandardE2V3 VirtualMachineSizeTypes = "Standard_E2_v3" - // StandardE3216V3 ... - StandardE3216V3 VirtualMachineSizeTypes = "Standard_E32-16_v3" - // StandardE328sV3 ... - StandardE328sV3 VirtualMachineSizeTypes = "Standard_E32-8s_v3" - // StandardE32sV3 ... - StandardE32sV3 VirtualMachineSizeTypes = "Standard_E32s_v3" - // StandardE32V3 ... - StandardE32V3 VirtualMachineSizeTypes = "Standard_E32_v3" - // StandardE4sV3 ... - StandardE4sV3 VirtualMachineSizeTypes = "Standard_E4s_v3" - // StandardE4V3 ... - StandardE4V3 VirtualMachineSizeTypes = "Standard_E4_v3" - // StandardE6416sV3 ... - StandardE6416sV3 VirtualMachineSizeTypes = "Standard_E64-16s_v3" - // StandardE6432sV3 ... - StandardE6432sV3 VirtualMachineSizeTypes = "Standard_E64-32s_v3" - // StandardE64sV3 ... - StandardE64sV3 VirtualMachineSizeTypes = "Standard_E64s_v3" - // StandardE64V3 ... - StandardE64V3 VirtualMachineSizeTypes = "Standard_E64_v3" - // StandardE8sV3 ... - StandardE8sV3 VirtualMachineSizeTypes = "Standard_E8s_v3" - // StandardE8V3 ... - StandardE8V3 VirtualMachineSizeTypes = "Standard_E8_v3" - // StandardF1 ... - StandardF1 VirtualMachineSizeTypes = "Standard_F1" - // StandardF16 ... - StandardF16 VirtualMachineSizeTypes = "Standard_F16" - // StandardF16s ... - StandardF16s VirtualMachineSizeTypes = "Standard_F16s" - // StandardF16sV2 ... - StandardF16sV2 VirtualMachineSizeTypes = "Standard_F16s_v2" - // StandardF1s ... - StandardF1s VirtualMachineSizeTypes = "Standard_F1s" - // StandardF2 ... - StandardF2 VirtualMachineSizeTypes = "Standard_F2" - // StandardF2s ... - StandardF2s VirtualMachineSizeTypes = "Standard_F2s" - // StandardF2sV2 ... - StandardF2sV2 VirtualMachineSizeTypes = "Standard_F2s_v2" - // StandardF32sV2 ... - StandardF32sV2 VirtualMachineSizeTypes = "Standard_F32s_v2" - // StandardF4 ... - StandardF4 VirtualMachineSizeTypes = "Standard_F4" - // StandardF4s ... - StandardF4s VirtualMachineSizeTypes = "Standard_F4s" - // StandardF4sV2 ... - StandardF4sV2 VirtualMachineSizeTypes = "Standard_F4s_v2" - // StandardF64sV2 ... - StandardF64sV2 VirtualMachineSizeTypes = "Standard_F64s_v2" - // StandardF72sV2 ... - StandardF72sV2 VirtualMachineSizeTypes = "Standard_F72s_v2" - // StandardF8 ... - StandardF8 VirtualMachineSizeTypes = "Standard_F8" - // StandardF8s ... - StandardF8s VirtualMachineSizeTypes = "Standard_F8s" - // StandardF8sV2 ... - StandardF8sV2 VirtualMachineSizeTypes = "Standard_F8s_v2" - // StandardG1 ... - StandardG1 VirtualMachineSizeTypes = "Standard_G1" - // StandardG2 ... - StandardG2 VirtualMachineSizeTypes = "Standard_G2" - // StandardG3 ... - StandardG3 VirtualMachineSizeTypes = "Standard_G3" - // StandardG4 ... - StandardG4 VirtualMachineSizeTypes = "Standard_G4" - // StandardG5 ... - StandardG5 VirtualMachineSizeTypes = "Standard_G5" - // StandardGS1 ... - StandardGS1 VirtualMachineSizeTypes = "Standard_GS1" - // StandardGS2 ... - StandardGS2 VirtualMachineSizeTypes = "Standard_GS2" - // StandardGS3 ... - StandardGS3 VirtualMachineSizeTypes = "Standard_GS3" - // StandardGS4 ... - StandardGS4 VirtualMachineSizeTypes = "Standard_GS4" - // StandardGS44 ... - StandardGS44 VirtualMachineSizeTypes = "Standard_GS4-4" - // StandardGS48 ... - StandardGS48 VirtualMachineSizeTypes = "Standard_GS4-8" - // StandardGS5 ... - StandardGS5 VirtualMachineSizeTypes = "Standard_GS5" - // StandardGS516 ... - StandardGS516 VirtualMachineSizeTypes = "Standard_GS5-16" - // StandardGS58 ... - StandardGS58 VirtualMachineSizeTypes = "Standard_GS5-8" - // StandardH16 ... - StandardH16 VirtualMachineSizeTypes = "Standard_H16" - // StandardH16m ... - StandardH16m VirtualMachineSizeTypes = "Standard_H16m" - // StandardH16mr ... - StandardH16mr VirtualMachineSizeTypes = "Standard_H16mr" - // StandardH16r ... - StandardH16r VirtualMachineSizeTypes = "Standard_H16r" - // StandardH8 ... - StandardH8 VirtualMachineSizeTypes = "Standard_H8" - // StandardH8m ... - StandardH8m VirtualMachineSizeTypes = "Standard_H8m" - // StandardL16s ... - StandardL16s VirtualMachineSizeTypes = "Standard_L16s" - // StandardL32s ... - StandardL32s VirtualMachineSizeTypes = "Standard_L32s" - // StandardL4s ... - StandardL4s VirtualMachineSizeTypes = "Standard_L4s" - // StandardL8s ... - StandardL8s VirtualMachineSizeTypes = "Standard_L8s" - // StandardM12832ms ... - StandardM12832ms VirtualMachineSizeTypes = "Standard_M128-32ms" - // StandardM12864ms ... - StandardM12864ms VirtualMachineSizeTypes = "Standard_M128-64ms" - // StandardM128ms ... - StandardM128ms VirtualMachineSizeTypes = "Standard_M128ms" - // StandardM128s ... - StandardM128s VirtualMachineSizeTypes = "Standard_M128s" - // StandardM6416ms ... - StandardM6416ms VirtualMachineSizeTypes = "Standard_M64-16ms" - // StandardM6432ms ... - StandardM6432ms VirtualMachineSizeTypes = "Standard_M64-32ms" - // StandardM64ms ... - StandardM64ms VirtualMachineSizeTypes = "Standard_M64ms" - // StandardM64s ... - StandardM64s VirtualMachineSizeTypes = "Standard_M64s" - // StandardNC12 ... - StandardNC12 VirtualMachineSizeTypes = "Standard_NC12" - // StandardNC12sV2 ... - StandardNC12sV2 VirtualMachineSizeTypes = "Standard_NC12s_v2" - // StandardNC12sV3 ... - StandardNC12sV3 VirtualMachineSizeTypes = "Standard_NC12s_v3" - // StandardNC24 ... - StandardNC24 VirtualMachineSizeTypes = "Standard_NC24" - // StandardNC24r ... - StandardNC24r VirtualMachineSizeTypes = "Standard_NC24r" - // StandardNC24rsV2 ... - StandardNC24rsV2 VirtualMachineSizeTypes = "Standard_NC24rs_v2" - // StandardNC24rsV3 ... - StandardNC24rsV3 VirtualMachineSizeTypes = "Standard_NC24rs_v3" - // StandardNC24sV2 ... - StandardNC24sV2 VirtualMachineSizeTypes = "Standard_NC24s_v2" - // StandardNC24sV3 ... - StandardNC24sV3 VirtualMachineSizeTypes = "Standard_NC24s_v3" - // StandardNC6 ... - StandardNC6 VirtualMachineSizeTypes = "Standard_NC6" - // StandardNC6sV2 ... - StandardNC6sV2 VirtualMachineSizeTypes = "Standard_NC6s_v2" - // StandardNC6sV3 ... - StandardNC6sV3 VirtualMachineSizeTypes = "Standard_NC6s_v3" - // StandardND12s ... - StandardND12s VirtualMachineSizeTypes = "Standard_ND12s" - // StandardND24rs ... - StandardND24rs VirtualMachineSizeTypes = "Standard_ND24rs" - // StandardND24s ... - StandardND24s VirtualMachineSizeTypes = "Standard_ND24s" - // StandardND6s ... - StandardND6s VirtualMachineSizeTypes = "Standard_ND6s" - // StandardNV12 ... - StandardNV12 VirtualMachineSizeTypes = "Standard_NV12" - // StandardNV24 ... - StandardNV24 VirtualMachineSizeTypes = "Standard_NV24" - // StandardNV6 ... - StandardNV6 VirtualMachineSizeTypes = "Standard_NV6" + // VirtualMachineSizeTypesBasicA0 ... + VirtualMachineSizeTypesBasicA0 VirtualMachineSizeTypes = "Basic_A0" + // VirtualMachineSizeTypesBasicA1 ... + VirtualMachineSizeTypesBasicA1 VirtualMachineSizeTypes = "Basic_A1" + // VirtualMachineSizeTypesBasicA2 ... + VirtualMachineSizeTypesBasicA2 VirtualMachineSizeTypes = "Basic_A2" + // VirtualMachineSizeTypesBasicA3 ... + VirtualMachineSizeTypesBasicA3 VirtualMachineSizeTypes = "Basic_A3" + // VirtualMachineSizeTypesBasicA4 ... + VirtualMachineSizeTypesBasicA4 VirtualMachineSizeTypes = "Basic_A4" + // VirtualMachineSizeTypesStandardA0 ... + VirtualMachineSizeTypesStandardA0 VirtualMachineSizeTypes = "Standard_A0" + // VirtualMachineSizeTypesStandardA1 ... + VirtualMachineSizeTypesStandardA1 VirtualMachineSizeTypes = "Standard_A1" + // VirtualMachineSizeTypesStandardA10 ... + VirtualMachineSizeTypesStandardA10 VirtualMachineSizeTypes = "Standard_A10" + // VirtualMachineSizeTypesStandardA11 ... + VirtualMachineSizeTypesStandardA11 VirtualMachineSizeTypes = "Standard_A11" + // VirtualMachineSizeTypesStandardA1V2 ... + VirtualMachineSizeTypesStandardA1V2 VirtualMachineSizeTypes = "Standard_A1_v2" + // VirtualMachineSizeTypesStandardA2 ... + VirtualMachineSizeTypesStandardA2 VirtualMachineSizeTypes = "Standard_A2" + // VirtualMachineSizeTypesStandardA2mV2 ... + VirtualMachineSizeTypesStandardA2mV2 VirtualMachineSizeTypes = "Standard_A2m_v2" + // VirtualMachineSizeTypesStandardA2V2 ... + VirtualMachineSizeTypesStandardA2V2 VirtualMachineSizeTypes = "Standard_A2_v2" + // VirtualMachineSizeTypesStandardA3 ... + VirtualMachineSizeTypesStandardA3 VirtualMachineSizeTypes = "Standard_A3" + // VirtualMachineSizeTypesStandardA4 ... + VirtualMachineSizeTypesStandardA4 VirtualMachineSizeTypes = "Standard_A4" + // VirtualMachineSizeTypesStandardA4mV2 ... + VirtualMachineSizeTypesStandardA4mV2 VirtualMachineSizeTypes = "Standard_A4m_v2" + // VirtualMachineSizeTypesStandardA4V2 ... + VirtualMachineSizeTypesStandardA4V2 VirtualMachineSizeTypes = "Standard_A4_v2" + // VirtualMachineSizeTypesStandardA5 ... + VirtualMachineSizeTypesStandardA5 VirtualMachineSizeTypes = "Standard_A5" + // VirtualMachineSizeTypesStandardA6 ... + VirtualMachineSizeTypesStandardA6 VirtualMachineSizeTypes = "Standard_A6" + // VirtualMachineSizeTypesStandardA7 ... + VirtualMachineSizeTypesStandardA7 VirtualMachineSizeTypes = "Standard_A7" + // VirtualMachineSizeTypesStandardA8 ... + VirtualMachineSizeTypesStandardA8 VirtualMachineSizeTypes = "Standard_A8" + // VirtualMachineSizeTypesStandardA8mV2 ... + VirtualMachineSizeTypesStandardA8mV2 VirtualMachineSizeTypes = "Standard_A8m_v2" + // VirtualMachineSizeTypesStandardA8V2 ... + VirtualMachineSizeTypesStandardA8V2 VirtualMachineSizeTypes = "Standard_A8_v2" + // VirtualMachineSizeTypesStandardA9 ... + VirtualMachineSizeTypesStandardA9 VirtualMachineSizeTypes = "Standard_A9" + // VirtualMachineSizeTypesStandardB1ms ... + VirtualMachineSizeTypesStandardB1ms VirtualMachineSizeTypes = "Standard_B1ms" + // VirtualMachineSizeTypesStandardB1s ... + VirtualMachineSizeTypesStandardB1s VirtualMachineSizeTypes = "Standard_B1s" + // VirtualMachineSizeTypesStandardB2ms ... + VirtualMachineSizeTypesStandardB2ms VirtualMachineSizeTypes = "Standard_B2ms" + // VirtualMachineSizeTypesStandardB2s ... + VirtualMachineSizeTypesStandardB2s VirtualMachineSizeTypes = "Standard_B2s" + // VirtualMachineSizeTypesStandardB4ms ... + VirtualMachineSizeTypesStandardB4ms VirtualMachineSizeTypes = "Standard_B4ms" + // VirtualMachineSizeTypesStandardB8ms ... + VirtualMachineSizeTypesStandardB8ms VirtualMachineSizeTypes = "Standard_B8ms" + // VirtualMachineSizeTypesStandardD1 ... + VirtualMachineSizeTypesStandardD1 VirtualMachineSizeTypes = "Standard_D1" + // VirtualMachineSizeTypesStandardD11 ... + VirtualMachineSizeTypesStandardD11 VirtualMachineSizeTypes = "Standard_D11" + // VirtualMachineSizeTypesStandardD11V2 ... + VirtualMachineSizeTypesStandardD11V2 VirtualMachineSizeTypes = "Standard_D11_v2" + // VirtualMachineSizeTypesStandardD12 ... + VirtualMachineSizeTypesStandardD12 VirtualMachineSizeTypes = "Standard_D12" + // VirtualMachineSizeTypesStandardD12V2 ... + VirtualMachineSizeTypesStandardD12V2 VirtualMachineSizeTypes = "Standard_D12_v2" + // VirtualMachineSizeTypesStandardD13 ... + VirtualMachineSizeTypesStandardD13 VirtualMachineSizeTypes = "Standard_D13" + // VirtualMachineSizeTypesStandardD13V2 ... + VirtualMachineSizeTypesStandardD13V2 VirtualMachineSizeTypes = "Standard_D13_v2" + // VirtualMachineSizeTypesStandardD14 ... + VirtualMachineSizeTypesStandardD14 VirtualMachineSizeTypes = "Standard_D14" + // VirtualMachineSizeTypesStandardD14V2 ... + VirtualMachineSizeTypesStandardD14V2 VirtualMachineSizeTypes = "Standard_D14_v2" + // VirtualMachineSizeTypesStandardD15V2 ... + VirtualMachineSizeTypesStandardD15V2 VirtualMachineSizeTypes = "Standard_D15_v2" + // VirtualMachineSizeTypesStandardD16sV3 ... + VirtualMachineSizeTypesStandardD16sV3 VirtualMachineSizeTypes = "Standard_D16s_v3" + // VirtualMachineSizeTypesStandardD16V3 ... + VirtualMachineSizeTypesStandardD16V3 VirtualMachineSizeTypes = "Standard_D16_v3" + // VirtualMachineSizeTypesStandardD1V2 ... + VirtualMachineSizeTypesStandardD1V2 VirtualMachineSizeTypes = "Standard_D1_v2" + // VirtualMachineSizeTypesStandardD2 ... + VirtualMachineSizeTypesStandardD2 VirtualMachineSizeTypes = "Standard_D2" + // VirtualMachineSizeTypesStandardD2sV3 ... + VirtualMachineSizeTypesStandardD2sV3 VirtualMachineSizeTypes = "Standard_D2s_v3" + // VirtualMachineSizeTypesStandardD2V2 ... + VirtualMachineSizeTypesStandardD2V2 VirtualMachineSizeTypes = "Standard_D2_v2" + // VirtualMachineSizeTypesStandardD2V3 ... + VirtualMachineSizeTypesStandardD2V3 VirtualMachineSizeTypes = "Standard_D2_v3" + // VirtualMachineSizeTypesStandardD3 ... + VirtualMachineSizeTypesStandardD3 VirtualMachineSizeTypes = "Standard_D3" + // VirtualMachineSizeTypesStandardD32sV3 ... + VirtualMachineSizeTypesStandardD32sV3 VirtualMachineSizeTypes = "Standard_D32s_v3" + // VirtualMachineSizeTypesStandardD32V3 ... + VirtualMachineSizeTypesStandardD32V3 VirtualMachineSizeTypes = "Standard_D32_v3" + // VirtualMachineSizeTypesStandardD3V2 ... + VirtualMachineSizeTypesStandardD3V2 VirtualMachineSizeTypes = "Standard_D3_v2" + // VirtualMachineSizeTypesStandardD4 ... + VirtualMachineSizeTypesStandardD4 VirtualMachineSizeTypes = "Standard_D4" + // VirtualMachineSizeTypesStandardD4sV3 ... + VirtualMachineSizeTypesStandardD4sV3 VirtualMachineSizeTypes = "Standard_D4s_v3" + // VirtualMachineSizeTypesStandardD4V2 ... + VirtualMachineSizeTypesStandardD4V2 VirtualMachineSizeTypes = "Standard_D4_v2" + // VirtualMachineSizeTypesStandardD4V3 ... + VirtualMachineSizeTypesStandardD4V3 VirtualMachineSizeTypes = "Standard_D4_v3" + // VirtualMachineSizeTypesStandardD5V2 ... + VirtualMachineSizeTypesStandardD5V2 VirtualMachineSizeTypes = "Standard_D5_v2" + // VirtualMachineSizeTypesStandardD64sV3 ... + VirtualMachineSizeTypesStandardD64sV3 VirtualMachineSizeTypes = "Standard_D64s_v3" + // VirtualMachineSizeTypesStandardD64V3 ... + VirtualMachineSizeTypesStandardD64V3 VirtualMachineSizeTypes = "Standard_D64_v3" + // VirtualMachineSizeTypesStandardD8sV3 ... + VirtualMachineSizeTypesStandardD8sV3 VirtualMachineSizeTypes = "Standard_D8s_v3" + // VirtualMachineSizeTypesStandardD8V3 ... + VirtualMachineSizeTypesStandardD8V3 VirtualMachineSizeTypes = "Standard_D8_v3" + // VirtualMachineSizeTypesStandardDS1 ... + VirtualMachineSizeTypesStandardDS1 VirtualMachineSizeTypes = "Standard_DS1" + // VirtualMachineSizeTypesStandardDS11 ... + VirtualMachineSizeTypesStandardDS11 VirtualMachineSizeTypes = "Standard_DS11" + // VirtualMachineSizeTypesStandardDS11V2 ... + VirtualMachineSizeTypesStandardDS11V2 VirtualMachineSizeTypes = "Standard_DS11_v2" + // VirtualMachineSizeTypesStandardDS12 ... + VirtualMachineSizeTypesStandardDS12 VirtualMachineSizeTypes = "Standard_DS12" + // VirtualMachineSizeTypesStandardDS12V2 ... + VirtualMachineSizeTypesStandardDS12V2 VirtualMachineSizeTypes = "Standard_DS12_v2" + // VirtualMachineSizeTypesStandardDS13 ... + VirtualMachineSizeTypesStandardDS13 VirtualMachineSizeTypes = "Standard_DS13" + // VirtualMachineSizeTypesStandardDS132V2 ... + VirtualMachineSizeTypesStandardDS132V2 VirtualMachineSizeTypes = "Standard_DS13-2_v2" + // VirtualMachineSizeTypesStandardDS134V2 ... + VirtualMachineSizeTypesStandardDS134V2 VirtualMachineSizeTypes = "Standard_DS13-4_v2" + // VirtualMachineSizeTypesStandardDS13V2 ... + VirtualMachineSizeTypesStandardDS13V2 VirtualMachineSizeTypes = "Standard_DS13_v2" + // VirtualMachineSizeTypesStandardDS14 ... + VirtualMachineSizeTypesStandardDS14 VirtualMachineSizeTypes = "Standard_DS14" + // VirtualMachineSizeTypesStandardDS144V2 ... + VirtualMachineSizeTypesStandardDS144V2 VirtualMachineSizeTypes = "Standard_DS14-4_v2" + // VirtualMachineSizeTypesStandardDS148V2 ... + VirtualMachineSizeTypesStandardDS148V2 VirtualMachineSizeTypes = "Standard_DS14-8_v2" + // VirtualMachineSizeTypesStandardDS14V2 ... + VirtualMachineSizeTypesStandardDS14V2 VirtualMachineSizeTypes = "Standard_DS14_v2" + // VirtualMachineSizeTypesStandardDS15V2 ... + VirtualMachineSizeTypesStandardDS15V2 VirtualMachineSizeTypes = "Standard_DS15_v2" + // VirtualMachineSizeTypesStandardDS1V2 ... + VirtualMachineSizeTypesStandardDS1V2 VirtualMachineSizeTypes = "Standard_DS1_v2" + // VirtualMachineSizeTypesStandardDS2 ... + VirtualMachineSizeTypesStandardDS2 VirtualMachineSizeTypes = "Standard_DS2" + // VirtualMachineSizeTypesStandardDS2V2 ... + VirtualMachineSizeTypesStandardDS2V2 VirtualMachineSizeTypes = "Standard_DS2_v2" + // VirtualMachineSizeTypesStandardDS3 ... + VirtualMachineSizeTypesStandardDS3 VirtualMachineSizeTypes = "Standard_DS3" + // VirtualMachineSizeTypesStandardDS3V2 ... + VirtualMachineSizeTypesStandardDS3V2 VirtualMachineSizeTypes = "Standard_DS3_v2" + // VirtualMachineSizeTypesStandardDS4 ... + VirtualMachineSizeTypesStandardDS4 VirtualMachineSizeTypes = "Standard_DS4" + // VirtualMachineSizeTypesStandardDS4V2 ... + VirtualMachineSizeTypesStandardDS4V2 VirtualMachineSizeTypes = "Standard_DS4_v2" + // VirtualMachineSizeTypesStandardDS5V2 ... + VirtualMachineSizeTypesStandardDS5V2 VirtualMachineSizeTypes = "Standard_DS5_v2" + // VirtualMachineSizeTypesStandardE16sV3 ... + VirtualMachineSizeTypesStandardE16sV3 VirtualMachineSizeTypes = "Standard_E16s_v3" + // VirtualMachineSizeTypesStandardE16V3 ... + VirtualMachineSizeTypesStandardE16V3 VirtualMachineSizeTypes = "Standard_E16_v3" + // VirtualMachineSizeTypesStandardE2sV3 ... + VirtualMachineSizeTypesStandardE2sV3 VirtualMachineSizeTypes = "Standard_E2s_v3" + // VirtualMachineSizeTypesStandardE2V3 ... + VirtualMachineSizeTypesStandardE2V3 VirtualMachineSizeTypes = "Standard_E2_v3" + // VirtualMachineSizeTypesStandardE3216V3 ... + VirtualMachineSizeTypesStandardE3216V3 VirtualMachineSizeTypes = "Standard_E32-16_v3" + // VirtualMachineSizeTypesStandardE328sV3 ... + VirtualMachineSizeTypesStandardE328sV3 VirtualMachineSizeTypes = "Standard_E32-8s_v3" + // VirtualMachineSizeTypesStandardE32sV3 ... + VirtualMachineSizeTypesStandardE32sV3 VirtualMachineSizeTypes = "Standard_E32s_v3" + // VirtualMachineSizeTypesStandardE32V3 ... + VirtualMachineSizeTypesStandardE32V3 VirtualMachineSizeTypes = "Standard_E32_v3" + // VirtualMachineSizeTypesStandardE4sV3 ... + VirtualMachineSizeTypesStandardE4sV3 VirtualMachineSizeTypes = "Standard_E4s_v3" + // VirtualMachineSizeTypesStandardE4V3 ... + VirtualMachineSizeTypesStandardE4V3 VirtualMachineSizeTypes = "Standard_E4_v3" + // VirtualMachineSizeTypesStandardE6416sV3 ... + VirtualMachineSizeTypesStandardE6416sV3 VirtualMachineSizeTypes = "Standard_E64-16s_v3" + // VirtualMachineSizeTypesStandardE6432sV3 ... + VirtualMachineSizeTypesStandardE6432sV3 VirtualMachineSizeTypes = "Standard_E64-32s_v3" + // VirtualMachineSizeTypesStandardE64sV3 ... + VirtualMachineSizeTypesStandardE64sV3 VirtualMachineSizeTypes = "Standard_E64s_v3" + // VirtualMachineSizeTypesStandardE64V3 ... + VirtualMachineSizeTypesStandardE64V3 VirtualMachineSizeTypes = "Standard_E64_v3" + // VirtualMachineSizeTypesStandardE8sV3 ... + VirtualMachineSizeTypesStandardE8sV3 VirtualMachineSizeTypes = "Standard_E8s_v3" + // VirtualMachineSizeTypesStandardE8V3 ... + VirtualMachineSizeTypesStandardE8V3 VirtualMachineSizeTypes = "Standard_E8_v3" + // VirtualMachineSizeTypesStandardF1 ... + VirtualMachineSizeTypesStandardF1 VirtualMachineSizeTypes = "Standard_F1" + // VirtualMachineSizeTypesStandardF16 ... + VirtualMachineSizeTypesStandardF16 VirtualMachineSizeTypes = "Standard_F16" + // VirtualMachineSizeTypesStandardF16s ... + VirtualMachineSizeTypesStandardF16s VirtualMachineSizeTypes = "Standard_F16s" + // VirtualMachineSizeTypesStandardF16sV2 ... + VirtualMachineSizeTypesStandardF16sV2 VirtualMachineSizeTypes = "Standard_F16s_v2" + // VirtualMachineSizeTypesStandardF1s ... + VirtualMachineSizeTypesStandardF1s VirtualMachineSizeTypes = "Standard_F1s" + // VirtualMachineSizeTypesStandardF2 ... + VirtualMachineSizeTypesStandardF2 VirtualMachineSizeTypes = "Standard_F2" + // VirtualMachineSizeTypesStandardF2s ... + VirtualMachineSizeTypesStandardF2s VirtualMachineSizeTypes = "Standard_F2s" + // VirtualMachineSizeTypesStandardF2sV2 ... + VirtualMachineSizeTypesStandardF2sV2 VirtualMachineSizeTypes = "Standard_F2s_v2" + // VirtualMachineSizeTypesStandardF32sV2 ... + VirtualMachineSizeTypesStandardF32sV2 VirtualMachineSizeTypes = "Standard_F32s_v2" + // VirtualMachineSizeTypesStandardF4 ... + VirtualMachineSizeTypesStandardF4 VirtualMachineSizeTypes = "Standard_F4" + // VirtualMachineSizeTypesStandardF4s ... + VirtualMachineSizeTypesStandardF4s VirtualMachineSizeTypes = "Standard_F4s" + // VirtualMachineSizeTypesStandardF4sV2 ... + VirtualMachineSizeTypesStandardF4sV2 VirtualMachineSizeTypes = "Standard_F4s_v2" + // VirtualMachineSizeTypesStandardF64sV2 ... + VirtualMachineSizeTypesStandardF64sV2 VirtualMachineSizeTypes = "Standard_F64s_v2" + // VirtualMachineSizeTypesStandardF72sV2 ... + VirtualMachineSizeTypesStandardF72sV2 VirtualMachineSizeTypes = "Standard_F72s_v2" + // VirtualMachineSizeTypesStandardF8 ... + VirtualMachineSizeTypesStandardF8 VirtualMachineSizeTypes = "Standard_F8" + // VirtualMachineSizeTypesStandardF8s ... + VirtualMachineSizeTypesStandardF8s VirtualMachineSizeTypes = "Standard_F8s" + // VirtualMachineSizeTypesStandardF8sV2 ... + VirtualMachineSizeTypesStandardF8sV2 VirtualMachineSizeTypes = "Standard_F8s_v2" + // VirtualMachineSizeTypesStandardG1 ... + VirtualMachineSizeTypesStandardG1 VirtualMachineSizeTypes = "Standard_G1" + // VirtualMachineSizeTypesStandardG2 ... + VirtualMachineSizeTypesStandardG2 VirtualMachineSizeTypes = "Standard_G2" + // VirtualMachineSizeTypesStandardG3 ... + VirtualMachineSizeTypesStandardG3 VirtualMachineSizeTypes = "Standard_G3" + // VirtualMachineSizeTypesStandardG4 ... + VirtualMachineSizeTypesStandardG4 VirtualMachineSizeTypes = "Standard_G4" + // VirtualMachineSizeTypesStandardG5 ... + VirtualMachineSizeTypesStandardG5 VirtualMachineSizeTypes = "Standard_G5" + // VirtualMachineSizeTypesStandardGS1 ... + VirtualMachineSizeTypesStandardGS1 VirtualMachineSizeTypes = "Standard_GS1" + // VirtualMachineSizeTypesStandardGS2 ... + VirtualMachineSizeTypesStandardGS2 VirtualMachineSizeTypes = "Standard_GS2" + // VirtualMachineSizeTypesStandardGS3 ... + VirtualMachineSizeTypesStandardGS3 VirtualMachineSizeTypes = "Standard_GS3" + // VirtualMachineSizeTypesStandardGS4 ... + VirtualMachineSizeTypesStandardGS4 VirtualMachineSizeTypes = "Standard_GS4" + // VirtualMachineSizeTypesStandardGS44 ... + VirtualMachineSizeTypesStandardGS44 VirtualMachineSizeTypes = "Standard_GS4-4" + // VirtualMachineSizeTypesStandardGS48 ... + VirtualMachineSizeTypesStandardGS48 VirtualMachineSizeTypes = "Standard_GS4-8" + // VirtualMachineSizeTypesStandardGS5 ... + VirtualMachineSizeTypesStandardGS5 VirtualMachineSizeTypes = "Standard_GS5" + // VirtualMachineSizeTypesStandardGS516 ... + VirtualMachineSizeTypesStandardGS516 VirtualMachineSizeTypes = "Standard_GS5-16" + // VirtualMachineSizeTypesStandardGS58 ... + VirtualMachineSizeTypesStandardGS58 VirtualMachineSizeTypes = "Standard_GS5-8" + // VirtualMachineSizeTypesStandardH16 ... + VirtualMachineSizeTypesStandardH16 VirtualMachineSizeTypes = "Standard_H16" + // VirtualMachineSizeTypesStandardH16m ... + VirtualMachineSizeTypesStandardH16m VirtualMachineSizeTypes = "Standard_H16m" + // VirtualMachineSizeTypesStandardH16mr ... + VirtualMachineSizeTypesStandardH16mr VirtualMachineSizeTypes = "Standard_H16mr" + // VirtualMachineSizeTypesStandardH16r ... + VirtualMachineSizeTypesStandardH16r VirtualMachineSizeTypes = "Standard_H16r" + // VirtualMachineSizeTypesStandardH8 ... + VirtualMachineSizeTypesStandardH8 VirtualMachineSizeTypes = "Standard_H8" + // VirtualMachineSizeTypesStandardH8m ... + VirtualMachineSizeTypesStandardH8m VirtualMachineSizeTypes = "Standard_H8m" + // VirtualMachineSizeTypesStandardL16s ... + VirtualMachineSizeTypesStandardL16s VirtualMachineSizeTypes = "Standard_L16s" + // VirtualMachineSizeTypesStandardL32s ... + VirtualMachineSizeTypesStandardL32s VirtualMachineSizeTypes = "Standard_L32s" + // VirtualMachineSizeTypesStandardL4s ... + VirtualMachineSizeTypesStandardL4s VirtualMachineSizeTypes = "Standard_L4s" + // VirtualMachineSizeTypesStandardL8s ... + VirtualMachineSizeTypesStandardL8s VirtualMachineSizeTypes = "Standard_L8s" + // VirtualMachineSizeTypesStandardM12832ms ... + VirtualMachineSizeTypesStandardM12832ms VirtualMachineSizeTypes = "Standard_M128-32ms" + // VirtualMachineSizeTypesStandardM12864ms ... + VirtualMachineSizeTypesStandardM12864ms VirtualMachineSizeTypes = "Standard_M128-64ms" + // VirtualMachineSizeTypesStandardM128ms ... + VirtualMachineSizeTypesStandardM128ms VirtualMachineSizeTypes = "Standard_M128ms" + // VirtualMachineSizeTypesStandardM128s ... + VirtualMachineSizeTypesStandardM128s VirtualMachineSizeTypes = "Standard_M128s" + // VirtualMachineSizeTypesStandardM6416ms ... + VirtualMachineSizeTypesStandardM6416ms VirtualMachineSizeTypes = "Standard_M64-16ms" + // VirtualMachineSizeTypesStandardM6432ms ... + VirtualMachineSizeTypesStandardM6432ms VirtualMachineSizeTypes = "Standard_M64-32ms" + // VirtualMachineSizeTypesStandardM64ms ... + VirtualMachineSizeTypesStandardM64ms VirtualMachineSizeTypes = "Standard_M64ms" + // VirtualMachineSizeTypesStandardM64s ... + VirtualMachineSizeTypesStandardM64s VirtualMachineSizeTypes = "Standard_M64s" + // VirtualMachineSizeTypesStandardNC12 ... + VirtualMachineSizeTypesStandardNC12 VirtualMachineSizeTypes = "Standard_NC12" + // VirtualMachineSizeTypesStandardNC12sV2 ... + VirtualMachineSizeTypesStandardNC12sV2 VirtualMachineSizeTypes = "Standard_NC12s_v2" + // VirtualMachineSizeTypesStandardNC12sV3 ... + VirtualMachineSizeTypesStandardNC12sV3 VirtualMachineSizeTypes = "Standard_NC12s_v3" + // VirtualMachineSizeTypesStandardNC24 ... + VirtualMachineSizeTypesStandardNC24 VirtualMachineSizeTypes = "Standard_NC24" + // VirtualMachineSizeTypesStandardNC24r ... + VirtualMachineSizeTypesStandardNC24r VirtualMachineSizeTypes = "Standard_NC24r" + // VirtualMachineSizeTypesStandardNC24rsV2 ... + VirtualMachineSizeTypesStandardNC24rsV2 VirtualMachineSizeTypes = "Standard_NC24rs_v2" + // VirtualMachineSizeTypesStandardNC24rsV3 ... + VirtualMachineSizeTypesStandardNC24rsV3 VirtualMachineSizeTypes = "Standard_NC24rs_v3" + // VirtualMachineSizeTypesStandardNC24sV2 ... + VirtualMachineSizeTypesStandardNC24sV2 VirtualMachineSizeTypes = "Standard_NC24s_v2" + // VirtualMachineSizeTypesStandardNC24sV3 ... + VirtualMachineSizeTypesStandardNC24sV3 VirtualMachineSizeTypes = "Standard_NC24s_v3" + // VirtualMachineSizeTypesStandardNC6 ... + VirtualMachineSizeTypesStandardNC6 VirtualMachineSizeTypes = "Standard_NC6" + // VirtualMachineSizeTypesStandardNC6sV2 ... + VirtualMachineSizeTypesStandardNC6sV2 VirtualMachineSizeTypes = "Standard_NC6s_v2" + // VirtualMachineSizeTypesStandardNC6sV3 ... + VirtualMachineSizeTypesStandardNC6sV3 VirtualMachineSizeTypes = "Standard_NC6s_v3" + // VirtualMachineSizeTypesStandardND12s ... + VirtualMachineSizeTypesStandardND12s VirtualMachineSizeTypes = "Standard_ND12s" + // VirtualMachineSizeTypesStandardND24rs ... + VirtualMachineSizeTypesStandardND24rs VirtualMachineSizeTypes = "Standard_ND24rs" + // VirtualMachineSizeTypesStandardND24s ... + VirtualMachineSizeTypesStandardND24s VirtualMachineSizeTypes = "Standard_ND24s" + // VirtualMachineSizeTypesStandardND6s ... + VirtualMachineSizeTypesStandardND6s VirtualMachineSizeTypes = "Standard_ND6s" + // VirtualMachineSizeTypesStandardNV12 ... + VirtualMachineSizeTypesStandardNV12 VirtualMachineSizeTypes = "Standard_NV12" + // VirtualMachineSizeTypesStandardNV24 ... + VirtualMachineSizeTypesStandardNV24 VirtualMachineSizeTypes = "Standard_NV24" + // VirtualMachineSizeTypesStandardNV6 ... + VirtualMachineSizeTypesStandardNV6 VirtualMachineSizeTypes = "Standard_NV6" ) // PossibleVirtualMachineSizeTypesValues returns an array of possible values for the VirtualMachineSizeTypes const type. func PossibleVirtualMachineSizeTypesValues() []VirtualMachineSizeTypes { - return []VirtualMachineSizeTypes{BasicA0, BasicA1, BasicA2, BasicA3, BasicA4, StandardA0, StandardA1, StandardA10, StandardA11, StandardA1V2, StandardA2, StandardA2mV2, StandardA2V2, StandardA3, StandardA4, StandardA4mV2, StandardA4V2, StandardA5, StandardA6, StandardA7, StandardA8, StandardA8mV2, StandardA8V2, StandardA9, StandardB1ms, StandardB1s, StandardB2ms, StandardB2s, StandardB4ms, StandardB8ms, StandardD1, StandardD11, StandardD11V2, StandardD12, StandardD12V2, StandardD13, StandardD13V2, StandardD14, StandardD14V2, StandardD15V2, StandardD16sV3, StandardD16V3, StandardD1V2, StandardD2, StandardD2sV3, StandardD2V2, StandardD2V3, StandardD3, StandardD32sV3, StandardD32V3, StandardD3V2, StandardD4, StandardD4sV3, StandardD4V2, StandardD4V3, StandardD5V2, StandardD64sV3, StandardD64V3, StandardD8sV3, StandardD8V3, StandardDS1, StandardDS11, StandardDS11V2, StandardDS12, StandardDS12V2, StandardDS13, StandardDS132V2, StandardDS134V2, StandardDS13V2, StandardDS14, StandardDS144V2, StandardDS148V2, StandardDS14V2, StandardDS15V2, StandardDS1V2, StandardDS2, StandardDS2V2, StandardDS3, StandardDS3V2, StandardDS4, StandardDS4V2, StandardDS5V2, StandardE16sV3, StandardE16V3, StandardE2sV3, StandardE2V3, StandardE3216V3, StandardE328sV3, StandardE32sV3, StandardE32V3, StandardE4sV3, StandardE4V3, StandardE6416sV3, StandardE6432sV3, StandardE64sV3, StandardE64V3, StandardE8sV3, StandardE8V3, StandardF1, StandardF16, StandardF16s, StandardF16sV2, StandardF1s, StandardF2, StandardF2s, StandardF2sV2, StandardF32sV2, StandardF4, StandardF4s, StandardF4sV2, StandardF64sV2, StandardF72sV2, StandardF8, StandardF8s, StandardF8sV2, StandardG1, StandardG2, StandardG3, StandardG4, StandardG5, StandardGS1, StandardGS2, StandardGS3, StandardGS4, StandardGS44, StandardGS48, StandardGS5, StandardGS516, StandardGS58, StandardH16, StandardH16m, StandardH16mr, StandardH16r, StandardH8, StandardH8m, StandardL16s, StandardL32s, StandardL4s, StandardL8s, StandardM12832ms, StandardM12864ms, StandardM128ms, StandardM128s, StandardM6416ms, StandardM6432ms, StandardM64ms, StandardM64s, StandardNC12, StandardNC12sV2, StandardNC12sV3, StandardNC24, StandardNC24r, StandardNC24rsV2, StandardNC24rsV3, StandardNC24sV2, StandardNC24sV3, StandardNC6, StandardNC6sV2, StandardNC6sV3, StandardND12s, StandardND24rs, StandardND24s, StandardND6s, StandardNV12, StandardNV24, StandardNV6} + return []VirtualMachineSizeTypes{VirtualMachineSizeTypesBasicA0, VirtualMachineSizeTypesBasicA1, VirtualMachineSizeTypesBasicA2, VirtualMachineSizeTypesBasicA3, VirtualMachineSizeTypesBasicA4, VirtualMachineSizeTypesStandardA0, VirtualMachineSizeTypesStandardA1, VirtualMachineSizeTypesStandardA10, VirtualMachineSizeTypesStandardA11, VirtualMachineSizeTypesStandardA1V2, VirtualMachineSizeTypesStandardA2, VirtualMachineSizeTypesStandardA2mV2, VirtualMachineSizeTypesStandardA2V2, VirtualMachineSizeTypesStandardA3, VirtualMachineSizeTypesStandardA4, VirtualMachineSizeTypesStandardA4mV2, VirtualMachineSizeTypesStandardA4V2, VirtualMachineSizeTypesStandardA5, VirtualMachineSizeTypesStandardA6, VirtualMachineSizeTypesStandardA7, VirtualMachineSizeTypesStandardA8, VirtualMachineSizeTypesStandardA8mV2, VirtualMachineSizeTypesStandardA8V2, VirtualMachineSizeTypesStandardA9, VirtualMachineSizeTypesStandardB1ms, VirtualMachineSizeTypesStandardB1s, VirtualMachineSizeTypesStandardB2ms, VirtualMachineSizeTypesStandardB2s, VirtualMachineSizeTypesStandardB4ms, VirtualMachineSizeTypesStandardB8ms, VirtualMachineSizeTypesStandardD1, VirtualMachineSizeTypesStandardD11, VirtualMachineSizeTypesStandardD11V2, VirtualMachineSizeTypesStandardD12, VirtualMachineSizeTypesStandardD12V2, VirtualMachineSizeTypesStandardD13, VirtualMachineSizeTypesStandardD13V2, VirtualMachineSizeTypesStandardD14, VirtualMachineSizeTypesStandardD14V2, VirtualMachineSizeTypesStandardD15V2, VirtualMachineSizeTypesStandardD16sV3, VirtualMachineSizeTypesStandardD16V3, VirtualMachineSizeTypesStandardD1V2, VirtualMachineSizeTypesStandardD2, VirtualMachineSizeTypesStandardD2sV3, VirtualMachineSizeTypesStandardD2V2, VirtualMachineSizeTypesStandardD2V3, VirtualMachineSizeTypesStandardD3, VirtualMachineSizeTypesStandardD32sV3, VirtualMachineSizeTypesStandardD32V3, VirtualMachineSizeTypesStandardD3V2, VirtualMachineSizeTypesStandardD4, VirtualMachineSizeTypesStandardD4sV3, VirtualMachineSizeTypesStandardD4V2, VirtualMachineSizeTypesStandardD4V3, VirtualMachineSizeTypesStandardD5V2, VirtualMachineSizeTypesStandardD64sV3, VirtualMachineSizeTypesStandardD64V3, VirtualMachineSizeTypesStandardD8sV3, VirtualMachineSizeTypesStandardD8V3, VirtualMachineSizeTypesStandardDS1, VirtualMachineSizeTypesStandardDS11, VirtualMachineSizeTypesStandardDS11V2, VirtualMachineSizeTypesStandardDS12, VirtualMachineSizeTypesStandardDS12V2, VirtualMachineSizeTypesStandardDS13, VirtualMachineSizeTypesStandardDS132V2, VirtualMachineSizeTypesStandardDS134V2, VirtualMachineSizeTypesStandardDS13V2, VirtualMachineSizeTypesStandardDS14, VirtualMachineSizeTypesStandardDS144V2, VirtualMachineSizeTypesStandardDS148V2, VirtualMachineSizeTypesStandardDS14V2, VirtualMachineSizeTypesStandardDS15V2, VirtualMachineSizeTypesStandardDS1V2, VirtualMachineSizeTypesStandardDS2, VirtualMachineSizeTypesStandardDS2V2, VirtualMachineSizeTypesStandardDS3, VirtualMachineSizeTypesStandardDS3V2, VirtualMachineSizeTypesStandardDS4, VirtualMachineSizeTypesStandardDS4V2, VirtualMachineSizeTypesStandardDS5V2, VirtualMachineSizeTypesStandardE16sV3, VirtualMachineSizeTypesStandardE16V3, VirtualMachineSizeTypesStandardE2sV3, VirtualMachineSizeTypesStandardE2V3, VirtualMachineSizeTypesStandardE3216V3, VirtualMachineSizeTypesStandardE328sV3, VirtualMachineSizeTypesStandardE32sV3, VirtualMachineSizeTypesStandardE32V3, VirtualMachineSizeTypesStandardE4sV3, VirtualMachineSizeTypesStandardE4V3, VirtualMachineSizeTypesStandardE6416sV3, VirtualMachineSizeTypesStandardE6432sV3, VirtualMachineSizeTypesStandardE64sV3, VirtualMachineSizeTypesStandardE64V3, VirtualMachineSizeTypesStandardE8sV3, VirtualMachineSizeTypesStandardE8V3, VirtualMachineSizeTypesStandardF1, VirtualMachineSizeTypesStandardF16, VirtualMachineSizeTypesStandardF16s, VirtualMachineSizeTypesStandardF16sV2, VirtualMachineSizeTypesStandardF1s, VirtualMachineSizeTypesStandardF2, VirtualMachineSizeTypesStandardF2s, VirtualMachineSizeTypesStandardF2sV2, VirtualMachineSizeTypesStandardF32sV2, VirtualMachineSizeTypesStandardF4, VirtualMachineSizeTypesStandardF4s, VirtualMachineSizeTypesStandardF4sV2, VirtualMachineSizeTypesStandardF64sV2, VirtualMachineSizeTypesStandardF72sV2, VirtualMachineSizeTypesStandardF8, VirtualMachineSizeTypesStandardF8s, VirtualMachineSizeTypesStandardF8sV2, VirtualMachineSizeTypesStandardG1, VirtualMachineSizeTypesStandardG2, VirtualMachineSizeTypesStandardG3, VirtualMachineSizeTypesStandardG4, VirtualMachineSizeTypesStandardG5, VirtualMachineSizeTypesStandardGS1, VirtualMachineSizeTypesStandardGS2, VirtualMachineSizeTypesStandardGS3, VirtualMachineSizeTypesStandardGS4, VirtualMachineSizeTypesStandardGS44, VirtualMachineSizeTypesStandardGS48, VirtualMachineSizeTypesStandardGS5, VirtualMachineSizeTypesStandardGS516, VirtualMachineSizeTypesStandardGS58, VirtualMachineSizeTypesStandardH16, VirtualMachineSizeTypesStandardH16m, VirtualMachineSizeTypesStandardH16mr, VirtualMachineSizeTypesStandardH16r, VirtualMachineSizeTypesStandardH8, VirtualMachineSizeTypesStandardH8m, VirtualMachineSizeTypesStandardL16s, VirtualMachineSizeTypesStandardL32s, VirtualMachineSizeTypesStandardL4s, VirtualMachineSizeTypesStandardL8s, VirtualMachineSizeTypesStandardM12832ms, VirtualMachineSizeTypesStandardM12864ms, VirtualMachineSizeTypesStandardM128ms, VirtualMachineSizeTypesStandardM128s, VirtualMachineSizeTypesStandardM6416ms, VirtualMachineSizeTypesStandardM6432ms, VirtualMachineSizeTypesStandardM64ms, VirtualMachineSizeTypesStandardM64s, VirtualMachineSizeTypesStandardNC12, VirtualMachineSizeTypesStandardNC12sV2, VirtualMachineSizeTypesStandardNC12sV3, VirtualMachineSizeTypesStandardNC24, VirtualMachineSizeTypesStandardNC24r, VirtualMachineSizeTypesStandardNC24rsV2, VirtualMachineSizeTypesStandardNC24rsV3, VirtualMachineSizeTypesStandardNC24sV2, VirtualMachineSizeTypesStandardNC24sV3, VirtualMachineSizeTypesStandardNC6, VirtualMachineSizeTypesStandardNC6sV2, VirtualMachineSizeTypesStandardNC6sV3, VirtualMachineSizeTypesStandardND12s, VirtualMachineSizeTypesStandardND24rs, VirtualMachineSizeTypesStandardND24s, VirtualMachineSizeTypesStandardND6s, VirtualMachineSizeTypesStandardNV12, VirtualMachineSizeTypesStandardNV24, VirtualMachineSizeTypesStandardNV6} } // AccessURI a disk access SAS uri. @@ -802,6 +1159,12 @@ type AccessURI struct { AccessSAS *string `json:"accessSAS,omitempty"` } +// AdditionalCapabilities enables or disables a capability on the virtual machine or virtual machine scale set. +type AdditionalCapabilities struct { + // UltraSSDEnabled - The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. + UltraSSDEnabled *bool `json:"ultraSSDEnabled,omitempty"` +} + // AdditionalUnattendContent specifies additional XML formatted information that can be included in the // Unattend.xml file, which is used by Windows Setup. Contents are defined by setting name, component name, and the // pass in which the content is applied. @@ -846,10 +1209,12 @@ type APIErrorBase struct { Message *string `json:"message,omitempty"` } -// AutoOSUpgradePolicy the configuration parameters used for performing automatic OS upgrade. -type AutoOSUpgradePolicy struct { - // DisableAutoRollback - Whether OS image rollback feature should be disabled. Default value is false. - DisableAutoRollback *bool `json:"disableAutoRollback,omitempty"` +// AutomaticOSUpgradePolicy the configuration parameters used for performing automatic OS upgrade. +type AutomaticOSUpgradePolicy struct { + // EnableAutomaticOSUpgrade - Whether OS upgrades should automatically be applied to scale set instances in a rolling fashion when a newer version of the image becomes available. Default value is false. + EnableAutomaticOSUpgrade *bool `json:"enableAutomaticOSUpgrade,omitempty"` + // DisableAutomaticRollback - Whether OS image rollback feature should be disabled. Default value is false. + DisableAutomaticRollback *bool `json:"disableAutomaticRollback,omitempty"` } // AvailabilitySet specifies information about the availability set that the virtual machine should be assigned to. @@ -863,7 +1228,7 @@ type AutoOSUpgradePolicy struct { type AvailabilitySet struct { autorest.Response `json:"-"` *AvailabilitySetProperties `json:"properties,omitempty"` - // Sku - Sku of the availability set + // Sku - Sku of the availability set, only name is required to be set. See AvailabilitySetSkuTypes for possible set of values. Use 'Aligned' for virtual machines with managed disks and 'Classic' for virtual machines with unmanaged disks. Default value is 'Classic'. Sku *Sku `json:"sku,omitempty"` // ID - Resource Id ID *string `json:"id,omitempty"` @@ -1182,63 +1547,15 @@ type BootDiagnosticsInstanceView struct { SerialConsoleLogBlobURI *string `json:"serialConsoleLogBlobUri,omitempty"` } -// CreationData data used when creating a disk. -type CreationData struct { - // CreateOption - This enumerates the possible sources of a disk's creation. Possible values include: 'Empty', 'Attach', 'FromImage', 'Import', 'Copy', 'Restore' - CreateOption DiskCreateOption `json:"createOption,omitempty"` - // StorageAccountID - If createOption is Import, the Azure Resource Manager identifier of the storage account containing the blob to import as a disk. Required only if the blob is in a different subscription - StorageAccountID *string `json:"storageAccountId,omitempty"` - // ImageReference - Disk source information. - ImageReference *ImageDiskReference `json:"imageReference,omitempty"` - // SourceURI - If createOption is Import, this is the URI of a blob to be imported into a managed disk. - SourceURI *string `json:"sourceUri,omitempty"` - // SourceResourceID - If createOption is Copy, this is the ARM id of the source snapshot or disk. - SourceResourceID *string `json:"sourceResourceId,omitempty"` -} - -// DataDisk describes a data disk. -type DataDisk struct { - // Lun - Specifies the logical unit number of the data disk. This value is used to identify data disks within the VM and therefore must be unique for each data disk attached to a VM. - Lun *int32 `json:"lun,omitempty"` - // Name - The disk name. - Name *string `json:"name,omitempty"` - // Vhd - The virtual hard disk. - Vhd *VirtualHardDisk `json:"vhd,omitempty"` - // Image - The source user image virtual hard disk. The virtual hard disk will be copied before being attached to the virtual machine. If SourceImage is provided, the destination virtual hard drive must not exist. - Image *VirtualHardDisk `json:"image,omitempty"` - // Caching - Specifies the caching requirements.

Possible values are:

**None**

**ReadOnly**

**ReadWrite**

Default: **None for Standard storage. ReadOnly for Premium storage**. Possible values include: 'CachingTypesNone', 'CachingTypesReadOnly', 'CachingTypesReadWrite' - Caching CachingTypes `json:"caching,omitempty"` - // WriteAcceleratorEnabled - Specifies whether writeAccelerator should be enabled or disabled on the disk. - WriteAcceleratorEnabled *bool `json:"writeAcceleratorEnabled,omitempty"` - // CreateOption - Specifies how the virtual machine should be created.

Possible values are:

**Attach** \u2013 This value is used when you are using a specialized disk to create the virtual machine.

**FromImage** \u2013 This value is used when you are using an image to create the virtual machine. If you are using a platform image, you also use the imageReference element described above. If you are using a marketplace image, you also use the plan element previously described. Possible values include: 'DiskCreateOptionTypesFromImage', 'DiskCreateOptionTypesEmpty', 'DiskCreateOptionTypesAttach' - CreateOption DiskCreateOptionTypes `json:"createOption,omitempty"` - // DiskSizeGB - Specifies the size of an empty data disk in gigabytes. This element can be used to overwrite the size of the disk in a virtual machine image.

This value cannot be larger than 1023 GB - DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` - // ManagedDisk - The managed disk parameters. - ManagedDisk *ManagedDiskParameters `json:"managedDisk,omitempty"` -} - -// DataDiskImage contains the data disk images information. -type DataDiskImage struct { - // Lun - Specifies the logical unit number of the data disk. This value is used to identify data disks within the VM and therefore must be unique for each data disk attached to a VM. - Lun *int32 `json:"lun,omitempty"` -} - -// DiagnosticsProfile specifies the boot diagnostic settings state.

Minimum api-version: 2015-06-15. -type DiagnosticsProfile struct { - // BootDiagnostics - Boot Diagnostics is a debugging feature which allows you to view Console Output and Screenshot to diagnose VM status.

For Linux Virtual Machines, you can easily view the output of your console log.

For both Windows and Linux virtual machines, Azure also enables you to see a screenshot of the VM from the hypervisor. - BootDiagnostics *BootDiagnostics `json:"bootDiagnostics,omitempty"` +// CloudError an error response from the Gallery service. +type CloudError struct { + Error *APIError `json:"error,omitempty"` } -// Disk disk resource. -type Disk struct { - autorest.Response `json:"-"` - // ManagedBy - A relative URI containing the ID of the VM that has the disk attached. - ManagedBy *string `json:"managedBy,omitempty"` - Sku *DiskSku `json:"sku,omitempty"` - // Zones - The Logical zone list for Disk. - Zones *[]string `json:"zones,omitempty"` - *DiskProperties `json:"properties,omitempty"` +// ContainerService container service. +type ContainerService struct { + autorest.Response `json:"-"` + *ContainerServiceProperties `json:"properties,omitempty"` // ID - Resource Id ID *string `json:"id,omitempty"` // Name - Resource name @@ -1251,41 +1568,1474 @@ type Disk struct { Tags map[string]*string `json:"tags"` } -// MarshalJSON is the custom marshaler for Disk. -func (d Disk) MarshalJSON() ([]byte, error) { +// MarshalJSON is the custom marshaler for ContainerService. +func (cs ContainerService) MarshalJSON() ([]byte, error) { objectMap := make(map[string]interface{}) - if d.ManagedBy != nil { - objectMap["managedBy"] = d.ManagedBy + if cs.ContainerServiceProperties != nil { + objectMap["properties"] = cs.ContainerServiceProperties } - if d.Sku != nil { + if cs.ID != nil { + objectMap["id"] = cs.ID + } + if cs.Name != nil { + objectMap["name"] = cs.Name + } + if cs.Type != nil { + objectMap["type"] = cs.Type + } + if cs.Location != nil { + objectMap["location"] = cs.Location + } + if cs.Tags != nil { + objectMap["tags"] = cs.Tags + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for ContainerService struct. +func (cs *ContainerService) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var containerServiceProperties ContainerServiceProperties + err = json.Unmarshal(*v, &containerServiceProperties) + if err != nil { + return err + } + cs.ContainerServiceProperties = &containerServiceProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + cs.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + cs.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + cs.Type = &typeVar + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + cs.Location = &location + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + cs.Tags = tags + } + } + } + + return nil +} + +// ContainerServiceAgentPoolProfile profile for the container service agent pool. +type ContainerServiceAgentPoolProfile struct { + // Name - Unique name of the agent pool profile in the context of the subscription and resource group. + Name *string `json:"name,omitempty"` + // Count - Number of agents (VMs) to host docker containers. Allowed values must be in the range of 1 to 100 (inclusive). The default value is 1. + Count *int32 `json:"count,omitempty"` + // VMSize - Size of agent VMs. Possible values include: 'StandardA0', 'StandardA1', 'StandardA2', 'StandardA3', 'StandardA4', 'StandardA5', 'StandardA6', 'StandardA7', 'StandardA8', 'StandardA9', 'StandardA10', 'StandardA11', 'StandardD1', 'StandardD2', 'StandardD3', 'StandardD4', 'StandardD11', 'StandardD12', 'StandardD13', 'StandardD14', 'StandardD1V2', 'StandardD2V2', 'StandardD3V2', 'StandardD4V2', 'StandardD5V2', 'StandardD11V2', 'StandardD12V2', 'StandardD13V2', 'StandardD14V2', 'StandardG1', 'StandardG2', 'StandardG3', 'StandardG4', 'StandardG5', 'StandardDS1', 'StandardDS2', 'StandardDS3', 'StandardDS4', 'StandardDS11', 'StandardDS12', 'StandardDS13', 'StandardDS14', 'StandardGS1', 'StandardGS2', 'StandardGS3', 'StandardGS4', 'StandardGS5' + VMSize ContainerServiceVMSizeTypes `json:"vmSize,omitempty"` + // DNSPrefix - DNS prefix to be used to create the FQDN for the agent pool. + DNSPrefix *string `json:"dnsPrefix,omitempty"` + // Fqdn - FDQN for the agent pool. + Fqdn *string `json:"fqdn,omitempty"` +} + +// ContainerServiceCustomProfile properties to configure a custom container service cluster. +type ContainerServiceCustomProfile struct { + // Orchestrator - The name of the custom orchestrator to use. + Orchestrator *string `json:"orchestrator,omitempty"` +} + +// ContainerServiceDiagnosticsProfile ... +type ContainerServiceDiagnosticsProfile struct { + // VMDiagnostics - Profile for the container service VM diagnostic agent. + VMDiagnostics *ContainerServiceVMDiagnostics `json:"vmDiagnostics,omitempty"` +} + +// ContainerServiceLinuxProfile profile for Linux VMs in the container service cluster. +type ContainerServiceLinuxProfile struct { + // AdminUsername - The administrator username to use for Linux VMs. + AdminUsername *string `json:"adminUsername,omitempty"` + // SSH - The ssh key configuration for Linux VMs. + SSH *ContainerServiceSSHConfiguration `json:"ssh,omitempty"` +} + +// ContainerServiceListResult the response from the List Container Services operation. +type ContainerServiceListResult struct { + autorest.Response `json:"-"` + // Value - the list of container services. + Value *[]ContainerService `json:"value,omitempty"` + // NextLink - The URL to get the next set of container service results. + NextLink *string `json:"nextLink,omitempty"` +} + +// ContainerServiceListResultIterator provides access to a complete listing of ContainerService values. +type ContainerServiceListResultIterator struct { + i int + page ContainerServiceListResultPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *ContainerServiceListResultIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter ContainerServiceListResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter ContainerServiceListResultIterator) Response() ContainerServiceListResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter ContainerServiceListResultIterator) Value() ContainerService { + if !iter.page.NotDone() { + return ContainerService{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (cslr ContainerServiceListResult) IsEmpty() bool { + return cslr.Value == nil || len(*cslr.Value) == 0 +} + +// containerServiceListResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (cslr ContainerServiceListResult) containerServiceListResultPreparer() (*http.Request, error) { + if cslr.NextLink == nil || len(to.String(cslr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(cslr.NextLink))) +} + +// ContainerServiceListResultPage contains a page of ContainerService values. +type ContainerServiceListResultPage struct { + fn func(ContainerServiceListResult) (ContainerServiceListResult, error) + cslr ContainerServiceListResult +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *ContainerServiceListResultPage) Next() error { + next, err := page.fn(page.cslr) + if err != nil { + return err + } + page.cslr = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page ContainerServiceListResultPage) NotDone() bool { + return !page.cslr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page ContainerServiceListResultPage) Response() ContainerServiceListResult { + return page.cslr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page ContainerServiceListResultPage) Values() []ContainerService { + if page.cslr.IsEmpty() { + return nil + } + return *page.cslr.Value +} + +// ContainerServiceMasterProfile profile for the container service master. +type ContainerServiceMasterProfile struct { + // Count - Number of masters (VMs) in the container service cluster. Allowed values are 1, 3, and 5. The default value is 1. + Count *int32 `json:"count,omitempty"` + // DNSPrefix - DNS prefix to be used to create the FQDN for master. + DNSPrefix *string `json:"dnsPrefix,omitempty"` + // Fqdn - FDQN for the master. + Fqdn *string `json:"fqdn,omitempty"` +} + +// ContainerServiceOrchestratorProfile profile for the container service orchestrator. +type ContainerServiceOrchestratorProfile struct { + // OrchestratorType - The orchestrator to use to manage container service cluster resources. Valid values are Swarm, DCOS, and Custom. Possible values include: 'Swarm', 'DCOS', 'Custom', 'Kubernetes' + OrchestratorType ContainerServiceOrchestratorTypes `json:"orchestratorType,omitempty"` +} + +// ContainerServiceProperties properties of the container service. +type ContainerServiceProperties struct { + // ProvisioningState - the current deployment or provisioning state, which only appears in the response. + ProvisioningState *string `json:"provisioningState,omitempty"` + // OrchestratorProfile - Properties of the orchestrator. + OrchestratorProfile *ContainerServiceOrchestratorProfile `json:"orchestratorProfile,omitempty"` + // CustomProfile - Properties for custom clusters. + CustomProfile *ContainerServiceCustomProfile `json:"customProfile,omitempty"` + // ServicePrincipalProfile - Properties for cluster service principals. + ServicePrincipalProfile *ContainerServiceServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"` + // MasterProfile - Properties of master agents. + MasterProfile *ContainerServiceMasterProfile `json:"masterProfile,omitempty"` + // AgentPoolProfiles - Properties of the agent pool. + AgentPoolProfiles *[]ContainerServiceAgentPoolProfile `json:"agentPoolProfiles,omitempty"` + // WindowsProfile - Properties of Windows VMs. + WindowsProfile *ContainerServiceWindowsProfile `json:"windowsProfile,omitempty"` + // LinuxProfile - Properties of Linux VMs. + LinuxProfile *ContainerServiceLinuxProfile `json:"linuxProfile,omitempty"` + // DiagnosticsProfile - Properties of the diagnostic agent. + DiagnosticsProfile *ContainerServiceDiagnosticsProfile `json:"diagnosticsProfile,omitempty"` +} + +// ContainerServicesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running +// operation. +type ContainerServicesCreateOrUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *ContainerServicesCreateOrUpdateFuture) Result(client ContainerServicesClient) (cs ContainerService, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.ContainerServicesCreateOrUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if cs.Response.Response, err = future.GetResult(sender); err == nil && cs.Response.Response.StatusCode != http.StatusNoContent { + cs, err = client.CreateOrUpdateResponder(cs.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesCreateOrUpdateFuture", "Result", cs.Response.Response, "Failure responding to request") + } + } + return +} + +// ContainerServicesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running +// operation. +type ContainerServicesDeleteFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *ContainerServicesDeleteFuture) Result(client ContainerServicesClient) (ar autorest.Response, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ContainerServicesDeleteFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.ContainerServicesDeleteFuture") + return + } + ar.Response = future.Response() + return +} + +// ContainerServiceServicePrincipalProfile information about a service principal identity for the cluster to use +// for manipulating Azure APIs. +type ContainerServiceServicePrincipalProfile struct { + // ClientID - The ID for the service principal. + ClientID *string `json:"clientId,omitempty"` + // Secret - The secret password associated with the service principal. + Secret *string `json:"secret,omitempty"` +} + +// ContainerServiceSSHConfiguration SSH configuration for Linux-based VMs running on Azure. +type ContainerServiceSSHConfiguration struct { + // PublicKeys - the list of SSH public keys used to authenticate with Linux-based VMs. + PublicKeys *[]ContainerServiceSSHPublicKey `json:"publicKeys,omitempty"` +} + +// ContainerServiceSSHPublicKey contains information about SSH certificate public key data. +type ContainerServiceSSHPublicKey struct { + // KeyData - Certificate public key used to authenticate with VMs through SSH. The certificate must be in PEM format with or without headers. + KeyData *string `json:"keyData,omitempty"` +} + +// ContainerServiceVMDiagnostics profile for diagnostics on the container service VMs. +type ContainerServiceVMDiagnostics struct { + // Enabled - Whether the VM diagnostic agent is provisioned on the VM. + Enabled *bool `json:"enabled,omitempty"` + // StorageURI - The URI of the storage account where diagnostics are stored. + StorageURI *string `json:"storageUri,omitempty"` +} + +// ContainerServiceWindowsProfile profile for Windows VMs in the container service cluster. +type ContainerServiceWindowsProfile struct { + // AdminUsername - The administrator username to use for Windows VMs. + AdminUsername *string `json:"adminUsername,omitempty"` + // AdminPassword - The administrator password to use for Windows VMs. + AdminPassword *string `json:"adminPassword,omitempty"` +} + +// CreationData data used when creating a disk. +type CreationData struct { + // CreateOption - This enumerates the possible sources of a disk's creation. Possible values include: 'Empty', 'Attach', 'FromImage', 'Import', 'Copy', 'Restore' + CreateOption DiskCreateOption `json:"createOption,omitempty"` + // StorageAccountID - If createOption is Import, the Azure Resource Manager identifier of the storage account containing the blob to import as a disk. Required only if the blob is in a different subscription + StorageAccountID *string `json:"storageAccountId,omitempty"` + // ImageReference - Disk source information. + ImageReference *ImageDiskReference `json:"imageReference,omitempty"` + // SourceURI - If createOption is Import, this is the URI of a blob to be imported into a managed disk. + SourceURI *string `json:"sourceUri,omitempty"` + // SourceResourceID - If createOption is Copy, this is the ARM id of the source snapshot or disk. + SourceResourceID *string `json:"sourceResourceId,omitempty"` +} + +// DataDisk describes a data disk. +type DataDisk struct { + // Lun - Specifies the logical unit number of the data disk. This value is used to identify data disks within the VM and therefore must be unique for each data disk attached to a VM. + Lun *int32 `json:"lun,omitempty"` + // Name - The disk name. + Name *string `json:"name,omitempty"` + // Vhd - The virtual hard disk. + Vhd *VirtualHardDisk `json:"vhd,omitempty"` + // Image - The source user image virtual hard disk. The virtual hard disk will be copied before being attached to the virtual machine. If SourceImage is provided, the destination virtual hard drive must not exist. + Image *VirtualHardDisk `json:"image,omitempty"` + // Caching - Specifies the caching requirements.

Possible values are:

**None**

**ReadOnly**

**ReadWrite**

Default: **None for Standard storage. ReadOnly for Premium storage**. Possible values include: 'CachingTypesNone', 'CachingTypesReadOnly', 'CachingTypesReadWrite' + Caching CachingTypes `json:"caching,omitempty"` + // WriteAcceleratorEnabled - Specifies whether writeAccelerator should be enabled or disabled on the disk. + WriteAcceleratorEnabled *bool `json:"writeAcceleratorEnabled,omitempty"` + // CreateOption - Specifies how the virtual machine should be created.

Possible values are:

**Attach** \u2013 This value is used when you are using a specialized disk to create the virtual machine.

**FromImage** \u2013 This value is used when you are using an image to create the virtual machine. If you are using a platform image, you also use the imageReference element described above. If you are using a marketplace image, you also use the plan element previously described. Possible values include: 'DiskCreateOptionTypesFromImage', 'DiskCreateOptionTypesEmpty', 'DiskCreateOptionTypesAttach' + CreateOption DiskCreateOptionTypes `json:"createOption,omitempty"` + // DiskSizeGB - Specifies the size of an empty data disk in gigabytes. This element can be used to overwrite the size of the disk in a virtual machine image.

This value cannot be larger than 1023 GB + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + // ManagedDisk - The managed disk parameters. + ManagedDisk *ManagedDiskParameters `json:"managedDisk,omitempty"` +} + +// DataDiskImage contains the data disk images information. +type DataDiskImage struct { + // Lun - Specifies the logical unit number of the data disk. This value is used to identify data disks within the VM and therefore must be unique for each data disk attached to a VM. + Lun *int32 `json:"lun,omitempty"` +} + +// DiagnosticsProfile specifies the boot diagnostic settings state.

Minimum api-version: 2015-06-15. +type DiagnosticsProfile struct { + // BootDiagnostics - Boot Diagnostics is a debugging feature which allows you to view Console Output and Screenshot to diagnose VM status.

For Linux Virtual Machines, you can easily view the output of your console log.

For both Windows and Linux virtual machines, Azure also enables you to see a screenshot of the VM from the hypervisor. + BootDiagnostics *BootDiagnostics `json:"bootDiagnostics,omitempty"` +} + +// DiffDiskSettings describes the parameters of differencing disk settings that can be be specified for operating +// system disk.

NOTE: The differencing disk settings can only be specified for managed disk. +type DiffDiskSettings struct { + // Option - Specifies the differencing disk settings for operating system disk. Possible values include: 'Local' + Option DiffDiskOptions `json:"option,omitempty"` +} + +// Disallowed describes the disallowed disk types. +type Disallowed struct { + // DiskTypes - A list of disk types. + DiskTypes *[]string `json:"diskTypes,omitempty"` +} + +// Disk disk resource. +type Disk struct { + autorest.Response `json:"-"` + // ManagedBy - A relative URI containing the ID of the VM that has the disk attached. + ManagedBy *string `json:"managedBy,omitempty"` + Sku *DiskSku `json:"sku,omitempty"` + // Zones - The Logical zone list for Disk. + Zones *[]string `json:"zones,omitempty"` + *DiskProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Resource location + Location *string `json:"location,omitempty"` + // Tags - Resource tags + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for Disk. +func (d Disk) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if d.ManagedBy != nil { + objectMap["managedBy"] = d.ManagedBy + } + if d.Sku != nil { objectMap["sku"] = d.Sku } - if d.Zones != nil { - objectMap["zones"] = d.Zones + if d.Zones != nil { + objectMap["zones"] = d.Zones + } + if d.DiskProperties != nil { + objectMap["properties"] = d.DiskProperties + } + if d.ID != nil { + objectMap["id"] = d.ID + } + if d.Name != nil { + objectMap["name"] = d.Name + } + if d.Type != nil { + objectMap["type"] = d.Type + } + if d.Location != nil { + objectMap["location"] = d.Location + } + if d.Tags != nil { + objectMap["tags"] = d.Tags + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Disk struct. +func (d *Disk) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "managedBy": + if v != nil { + var managedBy string + err = json.Unmarshal(*v, &managedBy) + if err != nil { + return err + } + d.ManagedBy = &managedBy + } + case "sku": + if v != nil { + var sku DiskSku + err = json.Unmarshal(*v, &sku) + if err != nil { + return err + } + d.Sku = &sku + } + case "zones": + if v != nil { + var zones []string + err = json.Unmarshal(*v, &zones) + if err != nil { + return err + } + d.Zones = &zones + } + case "properties": + if v != nil { + var diskProperties DiskProperties + err = json.Unmarshal(*v, &diskProperties) + if err != nil { + return err + } + d.DiskProperties = &diskProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + d.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + d.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + d.Type = &typeVar + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + d.Location = &location + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + d.Tags = tags + } + } + } + + return nil +} + +// DiskEncryptionSettings describes a Encryption Settings for a Disk +type DiskEncryptionSettings struct { + // DiskEncryptionKey - Specifies the location of the disk encryption key, which is a Key Vault Secret. + DiskEncryptionKey *KeyVaultSecretReference `json:"diskEncryptionKey,omitempty"` + // KeyEncryptionKey - Specifies the location of the key encryption key in Key Vault. + KeyEncryptionKey *KeyVaultKeyReference `json:"keyEncryptionKey,omitempty"` + // Enabled - Specifies whether disk encryption should be enabled on the virtual machine. + Enabled *bool `json:"enabled,omitempty"` +} + +// DiskInstanceView the instance view of the disk. +type DiskInstanceView struct { + // Name - The disk name. + Name *string `json:"name,omitempty"` + // EncryptionSettings - Specifies the encryption settings for the OS Disk.

Minimum api-version: 2015-06-15 + EncryptionSettings *[]DiskEncryptionSettings `json:"encryptionSettings,omitempty"` + // Statuses - The resource status information. + Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` +} + +// DiskList the List Disks operation response. +type DiskList struct { + autorest.Response `json:"-"` + // Value - A list of disks. + Value *[]Disk `json:"value,omitempty"` + // NextLink - The uri to fetch the next page of disks. Call ListNext() with this to fetch the next page of disks. + NextLink *string `json:"nextLink,omitempty"` +} + +// DiskListIterator provides access to a complete listing of Disk values. +type DiskListIterator struct { + i int + page DiskListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *DiskListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter DiskListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter DiskListIterator) Response() DiskList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter DiskListIterator) Value() Disk { + if !iter.page.NotDone() { + return Disk{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (dl DiskList) IsEmpty() bool { + return dl.Value == nil || len(*dl.Value) == 0 +} + +// diskListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (dl DiskList) diskListPreparer() (*http.Request, error) { + if dl.NextLink == nil || len(to.String(dl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(dl.NextLink))) +} + +// DiskListPage contains a page of Disk values. +type DiskListPage struct { + fn func(DiskList) (DiskList, error) + dl DiskList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *DiskListPage) Next() error { + next, err := page.fn(page.dl) + if err != nil { + return err + } + page.dl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page DiskListPage) NotDone() bool { + return !page.dl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page DiskListPage) Response() DiskList { + return page.dl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page DiskListPage) Values() []Disk { + if page.dl.IsEmpty() { + return nil + } + return *page.dl.Value +} + +// DiskProperties disk resource properties. +type DiskProperties struct { + // TimeCreated - The time when the disk was created. + TimeCreated *date.Time `json:"timeCreated,omitempty"` + // OsType - The Operating System type. Possible values include: 'Windows', 'Linux' + OsType OperatingSystemTypes `json:"osType,omitempty"` + // CreationData - Disk source information. CreationData information cannot be changed after the disk has been created. + CreationData *CreationData `json:"creationData,omitempty"` + // DiskSizeGB - If creationData.createOption is Empty, this field is mandatory and it indicates the size of the VHD to create. If this field is present for updates or creation with other options, it indicates a resize. Resizes are only allowed if the disk is not attached to a running VM, and can only increase the disk's size. + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + // EncryptionSettings - Encryption settings for disk or snapshot + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` + // ProvisioningState - The disk provisioning state. + ProvisioningState *string `json:"provisioningState,omitempty"` + // DiskIOPSReadWrite - The number of IOPS allowed for this disk; only settable for UltraSSD disks. One operation can transfer between 4k and 256k bytes. + DiskIOPSReadWrite *int64 `json:"diskIOPSReadWrite,omitempty"` + // DiskMBpsReadWrite - The bandwidth allowed for this disk; only settable for UltraSSD disks. MBps means millions of bytes per second - MB here uses the ISO notation, of powers of 10. + DiskMBpsReadWrite *int32 `json:"diskMBpsReadWrite,omitempty"` +} + +// DisksCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type DisksCreateOrUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *DisksCreateOrUpdateFuture) Result(client DisksClient) (d Disk, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.DisksCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.DisksCreateOrUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if d.Response.Response, err = future.GetResult(sender); err == nil && d.Response.Response.StatusCode != http.StatusNoContent { + d, err = client.CreateOrUpdateResponder(d.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.DisksCreateOrUpdateFuture", "Result", d.Response.Response, "Failure responding to request") + } + } + return +} + +// DisksDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type DisksDeleteFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *DisksDeleteFuture) Result(client DisksClient) (ar autorest.Response, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.DisksDeleteFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.DisksDeleteFuture") + return + } + ar.Response = future.Response() + return +} + +// DisksGrantAccessFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type DisksGrantAccessFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *DisksGrantAccessFuture) Result(client DisksClient) (au AccessURI, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.DisksGrantAccessFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.DisksGrantAccessFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if au.Response.Response, err = future.GetResult(sender); err == nil && au.Response.Response.StatusCode != http.StatusNoContent { + au, err = client.GrantAccessResponder(au.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.DisksGrantAccessFuture", "Result", au.Response.Response, "Failure responding to request") + } + } + return +} + +// DiskSku the disks sku name. Can be Standard_LRS, Premium_LRS, StandardSSD_LRS, or UltraSSD_LRS. +type DiskSku struct { + // Name - The sku name. Possible values include: 'StandardLRS', 'PremiumLRS', 'StandardSSDLRS', 'UltraSSDLRS' + Name DiskStorageAccountTypes `json:"name,omitempty"` + // Tier - The sku tier. + Tier *string `json:"tier,omitempty"` +} + +// DisksRevokeAccessFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type DisksRevokeAccessFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *DisksRevokeAccessFuture) Result(client DisksClient) (ar autorest.Response, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.DisksRevokeAccessFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.DisksRevokeAccessFuture") + return + } + ar.Response = future.Response() + return +} + +// DisksUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type DisksUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *DisksUpdateFuture) Result(client DisksClient) (d Disk, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.DisksUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.DisksUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if d.Response.Response, err = future.GetResult(sender); err == nil && d.Response.Response.StatusCode != http.StatusNoContent { + d, err = client.UpdateResponder(d.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.DisksUpdateFuture", "Result", d.Response.Response, "Failure responding to request") + } + } + return +} + +// DiskUpdate disk update resource. +type DiskUpdate struct { + *DiskUpdateProperties `json:"properties,omitempty"` + // Tags - Resource tags + Tags map[string]*string `json:"tags"` + Sku *DiskSku `json:"sku,omitempty"` +} + +// MarshalJSON is the custom marshaler for DiskUpdate. +func (du DiskUpdate) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if du.DiskUpdateProperties != nil { + objectMap["properties"] = du.DiskUpdateProperties + } + if du.Tags != nil { + objectMap["tags"] = du.Tags + } + if du.Sku != nil { + objectMap["sku"] = du.Sku + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for DiskUpdate struct. +func (du *DiskUpdate) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var diskUpdateProperties DiskUpdateProperties + err = json.Unmarshal(*v, &diskUpdateProperties) + if err != nil { + return err + } + du.DiskUpdateProperties = &diskUpdateProperties + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + du.Tags = tags + } + case "sku": + if v != nil { + var sku DiskSku + err = json.Unmarshal(*v, &sku) + if err != nil { + return err + } + du.Sku = &sku + } + } + } + + return nil +} + +// DiskUpdateProperties disk resource update properties. +type DiskUpdateProperties struct { + // OsType - the Operating System type. Possible values include: 'Windows', 'Linux' + OsType OperatingSystemTypes `json:"osType,omitempty"` + // DiskSizeGB - If creationData.createOption is Empty, this field is mandatory and it indicates the size of the VHD to create. If this field is present for updates or creation with other options, it indicates a resize. Resizes are only allowed if the disk is not attached to a running VM, and can only increase the disk's size. + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + // EncryptionSettings - Encryption settings for disk or snapshot + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` + // DiskIOPSReadWrite - The number of IOPS allowed for this disk; only settable for UltraSSD disks. One operation can transfer between 4k and 256k bytes. + DiskIOPSReadWrite *int64 `json:"diskIOPSReadWrite,omitempty"` + // DiskMBpsReadWrite - The bandwidth allowed for this disk; only settable for UltraSSD disks. MBps means millions of bytes per second - MB here uses the ISO notation, of powers of 10. + DiskMBpsReadWrite *int32 `json:"diskMBpsReadWrite,omitempty"` +} + +// EncryptionSettings encryption settings for disk or snapshot +type EncryptionSettings struct { + // Enabled - Set this flag to true and provide DiskEncryptionKey and optional KeyEncryptionKey to enable encryption. Set this flag to false and remove DiskEncryptionKey and KeyEncryptionKey to disable encryption. If EncryptionSettings is null in the request object, the existing settings remain unchanged. + Enabled *bool `json:"enabled,omitempty"` + // DiskEncryptionKey - Key Vault Secret Url and vault id of the disk encryption key + DiskEncryptionKey *KeyVaultAndSecretReference `json:"diskEncryptionKey,omitempty"` + // KeyEncryptionKey - Key Vault Key Url and vault id of the key encryption key + KeyEncryptionKey *KeyVaultAndKeyReference `json:"keyEncryptionKey,omitempty"` +} + +// GalleriesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running +// operation. +type GalleriesCreateOrUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *GalleriesCreateOrUpdateFuture) Result(client GalleriesClient) (g Gallery, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.GalleriesCreateOrUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if g.Response.Response, err = future.GetResult(sender); err == nil && g.Response.Response.StatusCode != http.StatusNoContent { + g, err = client.CreateOrUpdateResponder(g.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesCreateOrUpdateFuture", "Result", g.Response.Response, "Failure responding to request") + } + } + return +} + +// GalleriesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type GalleriesDeleteFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *GalleriesDeleteFuture) Result(client GalleriesClient) (ar autorest.Response, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleriesDeleteFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.GalleriesDeleteFuture") + return + } + ar.Response = future.Response() + return +} + +// Gallery specifies information about the Shared Image Gallery that you want to create or update. +type Gallery struct { + autorest.Response `json:"-"` + *GalleryProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Resource location + Location *string `json:"location,omitempty"` + // Tags - Resource tags + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for Gallery. +func (g Gallery) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if g.GalleryProperties != nil { + objectMap["properties"] = g.GalleryProperties + } + if g.ID != nil { + objectMap["id"] = g.ID + } + if g.Name != nil { + objectMap["name"] = g.Name + } + if g.Type != nil { + objectMap["type"] = g.Type + } + if g.Location != nil { + objectMap["location"] = g.Location + } + if g.Tags != nil { + objectMap["tags"] = g.Tags + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Gallery struct. +func (g *Gallery) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var galleryProperties GalleryProperties + err = json.Unmarshal(*v, &galleryProperties) + if err != nil { + return err + } + g.GalleryProperties = &galleryProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + g.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + g.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + g.Type = &typeVar + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + g.Location = &location + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + g.Tags = tags + } + } + } + + return nil +} + +// GalleryArtifactPublishingProfileBase describes the basic gallery artifact publishing profile. +type GalleryArtifactPublishingProfileBase struct { + // TargetRegions - The target regions where the Image Version is going to be replicated to. This property is updateable. + TargetRegions *[]TargetRegion `json:"targetRegions,omitempty"` + Source *GalleryArtifactSource `json:"source,omitempty"` +} + +// GalleryArtifactSource the source image from which the Image Version is going to be created. +type GalleryArtifactSource struct { + ManagedImage *ManagedArtifact `json:"managedImage,omitempty"` +} + +// GalleryDataDiskImage this is the data disk image. +type GalleryDataDiskImage struct { + // Lun - This property specifies the logical unit number of the data disk. This value is used to identify data disks within the Virtual Machine and therefore must be unique for each data disk attached to the Virtual Machine. + Lun *int32 `json:"lun,omitempty"` + // SizeInGB - This property indicates the size of the VHD to be created. + SizeInGB *int32 `json:"sizeInGB,omitempty"` + // HostCaching - The host caching of the disk. Valid values are 'None', 'ReadOnly', and 'ReadWrite'. Possible values include: 'HostCachingNone', 'HostCachingReadOnly', 'HostCachingReadWrite' + HostCaching HostCaching `json:"hostCaching,omitempty"` +} + +// GalleryDiskImage this is the disk image base class. +type GalleryDiskImage struct { + // SizeInGB - This property indicates the size of the VHD to be created. + SizeInGB *int32 `json:"sizeInGB,omitempty"` + // HostCaching - The host caching of the disk. Valid values are 'None', 'ReadOnly', and 'ReadWrite'. Possible values include: 'HostCachingNone', 'HostCachingReadOnly', 'HostCachingReadWrite' + HostCaching HostCaching `json:"hostCaching,omitempty"` +} + +// GalleryIdentifier describes the gallery unique name. +type GalleryIdentifier struct { + // UniqueName - The unique name of the Shared Image Gallery. This name is generated automatically by Azure. + UniqueName *string `json:"uniqueName,omitempty"` +} + +// GalleryImage specifies information about the gallery Image Definition that you want to create or update. +type GalleryImage struct { + autorest.Response `json:"-"` + *GalleryImageProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Resource location + Location *string `json:"location,omitempty"` + // Tags - Resource tags + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for GalleryImage. +func (gi GalleryImage) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if gi.GalleryImageProperties != nil { + objectMap["properties"] = gi.GalleryImageProperties } - if d.DiskProperties != nil { - objectMap["properties"] = d.DiskProperties + if gi.ID != nil { + objectMap["id"] = gi.ID + } + if gi.Name != nil { + objectMap["name"] = gi.Name + } + if gi.Type != nil { + objectMap["type"] = gi.Type + } + if gi.Location != nil { + objectMap["location"] = gi.Location + } + if gi.Tags != nil { + objectMap["tags"] = gi.Tags + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for GalleryImage struct. +func (gi *GalleryImage) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var galleryImageProperties GalleryImageProperties + err = json.Unmarshal(*v, &galleryImageProperties) + if err != nil { + return err + } + gi.GalleryImageProperties = &galleryImageProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + gi.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + gi.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + gi.Type = &typeVar + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + gi.Location = &location + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + gi.Tags = tags + } + } + } + + return nil +} + +// GalleryImageIdentifier this is the gallery Image Definition identifier. +type GalleryImageIdentifier struct { + // Publisher - The name of the gallery Image Definition publisher. + Publisher *string `json:"publisher,omitempty"` + // Offer - The name of the gallery Image Definition offer. + Offer *string `json:"offer,omitempty"` + // Sku - The name of the gallery Image Definition SKU. + Sku *string `json:"sku,omitempty"` +} + +// GalleryImageList the List Gallery Images operation response. +type GalleryImageList struct { + autorest.Response `json:"-"` + // Value - A list of Shared Image Gallery images. + Value *[]GalleryImage `json:"value,omitempty"` + // NextLink - The uri to fetch the next page of Image Definitions in the Shared Image Gallery. Call ListNext() with this to fetch the next page of gallery Image Definitions. + NextLink *string `json:"nextLink,omitempty"` +} + +// GalleryImageListIterator provides access to a complete listing of GalleryImage values. +type GalleryImageListIterator struct { + i int + page GalleryImageListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *GalleryImageListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter GalleryImageListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter GalleryImageListIterator) Response() GalleryImageList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter GalleryImageListIterator) Value() GalleryImage { + if !iter.page.NotDone() { + return GalleryImage{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (gil GalleryImageList) IsEmpty() bool { + return gil.Value == nil || len(*gil.Value) == 0 +} + +// galleryImageListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (gil GalleryImageList) galleryImageListPreparer() (*http.Request, error) { + if gil.NextLink == nil || len(to.String(gil.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(gil.NextLink))) +} + +// GalleryImageListPage contains a page of GalleryImage values. +type GalleryImageListPage struct { + fn func(GalleryImageList) (GalleryImageList, error) + gil GalleryImageList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *GalleryImageListPage) Next() error { + next, err := page.fn(page.gil) + if err != nil { + return err + } + page.gil = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page GalleryImageListPage) NotDone() bool { + return !page.gil.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page GalleryImageListPage) Response() GalleryImageList { + return page.gil +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page GalleryImageListPage) Values() []GalleryImage { + if page.gil.IsEmpty() { + return nil + } + return *page.gil.Value +} + +// GalleryImageProperties describes the properties of a gallery Image Definition. +type GalleryImageProperties struct { + // Description - The description of this gallery Image Definition resource. This property is updateable. + Description *string `json:"description,omitempty"` + // Eula - The Eula agreement for the gallery Image Definition. + Eula *string `json:"eula,omitempty"` + // PrivacyStatementURI - The privacy statement uri. + PrivacyStatementURI *string `json:"privacyStatementUri,omitempty"` + // ReleaseNoteURI - The release note uri. + ReleaseNoteURI *string `json:"releaseNoteUri,omitempty"` + // OsType - This property allows you to specify the type of the OS that is included in the disk when creating a VM from a managed image.

Possible values are:

**Windows**

**Linux**. Possible values include: 'Windows', 'Linux' + OsType OperatingSystemTypes `json:"osType,omitempty"` + // OsState - The allowed values for OS State are 'Generalized'. Possible values include: 'Generalized', 'Specialized' + OsState OperatingSystemStateTypes `json:"osState,omitempty"` + // EndOfLifeDate - The end of life date of the gallery Image Definition. This property can be used for decommissioning purposes. This property is updateable. + EndOfLifeDate *date.Time `json:"endOfLifeDate,omitempty"` + Identifier *GalleryImageIdentifier `json:"identifier,omitempty"` + Recommended *RecommendedMachineConfiguration `json:"recommended,omitempty"` + Disallowed *Disallowed `json:"disallowed,omitempty"` + PurchasePlan *ImagePurchasePlan `json:"purchasePlan,omitempty"` + // ProvisioningState - The provisioning state, which only appears in the response. Possible values include: 'ProvisioningState1Creating', 'ProvisioningState1Updating', 'ProvisioningState1Failed', 'ProvisioningState1Succeeded', 'ProvisioningState1Deleting', 'ProvisioningState1Migrating' + ProvisioningState ProvisioningState1 `json:"provisioningState,omitempty"` +} + +// GalleryImagesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running +// operation. +type GalleryImagesCreateOrUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *GalleryImagesCreateOrUpdateFuture) Result(client GalleryImagesClient) (gi GalleryImage, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.GalleryImagesCreateOrUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if gi.Response.Response, err = future.GetResult(sender); err == nil && gi.Response.Response.StatusCode != http.StatusNoContent { + gi, err = client.CreateOrUpdateResponder(gi.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesCreateOrUpdateFuture", "Result", gi.Response.Response, "Failure responding to request") + } + } + return +} + +// GalleryImagesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type GalleryImagesDeleteFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *GalleryImagesDeleteFuture) Result(client GalleryImagesClient) (ar autorest.Response, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.GalleryImagesDeleteFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.GalleryImagesDeleteFuture") + return + } + ar.Response = future.Response() + return +} + +// GalleryImageVersion specifies information about the gallery Image Version that you want to create or update. +type GalleryImageVersion struct { + autorest.Response `json:"-"` + *GalleryImageVersionProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Resource location + Location *string `json:"location,omitempty"` + // Tags - Resource tags + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for GalleryImageVersion. +func (giv GalleryImageVersion) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if giv.GalleryImageVersionProperties != nil { + objectMap["properties"] = giv.GalleryImageVersionProperties } - if d.ID != nil { - objectMap["id"] = d.ID + if giv.ID != nil { + objectMap["id"] = giv.ID } - if d.Name != nil { - objectMap["name"] = d.Name + if giv.Name != nil { + objectMap["name"] = giv.Name } - if d.Type != nil { - objectMap["type"] = d.Type + if giv.Type != nil { + objectMap["type"] = giv.Type } - if d.Location != nil { - objectMap["location"] = d.Location + if giv.Location != nil { + objectMap["location"] = giv.Location } - if d.Tags != nil { - objectMap["tags"] = d.Tags + if giv.Tags != nil { + objectMap["tags"] = giv.Tags } return json.Marshal(objectMap) } -// UnmarshalJSON is the custom unmarshaler for Disk struct. -func (d *Disk) UnmarshalJSON(body []byte) error { +// UnmarshalJSON is the custom unmarshaler for GalleryImageVersion struct. +func (giv *GalleryImageVersion) UnmarshalJSON(body []byte) error { var m map[string]*json.RawMessage err := json.Unmarshal(body, &m) if err != nil { @@ -1293,41 +3043,14 @@ func (d *Disk) UnmarshalJSON(body []byte) error { } for k, v := range m { switch k { - case "managedBy": - if v != nil { - var managedBy string - err = json.Unmarshal(*v, &managedBy) - if err != nil { - return err - } - d.ManagedBy = &managedBy - } - case "sku": - if v != nil { - var sku DiskSku - err = json.Unmarshal(*v, &sku) - if err != nil { - return err - } - d.Sku = &sku - } - case "zones": - if v != nil { - var zones []string - err = json.Unmarshal(*v, &zones) - if err != nil { - return err - } - d.Zones = &zones - } case "properties": if v != nil { - var diskProperties DiskProperties - err = json.Unmarshal(*v, &diskProperties) + var galleryImageVersionProperties GalleryImageVersionProperties + err = json.Unmarshal(*v, &galleryImageVersionProperties) if err != nil { return err } - d.DiskProperties = &diskProperties + giv.GalleryImageVersionProperties = &galleryImageVersionProperties } case "id": if v != nil { @@ -1336,7 +3059,7 @@ func (d *Disk) UnmarshalJSON(body []byte) error { if err != nil { return err } - d.ID = &ID + giv.ID = &ID } case "name": if v != nil { @@ -1345,7 +3068,7 @@ func (d *Disk) UnmarshalJSON(body []byte) error { if err != nil { return err } - d.Name = &name + giv.Name = &name } case "type": if v != nil { @@ -1354,7 +3077,7 @@ func (d *Disk) UnmarshalJSON(body []byte) error { if err != nil { return err } - d.Type = &typeVar + giv.Type = &typeVar } case "location": if v != nil { @@ -1363,7 +3086,7 @@ func (d *Disk) UnmarshalJSON(body []byte) error { if err != nil { return err } - d.Location = &location + giv.Location = &location } case "tags": if v != nil { @@ -1372,7 +3095,7 @@ func (d *Disk) UnmarshalJSON(body []byte) error { if err != nil { return err } - d.Tags = tags + giv.Tags = tags } } } @@ -1380,44 +3103,24 @@ func (d *Disk) UnmarshalJSON(body []byte) error { return nil } -// DiskEncryptionSettings describes a Encryption Settings for a Disk -type DiskEncryptionSettings struct { - // DiskEncryptionKey - Specifies the location of the disk encryption key, which is a Key Vault Secret. - DiskEncryptionKey *KeyVaultSecretReference `json:"diskEncryptionKey,omitempty"` - // KeyEncryptionKey - Specifies the location of the key encryption key in Key Vault. - KeyEncryptionKey *KeyVaultKeyReference `json:"keyEncryptionKey,omitempty"` - // Enabled - Specifies whether disk encryption should be enabled on the virtual machine. - Enabled *bool `json:"enabled,omitempty"` -} - -// DiskInstanceView the instance view of the disk. -type DiskInstanceView struct { - // Name - The disk name. - Name *string `json:"name,omitempty"` - // EncryptionSettings - Specifies the encryption settings for the OS Disk.

Minimum api-version: 2015-06-15 - EncryptionSettings *[]DiskEncryptionSettings `json:"encryptionSettings,omitempty"` - // Statuses - The resource status information. - Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` -} - -// DiskList the List Disks operation response. -type DiskList struct { +// GalleryImageVersionList the List Gallery Image version operation response. +type GalleryImageVersionList struct { autorest.Response `json:"-"` - // Value - A list of disks. - Value *[]Disk `json:"value,omitempty"` - // NextLink - The uri to fetch the next page of disks. Call ListNext() with this to fetch the next page of disks. + // Value - A list of gallery Image Versions. + Value *[]GalleryImageVersion `json:"value,omitempty"` + // NextLink - The uri to fetch the next page of gallery Image Versions. Call ListNext() with this to fetch the next page of gallery Image Versions. NextLink *string `json:"nextLink,omitempty"` } -// DiskListIterator provides access to a complete listing of Disk values. -type DiskListIterator struct { +// GalleryImageVersionListIterator provides access to a complete listing of GalleryImageVersion values. +type GalleryImageVersionListIterator struct { i int - page DiskListPage + page GalleryImageVersionListPage } // Next advances to the next value. If there was an error making // the request the iterator does not advance and the error is returned. -func (iter *DiskListIterator) Next() error { +func (iter *GalleryImageVersionListIterator) Next() error { iter.i++ if iter.i < len(iter.page.Values()) { return nil @@ -1432,311 +3135,276 @@ func (iter *DiskListIterator) Next() error { } // NotDone returns true if the enumeration should be started or is not yet complete. -func (iter DiskListIterator) NotDone() bool { +func (iter GalleryImageVersionListIterator) NotDone() bool { return iter.page.NotDone() && iter.i < len(iter.page.Values()) } // Response returns the raw server response from the last page request. -func (iter DiskListIterator) Response() DiskList { +func (iter GalleryImageVersionListIterator) Response() GalleryImageVersionList { return iter.page.Response() } // Value returns the current value or a zero-initialized value if the // iterator has advanced beyond the end of the collection. -func (iter DiskListIterator) Value() Disk { +func (iter GalleryImageVersionListIterator) Value() GalleryImageVersion { if !iter.page.NotDone() { - return Disk{} + return GalleryImageVersion{} } return iter.page.Values()[iter.i] } // IsEmpty returns true if the ListResult contains no values. -func (dl DiskList) IsEmpty() bool { - return dl.Value == nil || len(*dl.Value) == 0 +func (givl GalleryImageVersionList) IsEmpty() bool { + return givl.Value == nil || len(*givl.Value) == 0 } -// diskListPreparer prepares a request to retrieve the next set of results. +// galleryImageVersionListPreparer prepares a request to retrieve the next set of results. // It returns nil if no more results exist. -func (dl DiskList) diskListPreparer() (*http.Request, error) { - if dl.NextLink == nil || len(to.String(dl.NextLink)) < 1 { +func (givl GalleryImageVersionList) galleryImageVersionListPreparer() (*http.Request, error) { + if givl.NextLink == nil || len(to.String(givl.NextLink)) < 1 { return nil, nil } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), autorest.AsGet(), - autorest.WithBaseURL(to.String(dl.NextLink))) + autorest.WithBaseURL(to.String(givl.NextLink))) } -// DiskListPage contains a page of Disk values. -type DiskListPage struct { - fn func(DiskList) (DiskList, error) - dl DiskList +// GalleryImageVersionListPage contains a page of GalleryImageVersion values. +type GalleryImageVersionListPage struct { + fn func(GalleryImageVersionList) (GalleryImageVersionList, error) + givl GalleryImageVersionList } // Next advances to the next page of values. If there was an error making // the request the page does not advance and the error is returned. -func (page *DiskListPage) Next() error { - next, err := page.fn(page.dl) +func (page *GalleryImageVersionListPage) Next() error { + next, err := page.fn(page.givl) if err != nil { return err } - page.dl = next + page.givl = next return nil } // NotDone returns true if the page enumeration should be started or is not yet complete. -func (page DiskListPage) NotDone() bool { - return !page.dl.IsEmpty() +func (page GalleryImageVersionListPage) NotDone() bool { + return !page.givl.IsEmpty() } // Response returns the raw server response from the last page request. -func (page DiskListPage) Response() DiskList { - return page.dl +func (page GalleryImageVersionListPage) Response() GalleryImageVersionList { + return page.givl } // Values returns the slice of values for the current page or nil if there are no values. -func (page DiskListPage) Values() []Disk { - if page.dl.IsEmpty() { +func (page GalleryImageVersionListPage) Values() []GalleryImageVersion { + if page.givl.IsEmpty() { return nil } - return *page.dl.Value + return *page.givl.Value } -// DiskProperties disk resource properties. -type DiskProperties struct { - // TimeCreated - The time when the disk was created. - TimeCreated *date.Time `json:"timeCreated,omitempty"` - // OsType - The Operating System type. Possible values include: 'Windows', 'Linux' - OsType OperatingSystemTypes `json:"osType,omitempty"` - // CreationData - Disk source information. CreationData information cannot be changed after the disk has been created. - CreationData *CreationData `json:"creationData,omitempty"` - // DiskSizeGB - If creationData.createOption is Empty, this field is mandatory and it indicates the size of the VHD to create. If this field is present for updates or creation with other options, it indicates a resize. Resizes are only allowed if the disk is not attached to a running VM, and can only increase the disk's size. - DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` - // EncryptionSettings - Encryption settings for disk or snapshot - EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` - // ProvisioningState - The disk provisioning state. - ProvisioningState *string `json:"provisioningState,omitempty"` +// GalleryImageVersionProperties describes the properties of a gallery Image Version. +type GalleryImageVersionProperties struct { + PublishingProfile *GalleryImageVersionPublishingProfile `json:"publishingProfile,omitempty"` + // ProvisioningState - The provisioning state, which only appears in the response. Possible values include: 'ProvisioningState2Creating', 'ProvisioningState2Updating', 'ProvisioningState2Failed', 'ProvisioningState2Succeeded', 'ProvisioningState2Deleting', 'ProvisioningState2Migrating' + ProvisioningState ProvisioningState2 `json:"provisioningState,omitempty"` + StorageProfile *GalleryImageVersionStorageProfile `json:"storageProfile,omitempty"` + ReplicationStatus *ReplicationStatus `json:"replicationStatus,omitempty"` } -// DisksCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. -type DisksCreateOrUpdateFuture struct { +// GalleryImageVersionPublishingProfile the publishing profile of a gallery Image Version. +type GalleryImageVersionPublishingProfile struct { + // ReplicaCount - The number of replicas of the Image Version to be created per region. This property would take effect for a region when regionalReplicaCount is not specified. This property is updateable. + ReplicaCount *int32 `json:"replicaCount,omitempty"` + // ExcludeFromLatest - If set to true, Virtual Machines deployed from the latest version of the Image Definition won't use this Image Version. + ExcludeFromLatest *bool `json:"excludeFromLatest,omitempty"` + // PublishedDate - The timestamp for when the gallery Image Version is published. + PublishedDate *date.Time `json:"publishedDate,omitempty"` + // EndOfLifeDate - The end of life date of the gallery Image Version. This property can be used for decommissioning purposes. This property is updateable. + EndOfLifeDate *date.Time `json:"endOfLifeDate,omitempty"` + // TargetRegions - The target regions where the Image Version is going to be replicated to. This property is updateable. + TargetRegions *[]TargetRegion `json:"targetRegions,omitempty"` + Source *GalleryArtifactSource `json:"source,omitempty"` +} + +// GalleryImageVersionsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a +// long-running operation. +type GalleryImageVersionsCreateOrUpdateFuture struct { azure.Future } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future *DisksCreateOrUpdateFuture) Result(client DisksClient) (d Disk, err error) { +func (future *GalleryImageVersionsCreateOrUpdateFuture) Result(client GalleryImageVersionsClient) (giv GalleryImageVersion, err error) { var done bool done, err = future.Done(client) if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") return } if !done { - err = azure.NewAsyncOpIncompleteError("compute.DisksCreateOrUpdateFuture") + err = azure.NewAsyncOpIncompleteError("compute.GalleryImageVersionsCreateOrUpdateFuture") return } sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if d.Response.Response, err = future.GetResult(sender); err == nil && d.Response.Response.StatusCode != http.StatusNoContent { - d, err = client.CreateOrUpdateResponder(d.Response.Response) + if giv.Response.Response, err = future.GetResult(sender); err == nil && giv.Response.Response.StatusCode != http.StatusNoContent { + giv, err = client.CreateOrUpdateResponder(giv.Response.Response) if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksCreateOrUpdateFuture", "Result", d.Response.Response, "Failure responding to request") + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsCreateOrUpdateFuture", "Result", giv.Response.Response, "Failure responding to request") } } return } -// DisksDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. -type DisksDeleteFuture struct { +// GalleryImageVersionsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running +// operation. +type GalleryImageVersionsDeleteFuture struct { azure.Future } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future *DisksDeleteFuture) Result(client DisksClient) (ar autorest.Response, err error) { +func (future *GalleryImageVersionsDeleteFuture) Result(client GalleryImageVersionsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksDeleteFuture", "Result", future.Response(), "Polling failure") + err = autorest.NewErrorWithError(err, "compute.GalleryImageVersionsDeleteFuture", "Result", future.Response(), "Polling failure") return } if !done { - err = azure.NewAsyncOpIncompleteError("compute.DisksDeleteFuture") + err = azure.NewAsyncOpIncompleteError("compute.GalleryImageVersionsDeleteFuture") return } ar.Response = future.Response() return } -// DisksGrantAccessFuture an abstraction for monitoring and retrieving the results of a long-running operation. -type DisksGrantAccessFuture struct { - azure.Future -} - -// Result returns the result of the asynchronous operation. -// If the operation has not completed it will return an error. -func (future *DisksGrantAccessFuture) Result(client DisksClient) (au AccessURI, err error) { - var done bool - done, err = future.Done(client) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksGrantAccessFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - err = azure.NewAsyncOpIncompleteError("compute.DisksGrantAccessFuture") - return - } - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if au.Response.Response, err = future.GetResult(sender); err == nil && au.Response.Response.StatusCode != http.StatusNoContent { - au, err = client.GrantAccessResponder(au.Response.Response) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksGrantAccessFuture", "Result", au.Response.Response, "Failure responding to request") - } - } - return +// GalleryImageVersionStorageProfile this is the storage profile of a gallery Image Version. +type GalleryImageVersionStorageProfile struct { + OsDiskImage *GalleryOSDiskImage `json:"osDiskImage,omitempty"` + // DataDiskImages - A list of data disk images. + DataDiskImages *[]GalleryDataDiskImage `json:"dataDiskImages,omitempty"` } -// DiskSku the disks sku name. Can be Standard_LRS, Premium_LRS, or StandardSSD_LRS. -type DiskSku struct { - // Name - The sku name. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS' - Name StorageAccountTypes `json:"name,omitempty"` - // Tier - The sku tier. - Tier *string `json:"tier,omitempty"` +// GalleryList the List Galleries operation response. +type GalleryList struct { + autorest.Response `json:"-"` + // Value - A list of galleries. + Value *[]Gallery `json:"value,omitempty"` + // NextLink - The uri to fetch the next page of galleries. Call ListNext() with this to fetch the next page of galleries. + NextLink *string `json:"nextLink,omitempty"` } -// DisksRevokeAccessFuture an abstraction for monitoring and retrieving the results of a long-running operation. -type DisksRevokeAccessFuture struct { - azure.Future +// GalleryListIterator provides access to a complete listing of Gallery values. +type GalleryListIterator struct { + i int + page GalleryListPage } -// Result returns the result of the asynchronous operation. -// If the operation has not completed it will return an error. -func (future *DisksRevokeAccessFuture) Result(client DisksClient) (ar autorest.Response, err error) { - var done bool - done, err = future.Done(client) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksRevokeAccessFuture", "Result", future.Response(), "Polling failure") - return +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *GalleryListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil } - if !done { - err = azure.NewAsyncOpIncompleteError("compute.DisksRevokeAccessFuture") - return + err := iter.page.Next() + if err != nil { + iter.i-- + return err } - ar.Response = future.Response() - return + iter.i = 0 + return nil } -// DisksUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. -type DisksUpdateFuture struct { - azure.Future +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter GalleryListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) } -// Result returns the result of the asynchronous operation. -// If the operation has not completed it will return an error. -func (future *DisksUpdateFuture) Result(client DisksClient) (d Disk, err error) { - var done bool - done, err = future.Done(client) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksUpdateFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - err = azure.NewAsyncOpIncompleteError("compute.DisksUpdateFuture") - return - } - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if d.Response.Response, err = future.GetResult(sender); err == nil && d.Response.Response.StatusCode != http.StatusNoContent { - d, err = client.UpdateResponder(d.Response.Response) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksUpdateFuture", "Result", d.Response.Response, "Failure responding to request") - } +// Response returns the raw server response from the last page request. +func (iter GalleryListIterator) Response() GalleryList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter GalleryListIterator) Value() Gallery { + if !iter.page.NotDone() { + return Gallery{} } - return + return iter.page.Values()[iter.i] } -// DiskUpdate disk update resource. -type DiskUpdate struct { - *DiskUpdateProperties `json:"properties,omitempty"` - // Tags - Resource tags - Tags map[string]*string `json:"tags"` - Sku *DiskSku `json:"sku,omitempty"` +// IsEmpty returns true if the ListResult contains no values. +func (gl GalleryList) IsEmpty() bool { + return gl.Value == nil || len(*gl.Value) == 0 } -// MarshalJSON is the custom marshaler for DiskUpdate. -func (du DiskUpdate) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if du.DiskUpdateProperties != nil { - objectMap["properties"] = du.DiskUpdateProperties - } - if du.Tags != nil { - objectMap["tags"] = du.Tags - } - if du.Sku != nil { - objectMap["sku"] = du.Sku +// galleryListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (gl GalleryList) galleryListPreparer() (*http.Request, error) { + if gl.NextLink == nil || len(to.String(gl.NextLink)) < 1 { + return nil, nil } - return json.Marshal(objectMap) + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(gl.NextLink))) } -// UnmarshalJSON is the custom unmarshaler for DiskUpdate struct. -func (du *DiskUpdate) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) +// GalleryListPage contains a page of Gallery values. +type GalleryListPage struct { + fn func(GalleryList) (GalleryList, error) + gl GalleryList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *GalleryListPage) Next() error { + next, err := page.fn(page.gl) if err != nil { return err } - for k, v := range m { - switch k { - case "properties": - if v != nil { - var diskUpdateProperties DiskUpdateProperties - err = json.Unmarshal(*v, &diskUpdateProperties) - if err != nil { - return err - } - du.DiskUpdateProperties = &diskUpdateProperties - } - case "tags": - if v != nil { - var tags map[string]*string - err = json.Unmarshal(*v, &tags) - if err != nil { - return err - } - du.Tags = tags - } - case "sku": - if v != nil { - var sku DiskSku - err = json.Unmarshal(*v, &sku) - if err != nil { - return err - } - du.Sku = &sku - } - } - } - + page.gl = next return nil } -// DiskUpdateProperties disk resource update properties. -type DiskUpdateProperties struct { - // OsType - the Operating System type. Possible values include: 'Windows', 'Linux' - OsType OperatingSystemTypes `json:"osType,omitempty"` - // DiskSizeGB - If creationData.createOption is Empty, this field is mandatory and it indicates the size of the VHD to create. If this field is present for updates or creation with other options, it indicates a resize. Resizes are only allowed if the disk is not attached to a running VM, and can only increase the disk's size. - DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` - // EncryptionSettings - Encryption settings for disk or snapshot - EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page GalleryListPage) NotDone() bool { + return !page.gl.IsEmpty() } -// EncryptionSettings encryption settings for disk or snapshot -type EncryptionSettings struct { - // Enabled - Set this flag to true and provide DiskEncryptionKey and optional KeyEncryptionKey to enable encryption. Set this flag to false and remove DiskEncryptionKey and KeyEncryptionKey to disable encryption. If EncryptionSettings is null in the request object, the existing settings remain unchanged. - Enabled *bool `json:"enabled,omitempty"` - // DiskEncryptionKey - Key Vault Secret Url and vault id of the disk encryption key - DiskEncryptionKey *KeyVaultAndSecretReference `json:"diskEncryptionKey,omitempty"` - // KeyEncryptionKey - Key Vault Key Url and vault id of the key encryption key - KeyEncryptionKey *KeyVaultAndKeyReference `json:"keyEncryptionKey,omitempty"` +// Response returns the raw server response from the last page request. +func (page GalleryListPage) Response() GalleryList { + return page.gl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page GalleryListPage) Values() []Gallery { + if page.gl.IsEmpty() { + return nil + } + return *page.gl.Value +} + +// GalleryOSDiskImage this is the OS disk image. +type GalleryOSDiskImage struct { + // SizeInGB - This property indicates the size of the VHD to be created. + SizeInGB *int32 `json:"sizeInGB,omitempty"` + // HostCaching - The host caching of the disk. Valid values are 'None', 'ReadOnly', and 'ReadWrite'. Possible values include: 'HostCachingNone', 'HostCachingReadOnly', 'HostCachingReadWrite' + HostCaching HostCaching `json:"hostCaching,omitempty"` +} + +// GalleryProperties describes the properties of a Shared Image Gallery. +type GalleryProperties struct { + // Description - The description of this Shared Image Gallery resource. This property is updateable. + Description *string `json:"description,omitempty"` + Identifier *GalleryIdentifier `json:"identifier,omitempty"` + // ProvisioningState - The provisioning state, which only appears in the response. Possible values include: 'ProvisioningStateCreating', 'ProvisioningStateUpdating', 'ProvisioningStateFailed', 'ProvisioningStateSucceeded', 'ProvisioningStateDeleting', 'ProvisioningStateMigrating' + ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` } // GrantAccessData data used for requesting a SAS. @@ -1749,7 +3417,7 @@ type GrantAccessData struct { // HardwareProfile specifies the hardware settings for the virtual machine. type HardwareProfile struct { - // VMSize - Specifies the size of the virtual machine. For more information about virtual machine sizes, see [Sizes for virtual machines](https://docs.microsoft.com/azure/virtual-machines/virtual-machines-windows-sizes?toc=%2fazure%2fvirtual-machines%2fwindows%2ftoc.json).

The available VM sizes depend on region and availability set. For a list of available sizes use these APIs:

[List all available virtual machine sizes in an availability set](https://docs.microsoft.com/rest/api/compute/availabilitysets/listavailablesizes)

[List all available virtual machine sizes in a region](https://docs.microsoft.com/rest/api/compute/virtualmachinesizes/list)

[List all available virtual machine sizes for resizing](https://docs.microsoft.com/rest/api/compute/virtualmachines/listavailablesizes). Possible values include: 'BasicA0', 'BasicA1', 'BasicA2', 'BasicA3', 'BasicA4', 'StandardA0', 'StandardA1', 'StandardA2', 'StandardA3', 'StandardA4', 'StandardA5', 'StandardA6', 'StandardA7', 'StandardA8', 'StandardA9', 'StandardA10', 'StandardA11', 'StandardA1V2', 'StandardA2V2', 'StandardA4V2', 'StandardA8V2', 'StandardA2mV2', 'StandardA4mV2', 'StandardA8mV2', 'StandardB1s', 'StandardB1ms', 'StandardB2s', 'StandardB2ms', 'StandardB4ms', 'StandardB8ms', 'StandardD1', 'StandardD2', 'StandardD3', 'StandardD4', 'StandardD11', 'StandardD12', 'StandardD13', 'StandardD14', 'StandardD1V2', 'StandardD2V2', 'StandardD3V2', 'StandardD4V2', 'StandardD5V2', 'StandardD2V3', 'StandardD4V3', 'StandardD8V3', 'StandardD16V3', 'StandardD32V3', 'StandardD64V3', 'StandardD2sV3', 'StandardD4sV3', 'StandardD8sV3', 'StandardD16sV3', 'StandardD32sV3', 'StandardD64sV3', 'StandardD11V2', 'StandardD12V2', 'StandardD13V2', 'StandardD14V2', 'StandardD15V2', 'StandardDS1', 'StandardDS2', 'StandardDS3', 'StandardDS4', 'StandardDS11', 'StandardDS12', 'StandardDS13', 'StandardDS14', 'StandardDS1V2', 'StandardDS2V2', 'StandardDS3V2', 'StandardDS4V2', 'StandardDS5V2', 'StandardDS11V2', 'StandardDS12V2', 'StandardDS13V2', 'StandardDS14V2', 'StandardDS15V2', 'StandardDS134V2', 'StandardDS132V2', 'StandardDS148V2', 'StandardDS144V2', 'StandardE2V3', 'StandardE4V3', 'StandardE8V3', 'StandardE16V3', 'StandardE32V3', 'StandardE64V3', 'StandardE2sV3', 'StandardE4sV3', 'StandardE8sV3', 'StandardE16sV3', 'StandardE32sV3', 'StandardE64sV3', 'StandardE3216V3', 'StandardE328sV3', 'StandardE6432sV3', 'StandardE6416sV3', 'StandardF1', 'StandardF2', 'StandardF4', 'StandardF8', 'StandardF16', 'StandardF1s', 'StandardF2s', 'StandardF4s', 'StandardF8s', 'StandardF16s', 'StandardF2sV2', 'StandardF4sV2', 'StandardF8sV2', 'StandardF16sV2', 'StandardF32sV2', 'StandardF64sV2', 'StandardF72sV2', 'StandardG1', 'StandardG2', 'StandardG3', 'StandardG4', 'StandardG5', 'StandardGS1', 'StandardGS2', 'StandardGS3', 'StandardGS4', 'StandardGS5', 'StandardGS48', 'StandardGS44', 'StandardGS516', 'StandardGS58', 'StandardH8', 'StandardH16', 'StandardH8m', 'StandardH16m', 'StandardH16r', 'StandardH16mr', 'StandardL4s', 'StandardL8s', 'StandardL16s', 'StandardL32s', 'StandardM64s', 'StandardM64ms', 'StandardM128s', 'StandardM128ms', 'StandardM6432ms', 'StandardM6416ms', 'StandardM12864ms', 'StandardM12832ms', 'StandardNC6', 'StandardNC12', 'StandardNC24', 'StandardNC24r', 'StandardNC6sV2', 'StandardNC12sV2', 'StandardNC24sV2', 'StandardNC24rsV2', 'StandardNC6sV3', 'StandardNC12sV3', 'StandardNC24sV3', 'StandardNC24rsV3', 'StandardND6s', 'StandardND12s', 'StandardND24s', 'StandardND24rs', 'StandardNV6', 'StandardNV12', 'StandardNV24' + // VMSize - Specifies the size of the virtual machine. For more information about virtual machine sizes, see [Sizes for virtual machines](https://docs.microsoft.com/azure/virtual-machines/virtual-machines-windows-sizes?toc=%2fazure%2fvirtual-machines%2fwindows%2ftoc.json).

The available VM sizes depend on region and availability set. For a list of available sizes use these APIs:

[List all available virtual machine sizes in an availability set](https://docs.microsoft.com/rest/api/compute/availabilitysets/listavailablesizes)

[List all available virtual machine sizes in a region](https://docs.microsoft.com/rest/api/compute/virtualmachinesizes/list)

[List all available virtual machine sizes for resizing](https://docs.microsoft.com/rest/api/compute/virtualmachines/listavailablesizes). Possible values include: 'VirtualMachineSizeTypesBasicA0', 'VirtualMachineSizeTypesBasicA1', 'VirtualMachineSizeTypesBasicA2', 'VirtualMachineSizeTypesBasicA3', 'VirtualMachineSizeTypesBasicA4', 'VirtualMachineSizeTypesStandardA0', 'VirtualMachineSizeTypesStandardA1', 'VirtualMachineSizeTypesStandardA2', 'VirtualMachineSizeTypesStandardA3', 'VirtualMachineSizeTypesStandardA4', 'VirtualMachineSizeTypesStandardA5', 'VirtualMachineSizeTypesStandardA6', 'VirtualMachineSizeTypesStandardA7', 'VirtualMachineSizeTypesStandardA8', 'VirtualMachineSizeTypesStandardA9', 'VirtualMachineSizeTypesStandardA10', 'VirtualMachineSizeTypesStandardA11', 'VirtualMachineSizeTypesStandardA1V2', 'VirtualMachineSizeTypesStandardA2V2', 'VirtualMachineSizeTypesStandardA4V2', 'VirtualMachineSizeTypesStandardA8V2', 'VirtualMachineSizeTypesStandardA2mV2', 'VirtualMachineSizeTypesStandardA4mV2', 'VirtualMachineSizeTypesStandardA8mV2', 'VirtualMachineSizeTypesStandardB1s', 'VirtualMachineSizeTypesStandardB1ms', 'VirtualMachineSizeTypesStandardB2s', 'VirtualMachineSizeTypesStandardB2ms', 'VirtualMachineSizeTypesStandardB4ms', 'VirtualMachineSizeTypesStandardB8ms', 'VirtualMachineSizeTypesStandardD1', 'VirtualMachineSizeTypesStandardD2', 'VirtualMachineSizeTypesStandardD3', 'VirtualMachineSizeTypesStandardD4', 'VirtualMachineSizeTypesStandardD11', 'VirtualMachineSizeTypesStandardD12', 'VirtualMachineSizeTypesStandardD13', 'VirtualMachineSizeTypesStandardD14', 'VirtualMachineSizeTypesStandardD1V2', 'VirtualMachineSizeTypesStandardD2V2', 'VirtualMachineSizeTypesStandardD3V2', 'VirtualMachineSizeTypesStandardD4V2', 'VirtualMachineSizeTypesStandardD5V2', 'VirtualMachineSizeTypesStandardD2V3', 'VirtualMachineSizeTypesStandardD4V3', 'VirtualMachineSizeTypesStandardD8V3', 'VirtualMachineSizeTypesStandardD16V3', 'VirtualMachineSizeTypesStandardD32V3', 'VirtualMachineSizeTypesStandardD64V3', 'VirtualMachineSizeTypesStandardD2sV3', 'VirtualMachineSizeTypesStandardD4sV3', 'VirtualMachineSizeTypesStandardD8sV3', 'VirtualMachineSizeTypesStandardD16sV3', 'VirtualMachineSizeTypesStandardD32sV3', 'VirtualMachineSizeTypesStandardD64sV3', 'VirtualMachineSizeTypesStandardD11V2', 'VirtualMachineSizeTypesStandardD12V2', 'VirtualMachineSizeTypesStandardD13V2', 'VirtualMachineSizeTypesStandardD14V2', 'VirtualMachineSizeTypesStandardD15V2', 'VirtualMachineSizeTypesStandardDS1', 'VirtualMachineSizeTypesStandardDS2', 'VirtualMachineSizeTypesStandardDS3', 'VirtualMachineSizeTypesStandardDS4', 'VirtualMachineSizeTypesStandardDS11', 'VirtualMachineSizeTypesStandardDS12', 'VirtualMachineSizeTypesStandardDS13', 'VirtualMachineSizeTypesStandardDS14', 'VirtualMachineSizeTypesStandardDS1V2', 'VirtualMachineSizeTypesStandardDS2V2', 'VirtualMachineSizeTypesStandardDS3V2', 'VirtualMachineSizeTypesStandardDS4V2', 'VirtualMachineSizeTypesStandardDS5V2', 'VirtualMachineSizeTypesStandardDS11V2', 'VirtualMachineSizeTypesStandardDS12V2', 'VirtualMachineSizeTypesStandardDS13V2', 'VirtualMachineSizeTypesStandardDS14V2', 'VirtualMachineSizeTypesStandardDS15V2', 'VirtualMachineSizeTypesStandardDS134V2', 'VirtualMachineSizeTypesStandardDS132V2', 'VirtualMachineSizeTypesStandardDS148V2', 'VirtualMachineSizeTypesStandardDS144V2', 'VirtualMachineSizeTypesStandardE2V3', 'VirtualMachineSizeTypesStandardE4V3', 'VirtualMachineSizeTypesStandardE8V3', 'VirtualMachineSizeTypesStandardE16V3', 'VirtualMachineSizeTypesStandardE32V3', 'VirtualMachineSizeTypesStandardE64V3', 'VirtualMachineSizeTypesStandardE2sV3', 'VirtualMachineSizeTypesStandardE4sV3', 'VirtualMachineSizeTypesStandardE8sV3', 'VirtualMachineSizeTypesStandardE16sV3', 'VirtualMachineSizeTypesStandardE32sV3', 'VirtualMachineSizeTypesStandardE64sV3', 'VirtualMachineSizeTypesStandardE3216V3', 'VirtualMachineSizeTypesStandardE328sV3', 'VirtualMachineSizeTypesStandardE6432sV3', 'VirtualMachineSizeTypesStandardE6416sV3', 'VirtualMachineSizeTypesStandardF1', 'VirtualMachineSizeTypesStandardF2', 'VirtualMachineSizeTypesStandardF4', 'VirtualMachineSizeTypesStandardF8', 'VirtualMachineSizeTypesStandardF16', 'VirtualMachineSizeTypesStandardF1s', 'VirtualMachineSizeTypesStandardF2s', 'VirtualMachineSizeTypesStandardF4s', 'VirtualMachineSizeTypesStandardF8s', 'VirtualMachineSizeTypesStandardF16s', 'VirtualMachineSizeTypesStandardF2sV2', 'VirtualMachineSizeTypesStandardF4sV2', 'VirtualMachineSizeTypesStandardF8sV2', 'VirtualMachineSizeTypesStandardF16sV2', 'VirtualMachineSizeTypesStandardF32sV2', 'VirtualMachineSizeTypesStandardF64sV2', 'VirtualMachineSizeTypesStandardF72sV2', 'VirtualMachineSizeTypesStandardG1', 'VirtualMachineSizeTypesStandardG2', 'VirtualMachineSizeTypesStandardG3', 'VirtualMachineSizeTypesStandardG4', 'VirtualMachineSizeTypesStandardG5', 'VirtualMachineSizeTypesStandardGS1', 'VirtualMachineSizeTypesStandardGS2', 'VirtualMachineSizeTypesStandardGS3', 'VirtualMachineSizeTypesStandardGS4', 'VirtualMachineSizeTypesStandardGS5', 'VirtualMachineSizeTypesStandardGS48', 'VirtualMachineSizeTypesStandardGS44', 'VirtualMachineSizeTypesStandardGS516', 'VirtualMachineSizeTypesStandardGS58', 'VirtualMachineSizeTypesStandardH8', 'VirtualMachineSizeTypesStandardH16', 'VirtualMachineSizeTypesStandardH8m', 'VirtualMachineSizeTypesStandardH16m', 'VirtualMachineSizeTypesStandardH16r', 'VirtualMachineSizeTypesStandardH16mr', 'VirtualMachineSizeTypesStandardL4s', 'VirtualMachineSizeTypesStandardL8s', 'VirtualMachineSizeTypesStandardL16s', 'VirtualMachineSizeTypesStandardL32s', 'VirtualMachineSizeTypesStandardM64s', 'VirtualMachineSizeTypesStandardM64ms', 'VirtualMachineSizeTypesStandardM128s', 'VirtualMachineSizeTypesStandardM128ms', 'VirtualMachineSizeTypesStandardM6432ms', 'VirtualMachineSizeTypesStandardM6416ms', 'VirtualMachineSizeTypesStandardM12864ms', 'VirtualMachineSizeTypesStandardM12832ms', 'VirtualMachineSizeTypesStandardNC6', 'VirtualMachineSizeTypesStandardNC12', 'VirtualMachineSizeTypesStandardNC24', 'VirtualMachineSizeTypesStandardNC24r', 'VirtualMachineSizeTypesStandardNC6sV2', 'VirtualMachineSizeTypesStandardNC12sV2', 'VirtualMachineSizeTypesStandardNC24sV2', 'VirtualMachineSizeTypesStandardNC24rsV2', 'VirtualMachineSizeTypesStandardNC6sV3', 'VirtualMachineSizeTypesStandardNC12sV3', 'VirtualMachineSizeTypesStandardNC24sV3', 'VirtualMachineSizeTypesStandardNC24rsV3', 'VirtualMachineSizeTypesStandardND6s', 'VirtualMachineSizeTypesStandardND12s', 'VirtualMachineSizeTypesStandardND24s', 'VirtualMachineSizeTypesStandardND24rs', 'VirtualMachineSizeTypesStandardNV6', 'VirtualMachineSizeTypesStandardNV12', 'VirtualMachineSizeTypesStandardNV24' VMSize VirtualMachineSizeTypes `json:"vmSize,omitempty"` } @@ -1877,7 +3545,7 @@ type ImageDataDisk struct { Caching CachingTypes `json:"caching,omitempty"` // DiskSizeGB - Specifies the size of empty data disks in gigabytes. This element can be used to overwrite the name of the disk in a virtual machine image.

This value cannot be larger than 1023 GB DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` - // StorageAccountType - Specifies the storage account type for the managed disk. Possible values are: Standard_LRS, Premium_LRS, and StandardSSD_LRS. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS' + // StorageAccountType - Specifies the storage account type for the managed disk. NOTE: UltraSSD_LRS can only be used with data disks, it cannot be used with OS Disk. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS', 'StorageAccountTypesUltraSSDLRS' StorageAccountType StorageAccountTypes `json:"storageAccountType,omitempty"` } @@ -2007,7 +3675,7 @@ type ImageOSDisk struct { Caching CachingTypes `json:"caching,omitempty"` // DiskSizeGB - Specifies the size of empty data disks in gigabytes. This element can be used to overwrite the name of the disk in a virtual machine image.

This value cannot be larger than 1023 GB DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` - // StorageAccountType - Specifies the storage account type for the managed disk. Possible values are: Standard_LRS, Premium_LRS, and StandardSSD_LRS. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS' + // StorageAccountType - Specifies the storage account type for the managed disk. UltraSSD_LRS cannot be used with OS Disk. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS', 'StorageAccountTypesUltraSSDLRS' StorageAccountType StorageAccountTypes `json:"storageAccountType,omitempty"` } @@ -2021,6 +3689,16 @@ type ImageProperties struct { ProvisioningState *string `json:"provisioningState,omitempty"` } +// ImagePurchasePlan describes the gallery Image Definition purchase plan. This is used by marketplace images. +type ImagePurchasePlan struct { + // Name - The plan ID. + Name *string `json:"name,omitempty"` + // Publisher - The publisher ID. + Publisher *string `json:"publisher,omitempty"` + // Product - The product ID. + Product *string `json:"product,omitempty"` +} + // ImageReference specifies information about the image to use. You can specify information about platform images, // marketplace images, or virtual machine images. This element is required when you want to use a platform image, // marketplace image, or virtual machine image, but is not used in other creation operations. @@ -2242,6 +3920,8 @@ type LinuxConfiguration struct { DisablePasswordAuthentication *bool `json:"disablePasswordAuthentication,omitempty"` // SSH - Specifies the ssh key configuration for a Linux OS. SSH *SSHConfiguration `json:"ssh,omitempty"` + // ProvisionVMAgent - Indicates whether virtual machine agent should be provisioned on the virtual machine.

When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later. + ProvisionVMAgent *bool `json:"provisionVMAgent,omitempty"` } // ListUsagesResult the List Usages operation response. @@ -2463,9 +4143,15 @@ type MaintenanceRedeployStatus struct { LastOperationMessage *string `json:"lastOperationMessage,omitempty"` } +// ManagedArtifact the managed artifact. +type ManagedArtifact struct { + // ID - The managed artifact id. + ID *string `json:"id,omitempty"` +} + // ManagedDiskParameters the parameters of a managed disk. type ManagedDiskParameters struct { - // StorageAccountType - Specifies the storage account type for the managed disk. Possible values are: Standard_LRS, Premium_LRS, and StandardSSD_LRS. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS' + // StorageAccountType - Specifies the storage account type for the managed disk. NOTE: UltraSSD_LRS can only be used with data disks, it cannot be used with OS Disk. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS', 'StorageAccountTypesUltraSSDLRS' StorageAccountType StorageAccountTypes `json:"storageAccountType,omitempty"` // ID - Resource Id ID *string `json:"id,omitempty"` @@ -2638,6 +4324,8 @@ type OSDisk struct { Caching CachingTypes `json:"caching,omitempty"` // WriteAcceleratorEnabled - Specifies whether writeAccelerator should be enabled or disabled on the disk. WriteAcceleratorEnabled *bool `json:"writeAcceleratorEnabled,omitempty"` + // DiffDiskSettings - Specifies the differencing Disk Settings for the operating system disk used by the virtual machine. + DiffDiskSettings *DiffDiskSettings `json:"diffDiskSettings,omitempty"` // CreateOption - Specifies how the virtual machine should be created.

Possible values are:

**Attach** \u2013 This value is used when you are using a specialized disk to create the virtual machine.

**FromImage** \u2013 This value is used when you are using an image to create the virtual machine. If you are using a platform image, you also use the imageReference element described above. If you are using a marketplace image, you also use the plan element previously described. Possible values include: 'DiskCreateOptionTypesFromImage', 'DiskCreateOptionTypesEmpty', 'DiskCreateOptionTypesAttach' CreateOption DiskCreateOptionTypes `json:"createOption,omitempty"` // DiskSizeGB - Specifies the size of an empty data disk in gigabytes. This element can be used to overwrite the size of the disk in a virtual machine image.

This value cannot be larger than 1023 GB @@ -2668,6 +4356,8 @@ type OSProfile struct { LinuxConfiguration *LinuxConfiguration `json:"linuxConfiguration,omitempty"` // Secrets - Specifies set of certificates that should be installed onto the virtual machine. Secrets *[]VaultSecretGroup `json:"secrets,omitempty"` + // AllowExtensionOperations - Specifies whether extension operations should be allowed on the virtual machine.

This may only be set to False when no extensions are present on the virtual machine. + AllowExtensionOperations *bool `json:"allowExtensionOperations,omitempty"` } // Plan specifies information about the marketplace image used to create the virtual machine. This element is only @@ -2695,6 +4385,13 @@ type PurchasePlan struct { Product *string `json:"product,omitempty"` } +// RecommendedMachineConfiguration the properties describe the recommended machine configuration for this Image +// Definition. These properties are updateable. +type RecommendedMachineConfiguration struct { + VCPUs *ResourceRange `json:"vCPUs,omitempty"` + Memory *ResourceRange `json:"memory,omitempty"` +} + // RecoveryWalkResponse response after calling a manual recovery walk type RecoveryWalkResponse struct { autorest.Response `json:"-"` @@ -2704,6 +4401,26 @@ type RecoveryWalkResponse struct { NextPlatformUpdateDomain *int32 `json:"nextPlatformUpdateDomain,omitempty"` } +// RegionalReplicationStatus this is the regional replication status. +type RegionalReplicationStatus struct { + // Region - The region to which the gallery Image Version is being replicated to. + Region *string `json:"region,omitempty"` + // State - This is the regional replication state. Possible values include: 'ReplicationStateUnknown', 'ReplicationStateReplicating', 'ReplicationStateCompleted', 'ReplicationStateFailed' + State ReplicationState `json:"state,omitempty"` + // Details - The details of the replication status. + Details *string `json:"details,omitempty"` + // Progress - It indicates progress of the replication job. + Progress *int32 `json:"progress,omitempty"` +} + +// ReplicationStatus this is the replication status of the gallery Image Version. +type ReplicationStatus struct { + // AggregatedState - This is the aggregated replication status based on all the regional replication status flags. Possible values include: 'Unknown', 'InProgress', 'Completed', 'Failed' + AggregatedState AggregatedReplicationState `json:"aggregatedState,omitempty"` + // Summary - This is a summary of replication status for each region. + Summary *[]RegionalReplicationStatus `json:"summary,omitempty"` +} + // RequestRateByIntervalInput api request input for LogAnalytics getRequestRateByInterval Api. type RequestRateByIntervalInput struct { // IntervalLength - Interval value in minutes used to create LogAnalytics call rate logs. Possible values include: 'ThreeMins', 'FiveMins', 'ThirtyMins', 'SixtyMins' @@ -2757,6 +4474,204 @@ func (r Resource) MarshalJSON() ([]byte, error) { return json.Marshal(objectMap) } +// ResourceRange describes the resource range. +type ResourceRange struct { + // Min - The minimum number of the resource. + Min *int32 `json:"min,omitempty"` + // Max - The maximum number of the resource. + Max *int32 `json:"max,omitempty"` +} + +// ResourceSku describes an available Compute SKU. +type ResourceSku struct { + // ResourceType - The type of resource the SKU applies to. + ResourceType *string `json:"resourceType,omitempty"` + // Name - The name of SKU. + Name *string `json:"name,omitempty"` + // Tier - Specifies the tier of virtual machines in a scale set.

Possible Values:

**Standard**

**Basic** + Tier *string `json:"tier,omitempty"` + // Size - The Size of the SKU. + Size *string `json:"size,omitempty"` + // Family - The Family of this particular SKU. + Family *string `json:"family,omitempty"` + // Kind - The Kind of resources that are supported in this SKU. + Kind *string `json:"kind,omitempty"` + // Capacity - Specifies the number of virtual machines in the scale set. + Capacity *ResourceSkuCapacity `json:"capacity,omitempty"` + // Locations - The set of locations that the SKU is available. + Locations *[]string `json:"locations,omitempty"` + // LocationInfo - A list of locations and availability zones in those locations where the SKU is available. + LocationInfo *[]ResourceSkuLocationInfo `json:"locationInfo,omitempty"` + // APIVersions - The api versions that support this SKU. + APIVersions *[]string `json:"apiVersions,omitempty"` + // Costs - Metadata for retrieving price info. + Costs *[]ResourceSkuCosts `json:"costs,omitempty"` + // Capabilities - A name value pair to describe the capability. + Capabilities *[]ResourceSkuCapabilities `json:"capabilities,omitempty"` + // Restrictions - The restrictions because of which SKU cannot be used. This is empty if there are no restrictions. + Restrictions *[]ResourceSkuRestrictions `json:"restrictions,omitempty"` +} + +// ResourceSkuCapabilities describes The SKU capabilites object. +type ResourceSkuCapabilities struct { + // Name - An invariant to describe the feature. + Name *string `json:"name,omitempty"` + // Value - An invariant if the feature is measured by quantity. + Value *string `json:"value,omitempty"` +} + +// ResourceSkuCapacity describes scaling information of a SKU. +type ResourceSkuCapacity struct { + // Minimum - The minimum capacity. + Minimum *int64 `json:"minimum,omitempty"` + // Maximum - The maximum capacity that can be set. + Maximum *int64 `json:"maximum,omitempty"` + // Default - The default capacity. + Default *int64 `json:"default,omitempty"` + // ScaleType - The scale type applicable to the sku. Possible values include: 'ResourceSkuCapacityScaleTypeAutomatic', 'ResourceSkuCapacityScaleTypeManual', 'ResourceSkuCapacityScaleTypeNone' + ScaleType ResourceSkuCapacityScaleType `json:"scaleType,omitempty"` +} + +// ResourceSkuCosts describes metadata for retrieving price info. +type ResourceSkuCosts struct { + // MeterID - Used for querying price from commerce. + MeterID *string `json:"meterID,omitempty"` + // Quantity - The multiplier is needed to extend the base metered cost. + Quantity *int64 `json:"quantity,omitempty"` + // ExtendedUnit - An invariant to show the extended unit. + ExtendedUnit *string `json:"extendedUnit,omitempty"` +} + +// ResourceSkuLocationInfo ... +type ResourceSkuLocationInfo struct { + // Location - Location of the SKU + Location *string `json:"location,omitempty"` + // Zones - List of availability zones where the SKU is supported. + Zones *[]string `json:"zones,omitempty"` +} + +// ResourceSkuRestrictionInfo ... +type ResourceSkuRestrictionInfo struct { + // Locations - Locations where the SKU is restricted + Locations *[]string `json:"locations,omitempty"` + // Zones - List of availability zones where the SKU is restricted. + Zones *[]string `json:"zones,omitempty"` +} + +// ResourceSkuRestrictions describes scaling information of a SKU. +type ResourceSkuRestrictions struct { + // Type - The type of restrictions. Possible values include: 'Location', 'Zone' + Type ResourceSkuRestrictionsType `json:"type,omitempty"` + // Values - The value of restrictions. If the restriction type is set to location. This would be different locations where the SKU is restricted. + Values *[]string `json:"values,omitempty"` + // RestrictionInfo - The information about the restriction where the SKU cannot be used. + RestrictionInfo *ResourceSkuRestrictionInfo `json:"restrictionInfo,omitempty"` + // ReasonCode - The reason for restriction. Possible values include: 'QuotaID', 'NotAvailableForSubscription' + ReasonCode ResourceSkuRestrictionsReasonCode `json:"reasonCode,omitempty"` +} + +// ResourceSkusResult the Compute List Skus operation response. +type ResourceSkusResult struct { + autorest.Response `json:"-"` + // Value - The list of skus available for the subscription. + Value *[]ResourceSku `json:"value,omitempty"` + // NextLink - The uri to fetch the next page of Compute Skus. Call ListNext() with this to fetch the next page of VMSS Skus. + NextLink *string `json:"nextLink,omitempty"` +} + +// ResourceSkusResultIterator provides access to a complete listing of ResourceSku values. +type ResourceSkusResultIterator struct { + i int + page ResourceSkusResultPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *ResourceSkusResultIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter ResourceSkusResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter ResourceSkusResultIterator) Response() ResourceSkusResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter ResourceSkusResultIterator) Value() ResourceSku { + if !iter.page.NotDone() { + return ResourceSku{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (rsr ResourceSkusResult) IsEmpty() bool { + return rsr.Value == nil || len(*rsr.Value) == 0 +} + +// resourceSkusResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (rsr ResourceSkusResult) resourceSkusResultPreparer() (*http.Request, error) { + if rsr.NextLink == nil || len(to.String(rsr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(rsr.NextLink))) +} + +// ResourceSkusResultPage contains a page of ResourceSku values. +type ResourceSkusResultPage struct { + fn func(ResourceSkusResult) (ResourceSkusResult, error) + rsr ResourceSkusResult +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *ResourceSkusResultPage) Next() error { + next, err := page.fn(page.rsr) + if err != nil { + return err + } + page.rsr = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page ResourceSkusResultPage) NotDone() bool { + return !page.rsr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page ResourceSkusResultPage) Response() ResourceSkusResult { + return page.rsr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page ResourceSkusResultPage) Values() []ResourceSku { + if page.rsr.IsEmpty() { + return nil + } + return *page.rsr.Value +} + // RollbackStatusInfo information about rollback on failed VM instances after a OS Upgrade operation. type RollbackStatusInfo struct { // SuccessfullyRolledbackInstanceCount - The number of instances which have been successfully rolled back. @@ -2793,7 +4708,7 @@ type RollingUpgradeProgressInfo struct { // RollingUpgradeRunningStatus information about the current running state of the overall upgrade. type RollingUpgradeRunningStatus struct { - // Code - Code indicating the current status of the upgrade. Possible values include: 'RollingForward', 'Cancelled', 'Completed', 'Faulted' + // Code - Code indicating the current status of the upgrade. Possible values include: 'RollingUpgradeStatusCodeRollingForward', 'RollingUpgradeStatusCodeCancelled', 'RollingUpgradeStatusCodeCompleted', 'RollingUpgradeStatusCodeFaulted' Code RollingUpgradeStatusCode `json:"code,omitempty"` // StartTime - Start time of the upgrade. StartTime *date.Time `json:"startTime,omitempty"` @@ -3110,9 +5025,9 @@ type Sku struct { type Snapshot struct { autorest.Response `json:"-"` // ManagedBy - Unused. Always Null. - ManagedBy *string `json:"managedBy,omitempty"` - Sku *SnapshotSku `json:"sku,omitempty"` - *DiskProperties `json:"properties,omitempty"` + ManagedBy *string `json:"managedBy,omitempty"` + Sku *SnapshotSku `json:"sku,omitempty"` + *SnapshotProperties `json:"properties,omitempty"` // ID - Resource Id ID *string `json:"id,omitempty"` // Name - Resource name @@ -3134,8 +5049,8 @@ func (s Snapshot) MarshalJSON() ([]byte, error) { if s.Sku != nil { objectMap["sku"] = s.Sku } - if s.DiskProperties != nil { - objectMap["properties"] = s.DiskProperties + if s.SnapshotProperties != nil { + objectMap["properties"] = s.SnapshotProperties } if s.ID != nil { objectMap["id"] = s.ID @@ -3184,12 +5099,12 @@ func (s *Snapshot) UnmarshalJSON(body []byte) error { } case "properties": if v != nil { - var diskProperties DiskProperties - err = json.Unmarshal(*v, &diskProperties) + var snapshotProperties SnapshotProperties + err = json.Unmarshal(*v, &snapshotProperties) if err != nil { return err } - s.DiskProperties = &diskProperties + s.SnapshotProperties = &snapshotProperties } case "id": if v != nil { @@ -3344,6 +5259,22 @@ func (page SnapshotListPage) Values() []Snapshot { return *page.sl.Value } +// SnapshotProperties snapshot resource properties. +type SnapshotProperties struct { + // TimeCreated - The time when the disk was created. + TimeCreated *date.Time `json:"timeCreated,omitempty"` + // OsType - The Operating System type. Possible values include: 'Windows', 'Linux' + OsType OperatingSystemTypes `json:"osType,omitempty"` + // CreationData - Disk source information. CreationData information cannot be changed after the disk has been created. + CreationData *CreationData `json:"creationData,omitempty"` + // DiskSizeGB - If creationData.createOption is Empty, this field is mandatory and it indicates the size of the VHD to create. If this field is present for updates or creation with other options, it indicates a resize. Resizes are only allowed if the disk is not attached to a running VM, and can only increase the disk's size. + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + // EncryptionSettings - Encryption settings for disk or snapshot + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` + // ProvisioningState - The disk provisioning state. + ProvisioningState *string `json:"provisioningState,omitempty"` +} + // SnapshotsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running // operation. type SnapshotsCreateOrUpdateFuture struct { @@ -3425,7 +5356,7 @@ func (future *SnapshotsGrantAccessFuture) Result(client SnapshotsClient) (au Acc // SnapshotSku the snapshots sku name. Can be Standard_LRS, Premium_LRS, or Standard_ZRS. type SnapshotSku struct { - // Name - The sku name. Possible values include: 'StandardLRS', 'PremiumLRS', 'StandardZRS' + // Name - The sku name. Possible values include: 'SnapshotStorageAccountTypesStandardLRS', 'SnapshotStorageAccountTypesPremiumLRS', 'SnapshotStorageAccountTypesStandardZRS' Name SnapshotStorageAccountTypes `json:"name,omitempty"` // Tier - The sku tier. Tier *string `json:"tier,omitempty"` @@ -3484,7 +5415,7 @@ func (future *SnapshotsUpdateFuture) Result(client SnapshotsClient) (s Snapshot, // SnapshotUpdate snapshot update resource. type SnapshotUpdate struct { - *DiskUpdateProperties `json:"properties,omitempty"` + *SnapshotUpdateProperties `json:"properties,omitempty"` // Tags - Resource tags Tags map[string]*string `json:"tags"` Sku *SnapshotSku `json:"sku,omitempty"` @@ -3493,8 +5424,8 @@ type SnapshotUpdate struct { // MarshalJSON is the custom marshaler for SnapshotUpdate. func (su SnapshotUpdate) MarshalJSON() ([]byte, error) { objectMap := make(map[string]interface{}) - if su.DiskUpdateProperties != nil { - objectMap["properties"] = su.DiskUpdateProperties + if su.SnapshotUpdateProperties != nil { + objectMap["properties"] = su.SnapshotUpdateProperties } if su.Tags != nil { objectMap["tags"] = su.Tags @@ -3516,12 +5447,12 @@ func (su *SnapshotUpdate) UnmarshalJSON(body []byte) error { switch k { case "properties": if v != nil { - var diskUpdateProperties DiskUpdateProperties - err = json.Unmarshal(*v, &diskUpdateProperties) + var snapshotUpdateProperties SnapshotUpdateProperties + err = json.Unmarshal(*v, &snapshotUpdateProperties) if err != nil { return err } - su.DiskUpdateProperties = &diskUpdateProperties + su.SnapshotUpdateProperties = &snapshotUpdateProperties } case "tags": if v != nil { @@ -3547,6 +5478,16 @@ func (su *SnapshotUpdate) UnmarshalJSON(body []byte) error { return nil } +// SnapshotUpdateProperties snapshot resource update properties. +type SnapshotUpdateProperties struct { + // OsType - the Operating System type. Possible values include: 'Windows', 'Linux' + OsType OperatingSystemTypes `json:"osType,omitempty"` + // DiskSizeGB - If creationData.createOption is Empty, this field is mandatory and it indicates the size of the VHD to create. If this field is present for updates or creation with other options, it indicates a resize. Resizes are only allowed if the disk is not attached to a running VM, and can only increase the disk's size. + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + // EncryptionSettings - Encryption settings for disk or snapshot + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` +} + // SourceVault the vault id is an Azure Resource Manager Resoure id in the form // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName} type SourceVault struct { @@ -3591,6 +5532,14 @@ type SubResourceReadOnly struct { ID *string `json:"id,omitempty"` } +// TargetRegion describes the target region information. +type TargetRegion struct { + // Name - The name of the region. + Name *string `json:"name,omitempty"` + // RegionalReplicaCount - The number of replicas of the Image Version to be created per region. This property is updateable. + RegionalReplicaCount *int32 `json:"regionalReplicaCount,omitempty"` +} + // ThrottledRequestsInput api request input for LogAnalytics getThrottledRequests Api. type ThrottledRequestsInput struct { // BlobContainerSasURI - SAS Uri of the logging blob container to which LogAnalytics Api writes output logs to. @@ -3640,7 +5589,7 @@ type UpgradeOperationHistoricalStatusInfoProperties struct { Progress *RollingUpgradeProgressInfo `json:"progress,omitempty"` // Error - Error Details for this upgrade if there are any. Error *APIError `json:"error,omitempty"` - // StartedBy - Invoker of the Upgrade Operation. Possible values include: 'Unknown', 'User', 'Platform' + // StartedBy - Invoker of the Upgrade Operation. Possible values include: 'UpgradeOperationInvokerUnknown', 'UpgradeOperationInvokerUser', 'UpgradeOperationInvokerPlatform' StartedBy UpgradeOperationInvoker `json:"startedBy,omitempty"` // TargetImageReference - Image Reference details TargetImageReference *ImageReference `json:"targetImageReference,omitempty"` @@ -3664,10 +5613,8 @@ type UpgradePolicy struct { Mode UpgradeMode `json:"mode,omitempty"` // RollingUpgradePolicy - The configuration parameters used while performing a rolling upgrade. RollingUpgradePolicy *RollingUpgradePolicy `json:"rollingUpgradePolicy,omitempty"` - // AutomaticOSUpgrade - Whether OS upgrades should automatically be applied to scale set instances in a rolling fashion when a newer version of the image becomes available. - AutomaticOSUpgrade *bool `json:"automaticOSUpgrade,omitempty"` - // AutoOSUpgradePolicy - Configuration parameters used for performing automatic OS Upgrade. - AutoOSUpgradePolicy *AutoOSUpgradePolicy `json:"autoOSUpgradePolicy,omitempty"` + // AutomaticOSUpgradePolicy - Configuration parameters used for performing automatic OS Upgrade. + AutomaticOSUpgradePolicy *AutomaticOSUpgradePolicy `json:"automaticOSUpgradePolicy,omitempty"` } // Usage describes Compute Resource Usage. @@ -4363,8 +6310,34 @@ type VirtualMachineIdentity struct { TenantID *string `json:"tenantId,omitempty"` // Type - The type of identity used for the virtual machine. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the virtual machine. Possible values include: 'ResourceIdentityTypeSystemAssigned', 'ResourceIdentityTypeUserAssigned', 'ResourceIdentityTypeSystemAssignedUserAssigned', 'ResourceIdentityTypeNone' Type ResourceIdentityType `json:"type,omitempty"` - // IdentityIds - The list of user identities associated with the Virtual Machine. The user identity references will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/identities/{identityName}'. - IdentityIds *[]string `json:"identityIds,omitempty"` + // UserAssignedIdentities - The list of user identities associated with the Virtual Machine. The user identity dictionary key references will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'. + UserAssignedIdentities map[string]*VirtualMachineIdentityUserAssignedIdentitiesValue `json:"userAssignedIdentities"` +} + +// MarshalJSON is the custom marshaler for VirtualMachineIdentity. +func (vmi VirtualMachineIdentity) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if vmi.PrincipalID != nil { + objectMap["principalId"] = vmi.PrincipalID + } + if vmi.TenantID != nil { + objectMap["tenantId"] = vmi.TenantID + } + if vmi.Type != "" { + objectMap["type"] = vmi.Type + } + if vmi.UserAssignedIdentities != nil { + objectMap["userAssignedIdentities"] = vmi.UserAssignedIdentities + } + return json.Marshal(objectMap) +} + +// VirtualMachineIdentityUserAssignedIdentitiesValue ... +type VirtualMachineIdentityUserAssignedIdentitiesValue struct { + // PrincipalID - The principal id of user assigned identity. + PrincipalID *string `json:"principalId,omitempty"` + // ClientID - The client id of user assigned identity. + ClientID *string `json:"clientId,omitempty"` } // VirtualMachineImage describes a Virtual Machine Image. @@ -4636,6 +6609,8 @@ type VirtualMachineProperties struct { HardwareProfile *HardwareProfile `json:"hardwareProfile,omitempty"` // StorageProfile - Specifies the storage settings for the virtual machine disks. StorageProfile *StorageProfile `json:"storageProfile,omitempty"` + // AdditionalCapabilities - Specifies additional capabilities enabled or disabled on the virtual machine. + AdditionalCapabilities *AdditionalCapabilities `json:"additionalCapabilities,omitempty"` // OsProfile - Specifies the operating system settings for the virtual machine. OsProfile *OSProfile `json:"osProfile,omitempty"` // NetworkProfile - Specifies the network interfaces of the virtual machine. @@ -5093,8 +7068,34 @@ type VirtualMachineScaleSetIdentity struct { TenantID *string `json:"tenantId,omitempty"` // Type - The type of identity used for the virtual machine scale set. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the virtual machine scale set. Possible values include: 'ResourceIdentityTypeSystemAssigned', 'ResourceIdentityTypeUserAssigned', 'ResourceIdentityTypeSystemAssignedUserAssigned', 'ResourceIdentityTypeNone' Type ResourceIdentityType `json:"type,omitempty"` - // IdentityIds - The list of user identities associated with the virtual machine scale set. The user identity references will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/identities/{identityName}'. - IdentityIds *[]string `json:"identityIds,omitempty"` + // UserAssignedIdentities - The list of user identities associated with the virtual machine scale set. The user identity dictionary key references will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'. + UserAssignedIdentities map[string]*VirtualMachineScaleSetIdentityUserAssignedIdentitiesValue `json:"userAssignedIdentities"` +} + +// MarshalJSON is the custom marshaler for VirtualMachineScaleSetIdentity. +func (vmssi VirtualMachineScaleSetIdentity) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if vmssi.PrincipalID != nil { + objectMap["principalId"] = vmssi.PrincipalID + } + if vmssi.TenantID != nil { + objectMap["tenantId"] = vmssi.TenantID + } + if vmssi.Type != "" { + objectMap["type"] = vmssi.Type + } + if vmssi.UserAssignedIdentities != nil { + objectMap["userAssignedIdentities"] = vmssi.UserAssignedIdentities + } + return json.Marshal(objectMap) +} + +// VirtualMachineScaleSetIdentityUserAssignedIdentitiesValue ... +type VirtualMachineScaleSetIdentityUserAssignedIdentitiesValue struct { + // PrincipalID - The principal id of user assigned identity. + PrincipalID *string `json:"principalId,omitempty"` + // ClientID - The client id of user assigned identity. + ClientID *string `json:"clientId,omitempty"` } // VirtualMachineScaleSetInstanceView the instance view of a virtual machine scale set. @@ -5194,6 +7195,8 @@ type VirtualMachineScaleSetIPConfigurationProperties struct { PrivateIPAddressVersion IPVersion `json:"privateIPAddressVersion,omitempty"` // ApplicationGatewayBackendAddressPools - Specifies an array of references to backend address pools of application gateways. A scale set can reference backend address pools of multiple application gateways. Multiple scale sets cannot use the same application gateway. ApplicationGatewayBackendAddressPools *[]SubResource `json:"applicationGatewayBackendAddressPools,omitempty"` + // ApplicationSecurityGroups - Specifies an array of references to application security group. + ApplicationSecurityGroups *[]SubResource `json:"applicationSecurityGroups,omitempty"` // LoadBalancerBackendAddressPools - Specifies an array of references to backend address pools of load balancers. A scale set can reference backend address pools of one public and one internal load balancer. Multiple scale sets cannot use the same load balancer. LoadBalancerBackendAddressPools *[]SubResource `json:"loadBalancerBackendAddressPools,omitempty"` // LoadBalancerInboundNatPools - Specifies an array of references to inbound Nat pools of the load balancers. A scale set can reference inbound nat pools of one public and one internal load balancer. Multiple scale sets cannot use the same load balancer @@ -5622,7 +7625,7 @@ func (page VirtualMachineScaleSetListWithLinkResultPage) Values() []VirtualMachi // VirtualMachineScaleSetManagedDiskParameters describes the parameters of a ScaleSet managed disk. type VirtualMachineScaleSetManagedDiskParameters struct { - // StorageAccountType - Specifies the storage account type for the managed disk. Possible values are: Standard_LRS, Premium_LRS, and StandardSSD_LRS. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS' + // StorageAccountType - Specifies the storage account type for the managed disk. NOTE: UltraSSD_LRS can only be used with data disks, it cannot be used with OS Disk. Possible values include: 'StorageAccountTypesStandardLRS', 'StorageAccountTypesPremiumLRS', 'StorageAccountTypesStandardSSDLRS', 'StorageAccountTypesUltraSSDLRS' StorageAccountType StorageAccountTypes `json:"storageAccountType,omitempty"` } @@ -5735,6 +7738,8 @@ type VirtualMachineScaleSetOSDisk struct { WriteAcceleratorEnabled *bool `json:"writeAcceleratorEnabled,omitempty"` // CreateOption - Specifies how the virtual machines in the scale set should be created.

The only allowed value is: **FromImage** \u2013 This value is used when you are using an image to create the virtual machine. If you are using a platform image, you also use the imageReference element described above. If you are using a marketplace image, you also use the plan element previously described. Possible values include: 'DiskCreateOptionTypesFromImage', 'DiskCreateOptionTypesEmpty', 'DiskCreateOptionTypesAttach' CreateOption DiskCreateOptionTypes `json:"createOption,omitempty"` + // DiffDiskSettings - Specifies the differencing Disk Settings for the operating system disk used by the virtual machine scale set. + DiffDiskSettings *DiffDiskSettings `json:"diffDiskSettings,omitempty"` // DiskSizeGB - Specifies the size of the operating system disk in gigabytes. This element can be used to overwrite the size of the disk in a virtual machine image.

This value cannot be larger than 1023 GB DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` // OsType - This property allows you to specify the type of the OS that is included in the disk if creating a VM from user-image or a specialized VHD.

Possible values are:

**Windows**

**Linux**. Possible values include: 'Windows', 'Linux' @@ -5854,6 +7859,8 @@ type VirtualMachineScaleSetPublicIPAddressConfigurationProperties struct { DNSSettings *VirtualMachineScaleSetPublicIPAddressConfigurationDNSSettings `json:"dnsSettings,omitempty"` // IPTags - The list of IP tags associated with the public IP address. IPTags *[]VirtualMachineScaleSetIPTag `json:"ipTags,omitempty"` + // PublicIPPrefix - The PublicIPPrefix from which to allocate publicIP addresses. + PublicIPPrefix *SubResource `json:"publicIPPrefix,omitempty"` } // VirtualMachineScaleSetRollingUpgradesCancelFuture an abstraction for monitoring and retrieving the results of a @@ -5879,6 +7886,29 @@ func (future *VirtualMachineScaleSetRollingUpgradesCancelFuture) Result(client V return } +// VirtualMachineScaleSetRollingUpgradesStartExtensionUpgradeFuture an abstraction for monitoring and retrieving +// the results of a long-running operation. +type VirtualMachineScaleSetRollingUpgradesStartExtensionUpgradeFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *VirtualMachineScaleSetRollingUpgradesStartExtensionUpgradeFuture) Result(client VirtualMachineScaleSetRollingUpgradesClient) (ar autorest.Response, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesStartExtensionUpgradeFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetRollingUpgradesStartExtensionUpgradeFuture") + return + } + ar.Response = future.Response() + return +} + // VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture an abstraction for monitoring and retrieving the // results of a long-running operation. type VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture struct { @@ -6419,6 +8449,8 @@ type VirtualMachineScaleSetUpdateIPConfigurationProperties struct { PrivateIPAddressVersion IPVersion `json:"privateIPAddressVersion,omitempty"` // ApplicationGatewayBackendAddressPools - The application gateway backend address pools. ApplicationGatewayBackendAddressPools *[]SubResource `json:"applicationGatewayBackendAddressPools,omitempty"` + // ApplicationSecurityGroups - Specifies an array of references to application security group. + ApplicationSecurityGroups *[]SubResource `json:"applicationSecurityGroups,omitempty"` // LoadBalancerBackendAddressPools - The load balancer backend address pools. LoadBalancerBackendAddressPools *[]SubResource `json:"loadBalancerBackendAddressPools,omitempty"` // LoadBalancerInboundNatPools - The load balancer inbound nat pools. @@ -6981,6 +9013,8 @@ type VirtualMachineScaleSetVMProfile struct { OsProfile *VirtualMachineScaleSetOSProfile `json:"osProfile,omitempty"` // StorageProfile - Specifies the storage settings for the virtual machine disks. StorageProfile *VirtualMachineScaleSetStorageProfile `json:"storageProfile,omitempty"` + // AdditionalCapabilities - Specifies additional capabilities enabled or disabled on the virtual machine in the scale set. For instance: whether the virtual machine has the capability to support attaching managed data disks with UltraSSD_LRS storage account type. + AdditionalCapabilities *AdditionalCapabilities `json:"additionalCapabilities,omitempty"` // NetworkProfile - Specifies properties of the network interfaces of the virtual machines in the scale set. NetworkProfile *VirtualMachineScaleSetNetworkProfile `json:"networkProfile,omitempty"` // DiagnosticsProfile - Specifies the boot diagnostic settings state.

Minimum api-version: 2015-06-15. @@ -7007,6 +9041,8 @@ type VirtualMachineScaleSetVMProperties struct { HardwareProfile *HardwareProfile `json:"hardwareProfile,omitempty"` // StorageProfile - Specifies the storage settings for the virtual machine disks. StorageProfile *StorageProfile `json:"storageProfile,omitempty"` + // AdditionalCapabilities - Specifies additional capabilities enabled or disabled on the virtual machine in the scale set. For instance: whether the virtual machine has the capability to support attaching managed data disks with UltraSSD_LRS storage account type. + AdditionalCapabilities *AdditionalCapabilities `json:"additionalCapabilities,omitempty"` // OsProfile - Specifies the operating system settings for the virtual machine. OsProfile *OSProfile `json:"osProfile,omitempty"` // NetworkProfile - Specifies the network interfaces of the virtual machine. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/operations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/operations.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/operations.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/operations.go index 14c892fe10acd..e8fb3415b48b0 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/operations.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/operations.go @@ -64,7 +64,7 @@ func (client OperationsClient) List(ctx context.Context) (result OperationListRe // ListPreparer prepares the List request. func (client OperationsClient) ListPreparer(ctx context.Context) (*http.Request, error) { - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/resourceskus.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/resourceskus.go new file mode 100644 index 0000000000000..de32a3df699dd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/resourceskus.go @@ -0,0 +1,130 @@ +package compute + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// ResourceSkusClient is the compute Client +type ResourceSkusClient struct { + BaseClient +} + +// NewResourceSkusClient creates an instance of the ResourceSkusClient client. +func NewResourceSkusClient(subscriptionID string) ResourceSkusClient { + return NewResourceSkusClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewResourceSkusClientWithBaseURI creates an instance of the ResourceSkusClient client. +func NewResourceSkusClientWithBaseURI(baseURI string, subscriptionID string) ResourceSkusClient { + return ResourceSkusClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// List gets the list of Microsoft.Compute SKUs available for your Subscription. +func (client ResourceSkusClient) List(ctx context.Context) (result ResourceSkusResultPage, err error) { + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ResourceSkusClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.rsr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.ResourceSkusClient", "List", resp, "Failure sending request") + return + } + + result.rsr, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ResourceSkusClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ResourceSkusClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/skus", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ResourceSkusClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ResourceSkusClient) ListResponder(resp *http.Response) (result ResourceSkusResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client ResourceSkusClient) listNextResults(lastResults ResourceSkusResult) (result ResourceSkusResult, err error) { + req, err := lastResults.resourceSkusResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.ResourceSkusClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.ResourceSkusClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.ResourceSkusClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client ResourceSkusClient) ListComplete(ctx context.Context) (result ResourceSkusResultIterator, err error) { + result.page, err = client.List(ctx) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/snapshots.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/snapshots.go similarity index 93% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/snapshots.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/snapshots.go index b87359354942e..89e57104c4f36 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/snapshots.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/snapshots.go @@ -49,19 +49,19 @@ func NewSnapshotsClientWithBaseURI(baseURI string, subscriptionID string) Snapsh func (client SnapshotsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, snapshotName string, snapshot Snapshot) (result SnapshotsCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: snapshot, - Constraints: []validation.Constraint{{Target: "snapshot.DiskProperties", Name: validation.Null, Rule: false, - Chain: []validation.Constraint{{Target: "snapshot.DiskProperties.CreationData", Name: validation.Null, Rule: true, - Chain: []validation.Constraint{{Target: "snapshot.DiskProperties.CreationData.ImageReference", Name: validation.Null, Rule: false, - Chain: []validation.Constraint{{Target: "snapshot.DiskProperties.CreationData.ImageReference.ID", Name: validation.Null, Rule: true, Chain: nil}}}, + Constraints: []validation.Constraint{{Target: "snapshot.SnapshotProperties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.SnapshotProperties.CreationData", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "snapshot.SnapshotProperties.CreationData.ImageReference", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.SnapshotProperties.CreationData.ImageReference.ID", Name: validation.Null, Rule: true, Chain: nil}}}, }}, - {Target: "snapshot.DiskProperties.EncryptionSettings", Name: validation.Null, Rule: false, - Chain: []validation.Constraint{{Target: "snapshot.DiskProperties.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, - Chain: []validation.Constraint{{Target: "snapshot.DiskProperties.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, - {Target: "snapshot.DiskProperties.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.SnapshotProperties.EncryptionSettings", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.SnapshotProperties.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.SnapshotProperties.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.SnapshotProperties.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, }}, - {Target: "snapshot.DiskProperties.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, - Chain: []validation.Constraint{{Target: "snapshot.DiskProperties.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, - {Target: "snapshot.DiskProperties.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.SnapshotProperties.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.SnapshotProperties.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.SnapshotProperties.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, }}, }}, }}}}}); err != nil { @@ -91,7 +91,7 @@ func (client SnapshotsClient) CreateOrUpdatePreparer(ctx context.Context, resour "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -165,7 +165,7 @@ func (client SnapshotsClient) DeletePreparer(ctx context.Context, resourceGroupN "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -242,7 +242,7 @@ func (client SnapshotsClient) GetPreparer(ctx context.Context, resourceGroupName "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -311,7 +311,7 @@ func (client SnapshotsClient) GrantAccessPreparer(ctx context.Context, resourceG "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -386,7 +386,7 @@ func (client SnapshotsClient) ListPreparer(ctx context.Context) (*http.Request, "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -479,7 +479,7 @@ func (client SnapshotsClient) ListByResourceGroupPreparer(ctx context.Context, r "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -568,7 +568,7 @@ func (client SnapshotsClient) RevokeAccessPreparer(ctx context.Context, resource "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -640,7 +640,7 @@ func (client SnapshotsClient) UpdatePreparer(ctx context.Context, resourceGroupN "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-06-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/usage.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/usage.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/usage.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/usage.go index fd007d01ea342..6e433603f8985 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/usage.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/usage.go @@ -80,7 +80,7 @@ func (client UsageClient) ListPreparer(ctx context.Context, location string) (*h "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/version.go similarity index 94% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/version.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/version.go index 87d03ecf94907..e28392b5b8e4b 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/version.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/version.go @@ -21,7 +21,7 @@ import "github.com/Azure/azure-sdk-for-go/version" // UserAgent returns the UserAgent string to use when sending http.Requests. func UserAgent() string { - return "Azure-SDK-For-Go/" + version.Number + " compute/2018-04-01" + return "Azure-SDK-For-Go/" + version.Number + " compute/2018-10-01" } // Version returns the semantic version (see http://semver.org) of the client. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensionimages.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineextensionimages.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensionimages.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineextensionimages.go index 45714d55e79cb..636160044851d 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensionimages.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineextensionimages.go @@ -75,7 +75,7 @@ func (client VirtualMachineExtensionImagesClient) GetPreparer(ctx context.Contex "version": autorest.Encode("path", version), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -141,7 +141,7 @@ func (client VirtualMachineExtensionImagesClient) ListTypesPreparer(ctx context. "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -209,7 +209,7 @@ func (client VirtualMachineExtensionImagesClient) ListVersionsPreparer(ctx conte "type": autorest.Encode("path", typeParameter), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineextensions.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensions.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineextensions.go index 06673a73d63ed..6bfd80ac3a17b 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensions.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineextensions.go @@ -70,7 +70,7 @@ func (client VirtualMachineExtensionsClient) CreateOrUpdatePreparer(ctx context. "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -145,7 +145,7 @@ func (client VirtualMachineExtensionsClient) DeletePreparer(ctx context.Context, "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -224,7 +224,7 @@ func (client VirtualMachineExtensionsClient) GetPreparer(ctx context.Context, re "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -295,7 +295,7 @@ func (client VirtualMachineExtensionsClient) ListPreparer(ctx context.Context, r "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -362,7 +362,7 @@ func (client VirtualMachineExtensionsClient) UpdatePreparer(ctx context.Context, "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineimages.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineimages.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineimages.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineimages.go index aeaa39b049185..23dab447a7500 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineimages.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineimages.go @@ -79,7 +79,7 @@ func (client VirtualMachineImagesClient) GetPreparer(ctx context.Context, locati "version": autorest.Encode("path", version), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -151,7 +151,7 @@ func (client VirtualMachineImagesClient) ListPreparer(ctx context.Context, locat "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -227,7 +227,7 @@ func (client VirtualMachineImagesClient) ListOffersPreparer(ctx context.Context, "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -292,7 +292,7 @@ func (client VirtualMachineImagesClient) ListPublishersPreparer(ctx context.Cont "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -361,7 +361,7 @@ func (client VirtualMachineImagesClient) ListSkusPreparer(ctx context.Context, l "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineruncommands.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineruncommands.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineruncommands.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineruncommands.go index 3777e8b867037..525fc948b8454 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineruncommands.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachineruncommands.go @@ -80,7 +80,7 @@ func (client VirtualMachineRunCommandsClient) GetPreparer(ctx context.Context, l "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -152,7 +152,7 @@ func (client VirtualMachineRunCommandsClient) ListPreparer(ctx context.Context, "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachines.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachines.go similarity index 98% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachines.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachines.go index 40a6166a1f346..e8149617e6e9c 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachines.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachines.go @@ -78,7 +78,7 @@ func (client VirtualMachinesClient) CapturePreparer(ctx context.Context, resourc "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -152,7 +152,7 @@ func (client VirtualMachinesClient) ConvertToManagedDisksPreparer(ctx context.Co "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -244,7 +244,7 @@ func (client VirtualMachinesClient) CreateOrUpdatePreparer(ctx context.Context, "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -318,7 +318,7 @@ func (client VirtualMachinesClient) DeallocatePreparer(ctx context.Context, reso "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -388,7 +388,7 @@ func (client VirtualMachinesClient) DeletePreparer(ctx context.Context, resource "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -464,7 +464,7 @@ func (client VirtualMachinesClient) GeneralizePreparer(ctx context.Context, reso "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -531,7 +531,7 @@ func (client VirtualMachinesClient) GetPreparer(ctx context.Context, resourceGro "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -601,7 +601,7 @@ func (client VirtualMachinesClient) InstanceViewPreparer(ctx context.Context, re "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -668,7 +668,7 @@ func (client VirtualMachinesClient) ListPreparer(ctx context.Context, resourceGr "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -759,7 +759,7 @@ func (client VirtualMachinesClient) ListAllPreparer(ctx context.Context) (*http. "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -853,7 +853,7 @@ func (client VirtualMachinesClient) ListAvailableSizesPreparer(ctx context.Conte "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -914,7 +914,7 @@ func (client VirtualMachinesClient) PerformMaintenancePreparer(ctx context.Conte "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -985,7 +985,7 @@ func (client VirtualMachinesClient) PowerOffPreparer(ctx context.Context, resour "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1055,7 +1055,7 @@ func (client VirtualMachinesClient) RedeployPreparer(ctx context.Context, resour "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1125,7 +1125,7 @@ func (client VirtualMachinesClient) RestartPreparer(ctx context.Context, resourc "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1202,7 +1202,7 @@ func (client VirtualMachinesClient) RunCommandPreparer(ctx context.Context, reso "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1275,7 +1275,7 @@ func (client VirtualMachinesClient) StartPreparer(ctx context.Context, resourceG "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1346,7 +1346,7 @@ func (client VirtualMachinesClient) UpdatePreparer(ctx context.Context, resource "vmName": autorest.Encode("path", VMName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetextensions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetextensions.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetextensions.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetextensions.go index c2f1187f8596d..43e443249b7ee 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetextensions.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetextensions.go @@ -71,7 +71,7 @@ func (client VirtualMachineScaleSetExtensionsClient) CreateOrUpdatePreparer(ctx "vmssExtensionName": autorest.Encode("path", vmssExtensionName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -146,7 +146,7 @@ func (client VirtualMachineScaleSetExtensionsClient) DeletePreparer(ctx context. "vmssExtensionName": autorest.Encode("path", vmssExtensionName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -225,7 +225,7 @@ func (client VirtualMachineScaleSetExtensionsClient) GetPreparer(ctx context.Con "vmssExtensionName": autorest.Encode("path", vmssExtensionName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -296,7 +296,7 @@ func (client VirtualMachineScaleSetExtensionsClient) ListPreparer(ctx context.Co "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetrollingupgrades.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetrollingupgrades.go similarity index 75% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetrollingupgrades.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetrollingupgrades.go index 381cb0cb63276..ca98956cfd04e 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetrollingupgrades.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetrollingupgrades.go @@ -69,7 +69,7 @@ func (client VirtualMachineScaleSetRollingUpgradesClient) CancelPreparer(ctx con "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -145,7 +145,7 @@ func (client VirtualMachineScaleSetRollingUpgradesClient) GetLatestPreparer(ctx "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -178,6 +178,78 @@ func (client VirtualMachineScaleSetRollingUpgradesClient) GetLatestResponder(res return } +// StartExtensionUpgrade starts a rolling upgrade to move all extensions for all virtual machine scale set instances to +// the latest available extension version. Instances which are already running the latest extension versions are not +// affected. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +func (client VirtualMachineScaleSetRollingUpgradesClient) StartExtensionUpgrade(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetRollingUpgradesStartExtensionUpgradeFuture, err error) { + req, err := client.StartExtensionUpgradePreparer(ctx, resourceGroupName, VMScaleSetName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesClient", "StartExtensionUpgrade", nil, "Failure preparing request") + return + } + + result, err = client.StartExtensionUpgradeSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesClient", "StartExtensionUpgrade", result.Response(), "Failure sending request") + return + } + + return +} + +// StartExtensionUpgradePreparer prepares the StartExtensionUpgrade request. +func (client VirtualMachineScaleSetRollingUpgradesClient) StartExtensionUpgradePreparer(ctx context.Context, resourceGroupName string, VMScaleSetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", VMScaleSetName), + } + + const APIVersion = "2018-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/extensionRollingUpgrade", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// StartExtensionUpgradeSender sends the StartExtensionUpgrade request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetRollingUpgradesClient) StartExtensionUpgradeSender(req *http.Request) (future VirtualMachineScaleSetRollingUpgradesStartExtensionUpgradeFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// StartExtensionUpgradeResponder handles the response to the StartExtensionUpgrade request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetRollingUpgradesClient) StartExtensionUpgradeResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + // StartOSUpgrade starts a rolling upgrade to move all virtual machine scale set instances to the latest available // Platform Image OS version. Instances which are already running the latest available OS version are not affected. // Parameters: @@ -207,7 +279,7 @@ func (client VirtualMachineScaleSetRollingUpgradesClient) StartOSUpgradePreparer "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesets.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesets.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesets.go index ef73c14177561..f78d824fdfef9 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesets.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesets.go @@ -92,7 +92,7 @@ func (client VirtualMachineScaleSetsClient) CreateOrUpdatePreparer(ctx context.C "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -167,7 +167,7 @@ func (client VirtualMachineScaleSetsClient) DeallocatePreparer(ctx context.Conte "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -242,7 +242,7 @@ func (client VirtualMachineScaleSetsClient) DeletePreparer(ctx context.Context, "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -319,7 +319,7 @@ func (client VirtualMachineScaleSetsClient) DeleteInstancesPreparer(ctx context. "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -399,7 +399,7 @@ func (client VirtualMachineScaleSetsClient) ForceRecoveryServiceFabricPlatformUp "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, "platformUpdateDomain": autorest.Encode("query", platformUpdateDomain), @@ -467,7 +467,7 @@ func (client VirtualMachineScaleSetsClient) GetPreparer(ctx context.Context, res "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -534,7 +534,7 @@ func (client VirtualMachineScaleSetsClient) GetInstanceViewPreparer(ctx context. "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -602,7 +602,7 @@ func (client VirtualMachineScaleSetsClient) GetOSUpgradeHistoryPreparer(ctx cont "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -695,7 +695,7 @@ func (client VirtualMachineScaleSetsClient) ListPreparer(ctx context.Context, re "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -787,7 +787,7 @@ func (client VirtualMachineScaleSetsClient) ListAllPreparer(ctx context.Context) "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -883,7 +883,7 @@ func (client VirtualMachineScaleSetsClient) ListSkusPreparer(ctx context.Context "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -974,7 +974,7 @@ func (client VirtualMachineScaleSetsClient) PerformMaintenancePreparer(ctx conte "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1051,7 +1051,7 @@ func (client VirtualMachineScaleSetsClient) PowerOffPreparer(ctx context.Context "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1127,7 +1127,7 @@ func (client VirtualMachineScaleSetsClient) RedeployPreparer(ctx context.Context "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1203,7 +1203,7 @@ func (client VirtualMachineScaleSetsClient) ReimagePreparer(ctx context.Context, "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1280,7 +1280,7 @@ func (client VirtualMachineScaleSetsClient) ReimageAllPreparer(ctx context.Conte "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1356,7 +1356,7 @@ func (client VirtualMachineScaleSetsClient) RestartPreparer(ctx context.Context, "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1432,7 +1432,7 @@ func (client VirtualMachineScaleSetsClient) StartPreparer(ctx context.Context, r "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1508,7 +1508,7 @@ func (client VirtualMachineScaleSetsClient) UpdatePreparer(ctx context.Context, "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1588,7 +1588,7 @@ func (client VirtualMachineScaleSetsClient) UpdateInstancesPreparer(ctx context. "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetvms.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetvms.go similarity index 99% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetvms.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetvms.go index a068ec453f0e6..2742fe91126e2 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetvms.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinescalesetvms.go @@ -72,7 +72,7 @@ func (client VirtualMachineScaleSetVMsClient) DeallocatePreparer(ctx context.Con "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -144,7 +144,7 @@ func (client VirtualMachineScaleSetVMsClient) DeletePreparer(ctx context.Context "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -222,7 +222,7 @@ func (client VirtualMachineScaleSetVMsClient) GetPreparer(ctx context.Context, r "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -291,7 +291,7 @@ func (client VirtualMachineScaleSetVMsClient) GetInstanceViewPreparer(ctx contex "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -362,7 +362,7 @@ func (client VirtualMachineScaleSetVMsClient) ListPreparer(ctx context.Context, "virtualMachineScaleSetName": autorest.Encode("path", virtualMachineScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -461,7 +461,7 @@ func (client VirtualMachineScaleSetVMsClient) PerformMaintenancePreparer(ctx con "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -534,7 +534,7 @@ func (client VirtualMachineScaleSetVMsClient) PowerOffPreparer(ctx context.Conte "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -606,7 +606,7 @@ func (client VirtualMachineScaleSetVMsClient) RedeployPreparer(ctx context.Conte "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -678,7 +678,7 @@ func (client VirtualMachineScaleSetVMsClient) ReimagePreparer(ctx context.Contex "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -751,7 +751,7 @@ func (client VirtualMachineScaleSetVMsClient) ReimageAllPreparer(ctx context.Con "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -823,7 +823,7 @@ func (client VirtualMachineScaleSetVMsClient) RestartPreparer(ctx context.Contex "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -902,7 +902,7 @@ func (client VirtualMachineScaleSetVMsClient) RunCommandPreparer(ctx context.Con "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -977,7 +977,7 @@ func (client VirtualMachineScaleSetVMsClient) StartPreparer(ctx context.Context, "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -1071,7 +1071,7 @@ func (client VirtualMachineScaleSetVMsClient) UpdatePreparer(ctx context.Context "vmScaleSetName": autorest.Encode("path", VMScaleSetName), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinesizes.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinesizes.go similarity index 96% rename from vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinesizes.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinesizes.go index d339b5dee2d0e..91343db942060 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinesizes.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute/virtualmachinesizes.go @@ -40,7 +40,8 @@ func NewVirtualMachineSizesClientWithBaseURI(baseURI string, subscriptionID stri return VirtualMachineSizesClient{NewWithBaseURI(baseURI, subscriptionID)} } -// List lists all available virtual machine sizes for a subscription in a location. +// List this API is deprecated. Use [Resources +// Skus](https://docs.microsoft.com/en-us/rest/api/compute/resourceskus/list) // Parameters: // location - the location upon which virtual-machine-sizes is queried. func (client VirtualMachineSizesClient) List(ctx context.Context, location string) (result VirtualMachineSizeListResult, err error) { @@ -78,7 +79,7 @@ func (client VirtualMachineSizesClient) ListPreparer(ctx context.Context, locati "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2018-04-01" + const APIVersion = "2018-10-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry/models.go index 19c6fb28d78cf..8e5ee3778cba8 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry/models.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry/models.go @@ -443,8 +443,10 @@ type ImportImageParameters struct { type ImportSource struct { // ResourceID - The resource identifier of the source Azure Container Registry. ResourceID *string `json:"resourceId,omitempty"` - // RegistryURI - The address of the source registry. + // RegistryURI - The address of the source registry (e.g. 'mcr.microsoft.com'). RegistryURI *string `json:"registryUri,omitempty"` + // Credentials - Credentials used when importing from a registry uri. + Credentials *ImportSourceCredentials `json:"credentials,omitempty"` // SourceImage - Repository name of the source image. // Specify an image by repository ('hello-world'). This will use the 'latest' tag. // Specify an image by tag ('hello-world:latest'). @@ -452,6 +454,14 @@ type ImportSource struct { SourceImage *string `json:"sourceImage,omitempty"` } +// ImportSourceCredentials ... +type ImportSourceCredentials struct { + // Username - The username to authenticate with the source registry. + Username *string `json:"username,omitempty"` + // Password - The password used to authenticate with the source registry. + Password *string `json:"password,omitempty"` +} + // OperationDefinition the definition of a container registry operation. type OperationDefinition struct { // Origin - The origin information of the container registry operation. @@ -822,6 +832,8 @@ type Registry struct { autorest.Response `json:"-"` // Sku - The SKU of the container registry. Sku *Sku `json:"sku,omitempty"` + // Identity - The identity of the container registry. + Identity *RegistryIdentity `json:"identity,omitempty"` // RegistryProperties - The properties of the container registry. *RegistryProperties `json:"properties,omitempty"` // ID - The resource ID. @@ -842,6 +854,9 @@ func (r Registry) MarshalJSON() ([]byte, error) { if r.Sku != nil { objectMap["sku"] = r.Sku } + if r.Identity != nil { + objectMap["identity"] = r.Identity + } if r.RegistryProperties != nil { objectMap["properties"] = r.RegistryProperties } @@ -881,6 +896,15 @@ func (r *Registry) UnmarshalJSON(body []byte) error { } r.Sku = &sku } + case "identity": + if v != nil { + var identity RegistryIdentity + err = json.Unmarshal(*v, &identity) + if err != nil { + return err + } + r.Identity = &identity + } case "properties": if v != nil { var registryProperties RegistryProperties @@ -941,6 +965,16 @@ func (r *Registry) UnmarshalJSON(body []byte) error { return nil } +// RegistryIdentity the identity of the container registry. +type RegistryIdentity struct { + // Type - The type of identity used for the registry. + Type *string `json:"type,omitempty"` + // PrincipalID - The principal ID of registry identity. + PrincipalID *string `json:"principalId,omitempty"` + // TenantID - The tenant ID associated with the registry. + TenantID *string `json:"tenantId,omitempty"` +} + // RegistryListCredentialsResult the response from the ListCredentials operation. type RegistryListCredentialsResult struct { autorest.Response `json:"-"` @@ -1118,6 +1152,8 @@ type RegistryUpdateParameters struct { Tags map[string]*string `json:"tags"` // Sku - The SKU of the container registry. Sku *Sku `json:"sku,omitempty"` + // Identity - The identity of the container registry. + Identity *RegistryIdentity `json:"identity,omitempty"` // RegistryPropertiesUpdateParameters - The properties that the container registry will be updated with. *RegistryPropertiesUpdateParameters `json:"properties,omitempty"` } @@ -1131,6 +1167,9 @@ func (rup RegistryUpdateParameters) MarshalJSON() ([]byte, error) { if rup.Sku != nil { objectMap["sku"] = rup.Sku } + if rup.Identity != nil { + objectMap["identity"] = rup.Identity + } if rup.RegistryPropertiesUpdateParameters != nil { objectMap["properties"] = rup.RegistryPropertiesUpdateParameters } @@ -1164,6 +1203,15 @@ func (rup *RegistryUpdateParameters) UnmarshalJSON(body []byte) error { } rup.Sku = &sku } + case "identity": + if v != nil { + var identity RegistryIdentity + err = json.Unmarshal(*v, &identity) + if err != nil { + return err + } + rup.Identity = &identity + } case "properties": if v != nil { var registryPropertiesUpdateParameters RegistryPropertiesUpdateParameters diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry/registries.go b/vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry/registries.go index 4fce43c74d0a5..b02ca13b2ea2b 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry/registries.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry/registries.go @@ -372,7 +372,10 @@ func (client RegistriesClient) ImportImage(ctx context.Context, resourceGroupNam {Target: "registryName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9]*$`, Chain: nil}}}, {TargetValue: parameters, Constraints: []validation.Constraint{{Target: "parameters.Source", Name: validation.Null, Rule: true, - Chain: []validation.Constraint{{Target: "parameters.Source.SourceImage", Name: validation.Null, Rule: true, Chain: nil}}}}}}); err != nil { + Chain: []validation.Constraint{{Target: "parameters.Source.Credentials", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Source.Credentials.Password", Name: validation.Null, Rule: true, Chain: nil}}}, + {Target: "parameters.Source.SourceImage", Name: validation.Null, Rule: true, Chain: nil}, + }}}}}); err != nil { return result, validation.NewError("containerregistry.RegistriesClient", "ImportImage", err.Error()) } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/applicationgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/applicationgateways.go index fe19916146dae..89b0b01ff991a 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/applicationgateways.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/applicationgateways.go @@ -94,10 +94,6 @@ func (client ApplicationGatewaysClient) BackendHealthSender(req *http.Request) ( if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -180,10 +176,6 @@ func (client ApplicationGatewaysClient) CreateOrUpdateSender(req *http.Request) if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -251,10 +243,6 @@ func (client ApplicationGatewaysClient) DeleteSender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -850,10 +838,6 @@ func (client ApplicationGatewaysClient) StartSender(req *http.Request) (future A if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -920,10 +904,6 @@ func (client ApplicationGatewaysClient) StopSender(req *http.Request) (future Ap if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -993,10 +973,6 @@ func (client ApplicationGatewaysClient) UpdateTagsSender(req *http.Request) (fut if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/applicationsecuritygroups.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/applicationsecuritygroups.go index 4d1a255a47be9..7c2ebe4692e5b 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/applicationsecuritygroups.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/applicationsecuritygroups.go @@ -92,10 +92,6 @@ func (client ApplicationSecurityGroupsClient) CreateOrUpdateSender(req *http.Req if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -163,10 +159,6 @@ func (client ApplicationSecurityGroupsClient) DeleteSender(req *http.Request) (f if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuitauthorizations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuitauthorizations.go index 2860cd6973345..0a15c4b4bd943 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuitauthorizations.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuitauthorizations.go @@ -97,10 +97,6 @@ func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdateSender(req * if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -170,10 +166,6 @@ func (client ExpressRouteCircuitAuthorizationsClient) DeleteSender(req *http.Req if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuitpeerings.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuitpeerings.go index b129f3c2ed804..7f397879c1d8b 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuitpeerings.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuitpeerings.go @@ -94,10 +94,6 @@ func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdateSender(req *http.R if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -167,10 +163,6 @@ func (client ExpressRouteCircuitPeeringsClient) DeleteSender(req *http.Request) if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuits.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuits.go index 0a11eb94914aa..d2932342de9ca 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuits.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/expressroutecircuits.go @@ -92,10 +92,6 @@ func (client ExpressRouteCircuitsClient) CreateOrUpdateSender(req *http.Request) if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -163,10 +159,6 @@ func (client ExpressRouteCircuitsClient) DeleteSender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -623,10 +615,6 @@ func (client ExpressRouteCircuitsClient) ListArpTableSender(req *http.Request) ( if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -699,10 +687,6 @@ func (client ExpressRouteCircuitsClient) ListRoutesTableSender(req *http.Request if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -775,10 +759,6 @@ func (client ExpressRouteCircuitsClient) ListRoutesTableSummarySender(req *http. if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -849,10 +829,6 @@ func (client ExpressRouteCircuitsClient) UpdateTagsSender(req *http.Request) (fu if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/inboundnatrules.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/inboundnatrules.go index 64c604441c6a6..806e21e3f9d24 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/inboundnatrules.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/inboundnatrules.go @@ -114,10 +114,6 @@ func (client InboundNatRulesClient) CreateOrUpdateSender(req *http.Request) (fut if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -187,10 +183,6 @@ func (client InboundNatRulesClient) DeleteSender(req *http.Request) (future Inbo if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/interfaces.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/interfaces.go index 5632e32b2276c..3b345a136fb8c 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/interfaces.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/interfaces.go @@ -92,10 +92,6 @@ func (client InterfacesClient) CreateOrUpdateSender(req *http.Request) (future I if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -163,10 +159,6 @@ func (client InterfacesClient) DeleteSender(req *http.Request) (future Interface if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -304,10 +296,6 @@ func (client InterfacesClient) GetEffectiveRouteTableSender(req *http.Request) ( if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -711,10 +699,6 @@ func (client InterfacesClient) ListEffectiveNetworkSecurityGroupsSender(req *htt if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1082,10 +1066,6 @@ func (client InterfacesClient) UpdateTagsSender(req *http.Request) (future Inter if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/loadbalancers.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/loadbalancers.go index f62ad7b99d646..27b6955976ee8 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/loadbalancers.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/loadbalancers.go @@ -92,10 +92,6 @@ func (client LoadBalancersClient) CreateOrUpdateSender(req *http.Request) (futur if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -163,10 +159,6 @@ func (client LoadBalancersClient) DeleteSender(req *http.Request) (future LoadBa if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -490,10 +482,6 @@ func (client LoadBalancersClient) UpdateTagsSender(req *http.Request) (future Lo if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/localnetworkgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/localnetworkgateways.go index b20ca1df7b687..1933dc9376685 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/localnetworkgateways.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/localnetworkgateways.go @@ -101,10 +101,6 @@ func (client LocalNetworkGatewaysClient) CreateOrUpdateSender(req *http.Request) if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -178,10 +174,6 @@ func (client LocalNetworkGatewaysClient) DeleteSender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -423,10 +415,6 @@ func (client LocalNetworkGatewaysClient) UpdateTagsSender(req *http.Request) (fu if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/packetcaptures.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/packetcaptures.go index 78b6b80d90b59..e44a38221dbb5 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/packetcaptures.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/packetcaptures.go @@ -104,10 +104,6 @@ func (client PacketCapturesClient) CreateSender(req *http.Request) (future Packe if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -177,10 +173,6 @@ func (client PacketCapturesClient) DeleteSender(req *http.Request) (future Packe if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -318,10 +310,6 @@ func (client PacketCapturesClient) GetStatusSender(req *http.Request) (future Pa if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -458,10 +446,6 @@ func (client PacketCapturesClient) StopSender(req *http.Request) (future PacketC if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/publicipaddresses.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/publicipaddresses.go index c49d425fe4e35..0b1bb489f8770 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/publicipaddresses.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/publicipaddresses.go @@ -104,10 +104,6 @@ func (client PublicIPAddressesClient) CreateOrUpdateSender(req *http.Request) (f if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -175,10 +171,6 @@ func (client PublicIPAddressesClient) DeleteSender(req *http.Request) (future Pu if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -779,10 +771,6 @@ func (client PublicIPAddressesClient) UpdateTagsSender(req *http.Request) (futur if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routefilterrules.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routefilterrules.go index 70181ed68c970..a9e3ae6232266 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routefilterrules.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routefilterrules.go @@ -104,10 +104,6 @@ func (client RouteFilterRulesClient) CreateOrUpdateSender(req *http.Request) (fu if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -177,10 +173,6 @@ func (client RouteFilterRulesClient) DeleteSender(req *http.Request) (future Rou if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -416,10 +408,6 @@ func (client RouteFilterRulesClient) UpdateSender(req *http.Request) (future Rou if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routefilters.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routefilters.go index 5c4f503fd6980..245ad832aec2f 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routefilters.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routefilters.go @@ -92,10 +92,6 @@ func (client RouteFiltersClient) CreateOrUpdateSender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -163,10 +159,6 @@ func (client RouteFiltersClient) DeleteSender(req *http.Request) (future RouteFi if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -490,10 +482,6 @@ func (client RouteFiltersClient) UpdateSender(req *http.Request) (future RouteFi if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routes.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routes.go index a1ac17b7decf7..013576182ec91 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routes.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routes.go @@ -94,10 +94,6 @@ func (client RoutesClient) CreateOrUpdateSender(req *http.Request) (future Route if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -167,10 +163,6 @@ func (client RoutesClient) DeleteSender(req *http.Request) (future RoutesDeleteF if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routetables.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routetables.go index c839f21b06060..490fe3032f783 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routetables.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/routetables.go @@ -92,10 +92,6 @@ func (client RouteTablesClient) CreateOrUpdateSender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -163,10 +159,6 @@ func (client RouteTablesClient) DeleteSender(req *http.Request) (future RouteTab if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -490,10 +482,6 @@ func (client RouteTablesClient) UpdateTagsSender(req *http.Request) (future Rout if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/securitygroups.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/securitygroups.go index e20eaeef39284..fa4d471b3babb 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/securitygroups.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/securitygroups.go @@ -92,10 +92,6 @@ func (client SecurityGroupsClient) CreateOrUpdateSender(req *http.Request) (futu if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -163,10 +159,6 @@ func (client SecurityGroupsClient) DeleteSender(req *http.Request) (future Secur if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -490,10 +482,6 @@ func (client SecurityGroupsClient) UpdateTagsSender(req *http.Request) (future S if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/securityrules.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/securityrules.go index e1761f25235ae..cab4c1f3f14bf 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/securityrules.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/securityrules.go @@ -94,10 +94,6 @@ func (client SecurityRulesClient) CreateOrUpdateSender(req *http.Request) (futur if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -167,10 +163,6 @@ func (client SecurityRulesClient) DeleteSender(req *http.Request) (future Securi if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/subnets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/subnets.go index 13f8a8bf15abf..10a16654f61c7 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/subnets.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/subnets.go @@ -94,10 +94,6 @@ func (client SubnetsClient) CreateOrUpdateSender(req *http.Request) (future Subn if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -167,10 +163,6 @@ func (client SubnetsClient) DeleteSender(req *http.Request) (future SubnetsDelet if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkgatewayconnections.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkgatewayconnections.go index 5facf960ef788..230392d5b3300 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkgatewayconnections.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkgatewayconnections.go @@ -107,10 +107,6 @@ func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdateSender(req *h if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -178,10 +174,6 @@ func (client VirtualNetworkGatewayConnectionsClient) DeleteSender(req *http.Requ if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -492,10 +484,6 @@ func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKeySender(req *h if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -575,10 +563,6 @@ func (client VirtualNetworkGatewayConnectionsClient) SetSharedKeySender(req *htt if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -649,10 +633,6 @@ func (client VirtualNetworkGatewayConnectionsClient) UpdateTagsSender(req *http. if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkgateways.go index b45b6bd82c04d..8e17e0a62e878 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkgateways.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkgateways.go @@ -99,10 +99,6 @@ func (client VirtualNetworkGatewaysClient) CreateOrUpdateSender(req *http.Reques if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -170,10 +166,6 @@ func (client VirtualNetworkGatewaysClient) DeleteSender(req *http.Request) (futu if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -244,10 +236,6 @@ func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackageSender(req *h if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -319,10 +307,6 @@ func (client VirtualNetworkGatewaysClient) GenerateVpnProfileSender(req *http.Re if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -460,10 +444,6 @@ func (client VirtualNetworkGatewaysClient) GetAdvertisedRoutesSender(req *http.R if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -535,10 +515,6 @@ func (client VirtualNetworkGatewaysClient) GetBgpPeerStatusSender(req *http.Requ if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -607,10 +583,6 @@ func (client VirtualNetworkGatewaysClient) GetLearnedRoutesSender(req *http.Requ if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -679,10 +651,6 @@ func (client VirtualNetworkGatewaysClient) GetVpnProfilePackageURLSender(req *ht if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -943,10 +911,6 @@ func (client VirtualNetworkGatewaysClient) ResetSender(req *http.Request) (futur if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1084,10 +1048,6 @@ func (client VirtualNetworkGatewaysClient) UpdateTagsSender(req *http.Request) ( if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkpeerings.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkpeerings.go index a0a54eea9ffcd..b5824eca546f3 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkpeerings.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworkpeerings.go @@ -95,10 +95,6 @@ func (client VirtualNetworkPeeringsClient) CreateOrUpdateSender(req *http.Reques if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -168,10 +164,6 @@ func (client VirtualNetworkPeeringsClient) DeleteSender(req *http.Request) (futu if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworks.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworks.go index afcd4b75c6209..9a7007ac7f941 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworks.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/virtualnetworks.go @@ -163,10 +163,6 @@ func (client VirtualNetworksClient) CreateOrUpdateSender(req *http.Request) (fut if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -234,10 +230,6 @@ func (client VirtualNetworksClient) DeleteSender(req *http.Request) (future Virt if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -656,10 +648,6 @@ func (client VirtualNetworksClient) UpdateTagsSender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/watchers.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/watchers.go index 992df7b254ad4..475ec59326934 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/watchers.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network/watchers.go @@ -102,10 +102,6 @@ func (client WatchersClient) CheckConnectivitySender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -243,10 +239,6 @@ func (client WatchersClient) DeleteSender(req *http.Request) (future WatchersDel if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -393,10 +385,6 @@ func (client WatchersClient) GetAzureReachabilityReportSender(req *http.Request) if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -473,10 +461,6 @@ func (client WatchersClient) GetFlowLogStatusSender(req *http.Request) (future W if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -555,10 +539,6 @@ func (client WatchersClient) GetNextHopSender(req *http.Request) (future Watcher if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -715,10 +695,6 @@ func (client WatchersClient) GetTroubleshootingSender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -795,10 +771,6 @@ func (client WatchersClient) GetTroubleshootingResultSender(req *http.Request) ( if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -875,10 +847,6 @@ func (client WatchersClient) GetVMSecurityRulesSender(req *http.Request) (future if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1076,10 +1044,6 @@ func (client WatchersClient) ListAvailableProvidersSender(req *http.Request) (fu if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1160,10 +1124,6 @@ func (client WatchersClient) SetFlowLogConfigurationSender(req *http.Request) (f if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1314,10 +1274,6 @@ func (client WatchersClient) VerifyIPFlowSender(req *http.Request) (future Watch if err != nil { return } - err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) - if err != nil { - return - } future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go index 55238ab15ffc2..f90050cb0029f 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go @@ -169,7 +169,7 @@ func (q *Queue) GetMetadata(options *QueueServiceOptions) error { params = addTimeout(params, options.Timeout) headers = mergeHeaders(headers, headersFromStruct(*options)) } - uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), url.Values{"comp": {"metadata"}}) + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), params) resp, err := q.qsc.client.exec(http.MethodGet, uri, headers, nil, q.qsc.auth) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go index a9cd65df58697..7f0f6f2b660e9 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go @@ -18,4 +18,4 @@ package version // Changes may cause incorrect behavior and will be lost if the code is regenerated. // Number contains the semantic version of this SDK. -const Number = "v21.1.0" +const Number = "v21.3.0" diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go index bee5e61ddb2c0..8c83a917ff7e7 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go @@ -19,10 +19,6 @@ import ( "net/url" ) -const ( - activeDirectoryAPIVersion = "1.0" -) - // OAuthConfig represents the endpoints needed // in OAuth operations type OAuthConfig struct { @@ -46,11 +42,25 @@ func validateStringParam(param, name string) error { // NewOAuthConfig returns an OAuthConfig with tenant specific urls func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) { + apiVer := "1.0" + return NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID, &apiVer) +} + +// NewOAuthConfigWithAPIVersion returns an OAuthConfig with tenant specific urls. +// If apiVersion is not nil the "api-version" query parameter will be appended to the endpoint URLs with the specified value. +func NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID string, apiVersion *string) (*OAuthConfig, error) { if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil { return nil, err } + api := "" // it's legal for tenantID to be empty so don't validate it - const activeDirectoryEndpointTemplate = "%s/oauth2/%s?api-version=%s" + if apiVersion != nil { + if err := validateStringParam(*apiVersion, "apiVersion"); err != nil { + return nil, err + } + api = fmt.Sprintf("?api-version=%s", *apiVersion) + } + const activeDirectoryEndpointTemplate = "%s/oauth2/%s%s" u, err := url.Parse(activeDirectoryEndpoint) if err != nil { return nil, err @@ -59,15 +69,15 @@ func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, err if err != nil { return nil, err } - authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", activeDirectoryAPIVersion)) + authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", api)) if err != nil { return nil, err } - tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", activeDirectoryAPIVersion)) + tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", api)) if err != nil { return nil, err } - deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", activeDirectoryAPIVersion)) + deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", api)) if err != nil { return nil, err } diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go b/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go index 0e5ad14d39627..834401e00dec4 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go @@ -38,7 +38,7 @@ func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { return sf(r) } -// SendDecorator takes and possibily decorates, by wrapping, a Sender. Decorators may affect the +// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the // http.Request and pass it along or, first, pass the http.Request along then react to the // http.Response result. type SendDecorator func(Sender) Sender diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go index 32aea83891276..2fd340d6922f6 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go @@ -29,7 +29,6 @@ import ( "net" "net/http" "net/url" - "strconv" "strings" "sync" "time" @@ -97,18 +96,27 @@ type RefresherWithContext interface { type TokenRefreshCallback func(Token) error // Token encapsulates the access token used to authorize Azure requests. +// https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#service-to-service-access-token-response type Token struct { AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` - ExpiresIn string `json:"expires_in"` - ExpiresOn string `json:"expires_on"` - NotBefore string `json:"not_before"` + ExpiresIn json.Number `json:"expires_in"` + ExpiresOn json.Number `json:"expires_on"` + NotBefore json.Number `json:"not_before"` Resource string `json:"resource"` Type string `json:"token_type"` } +func newToken() Token { + return Token{ + ExpiresIn: "0", + ExpiresOn: "0", + NotBefore: "0", + } +} + // IsZero returns true if the token object is zero-initialized. func (t Token) IsZero() bool { return t == Token{} @@ -116,12 +124,12 @@ func (t Token) IsZero() bool { // Expires returns the time.Time when the Token expires. func (t Token) Expires() time.Time { - s, err := strconv.Atoi(t.ExpiresOn) + s, err := t.ExpiresOn.Float64() if err != nil { s = -3600 } - expiration := date.NewUnixTimeFromSeconds(float64(s)) + expiration := date.NewUnixTimeFromSeconds(s) return time.Time(expiration).UTC() } @@ -218,6 +226,8 @@ func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalTo token := jwt.New(jwt.SigningMethodRS256) token.Header["x5t"] = thumbprint + x5c := []string{base64.StdEncoding.EncodeToString(secret.Certificate.Raw)} + token.Header["x5c"] = x5c token.Claims = jwt.MapClaims{ "aud": spt.inner.OauthConfig.TokenEndpoint.String(), "iss": spt.inner.ClientID, @@ -414,6 +424,7 @@ func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, reso } spt := &ServicePrincipalToken{ inner: servicePrincipalToken{ + Token: newToken(), OauthConfig: oauthConfig, Secret: secret, ClientID: id, @@ -653,6 +664,7 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI spt := &ServicePrincipalToken{ inner: servicePrincipalToken{ + Token: newToken(), OauthConfig: OAuthConfig{ TokenEndpoint: *msiEndpointURL, }, diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go index 9dd7a1d27c5f1..e43f7a2c4dac9 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go @@ -168,8 +168,12 @@ func (f Future) WaitForCompletion(ctx context.Context, client autorest.Client) e // polling duration has been exceeded. It will retry failed polling attempts based on // the retry value defined in the client up to the maximum retry attempts. func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Client) error { - ctx, cancel := context.WithTimeout(ctx, client.PollingDuration) - defer cancel() + if d := client.PollingDuration; d != 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, d) + defer cancel() + } + done, err := f.Done(client) for attempts := 0; !done; done, err = f.Done(client) { if attempts >= client.RetryAttempts { diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go index bd34f0ed5a581..86ce9f2b5b1e5 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go @@ -140,8 +140,8 @@ func register(client autorest.Client, originalReq *http.Request, re RequestError } // poll for registered provisioning state - now := time.Now() - for err == nil && time.Since(now) < client.PollingDuration { + registrationStartTime := time.Now() + for err == nil && (client.PollingDuration == 0 || (client.PollingDuration != 0 && time.Since(registrationStartTime) < client.PollingDuration)) { // taken from the resources SDK // https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45 preparer := autorest.CreatePreparer( @@ -183,7 +183,7 @@ func register(client autorest.Client, originalReq *http.Request, re RequestError return originalReq.Context().Err() } } - if !(time.Since(now) < client.PollingDuration) { + if client.PollingDuration != 0 && !(time.Since(registrationStartTime) < client.PollingDuration) { return errors.New("polling for resource provider registration has exceeded the polling duration") } return err diff --git a/vendor/github.com/Azure/go-autorest/autorest/client.go b/vendor/github.com/Azure/go-autorest/autorest/client.go index 5c558c83a7e57..48eb0e8b73bc0 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/client.go +++ b/vendor/github.com/Azure/go-autorest/autorest/client.go @@ -147,6 +147,7 @@ type Client struct { PollingDelay time.Duration // PollingDuration sets the maximum polling time after which an error is returned. + // Setting this to zero will use the provided context to control the duration. PollingDuration time.Duration // RetryAttempts sets the default number of retry attempts for client. diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go index cacbd815717dd..e8893a282e386 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/sender.go +++ b/vendor/github.com/Azure/go-autorest/autorest/sender.go @@ -234,7 +234,7 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se } delayed := DelayWithRetryAfter(resp, r.Context().Done()) if !delayed && !DelayForBackoff(backoff, attempt, r.Context().Done()) { - return nil, r.Context().Err() + return resp, r.Context().Err() } // don't count a 429 against the number of attempts // so that we continue to retry until it succeeds diff --git a/vendor/github.com/Azure/go-autorest/version/version.go b/vendor/github.com/Azure/go-autorest/version/version.go index ad2d6099f52bf..6323c288fbfc7 100644 --- a/vendor/github.com/Azure/go-autorest/version/version.go +++ b/vendor/github.com/Azure/go-autorest/version/version.go @@ -20,7 +20,7 @@ import ( ) // Number contains the semantic version of this SDK. -const Number = "v10.15.4" +const Number = "v11.1.0" var ( userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s", diff --git a/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md b/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md new file mode 100644 index 0000000000000..f0f7e3a8add01 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md @@ -0,0 +1,63 @@ +#### Support +If you do have a contribution to the package, feel free to create a Pull Request or an Issue. + +#### What to contribute +If you don't know what to do, there are some features and functions that need to be done + +- [ ] Refactor code +- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check +- [ ] Create actual list of contributors and projects that currently using this package +- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues) +- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions) +- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new +- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc +- [ ] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224) +- [ ] Implement fuzzing testing +- [ ] Implement some struct/map/array utilities +- [ ] Implement map/array validation +- [ ] Implement benchmarking +- [ ] Implement batch of examples +- [ ] Look at forks for new features and fixes + +#### Advice +Feel free to create what you want, but keep in mind when you implement new features: +- Code must be clear and readable, names of variables/constants clearly describes what they are doing +- Public functions must be documented and described in source file and added to README.md to the list of available functions +- There are must be unit-tests for any new functions and improvements + +## Financial contributions + +We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/govalidator). +Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed. + + +## Credits + + +### Contributors + +Thank you to all the people who have already contributed to govalidator! + + + +### Backers + +Thank you to all our backers! [[Become a backer](https://opencollective.com/govalidator#backer)] + + + + +### Sponsors + +Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/govalidator#sponsor)) + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/github.com/asaskevich/govalidator/README.md b/vendor/github.com/asaskevich/govalidator/README.md index 57d85fd410c9a..0e8793f719a8e 100644 --- a/vendor/github.com/asaskevich/govalidator/README.md +++ b/vendor/github.com/asaskevich/govalidator/README.md @@ -1,7 +1,7 @@ govalidator =========== [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator) [![Coverage Status](https://img.shields.io/coveralls/asaskevich/govalidator.svg)](https://coveralls.io/r/asaskevich/govalidator?branch=master) [![wercker status](https://app.wercker.com/status/1ec990b09ea86c910d5f08b0e02c6043/s "wercker status")](https://app.wercker.com/project/bykey/1ec990b09ea86c910d5f08b0e02c6043) -[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) +[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield) A package of validators and sanitizers for strings, structs and collections. Based on [validator.js](https://github.com/chriso/validator.js). @@ -33,6 +33,8 @@ import ( #### Activate behavior to require all fields have a validation tag by default `SetFieldsRequiredByDefault` causes validation to fail when struct fields do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). A good place to activate this is a package init function or the main() function. +`SetNilPtrAllowedByRequired` causes validation to pass when struct fields marked by `required` are set to nil. This is disabled by default for consistency, but some packages that need to be able to determine between `nil` and `zero value` state can use this. If disabled, both `nil` and `zero` values cause validation errors. + ```go import "github.com/asaskevich/govalidator" @@ -96,28 +98,27 @@ govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator func Abs(value float64) float64 func BlackList(str, chars string) string func ByteLength(str string, params ...string) bool -func StringLength(str string, params ...string) bool -func StringMatches(s string, params ...string) bool func CamelCaseToUnderscore(str string) string func Contains(str, substring string) bool func Count(array []interface{}, iterator ConditionIterator) int func Each(array []interface{}, iterator Iterator) func ErrorByField(e error, field string) string +func ErrorsByField(e error) map[string]string func Filter(array []interface{}, iterator ConditionIterator) []interface{} func Find(array []interface{}, iterator ConditionIterator) interface{} func GetLine(s string, index int) (string, error) func GetLines(s string) []string -func IsHost(s string) bool func InRange(value, left, right float64) bool func IsASCII(str string) bool func IsAlpha(str string) bool func IsAlphanumeric(str string) bool func IsBase64(str string) bool func IsByteLength(str string, min, max int) bool +func IsCIDR(str string) bool func IsCreditCard(str string) bool +func IsDNSName(str string) bool func IsDataURI(str string) bool func IsDialString(str string) bool -func IsDNSName(str string) bool func IsDivisibleBy(str, num string) bool func IsEmail(str string) bool func IsFilePath(str string) (bool, int) @@ -126,6 +127,7 @@ func IsFullWidth(str string) bool func IsHalfWidth(str string) bool func IsHexadecimal(str string) bool func IsHexcolor(str string) bool +func IsHost(str string) bool func IsIP(str string) bool func IsIPv4(str string) bool func IsIPv6(str string) bool @@ -134,6 +136,10 @@ func IsISBN10(str string) bool func IsISBN13(str string) bool func IsISO3166Alpha2(str string) bool func IsISO3166Alpha3(str string) bool +func IsISO693Alpha2(str string) bool +func IsISO693Alpha3b(str string) bool +func IsISO4217(str string) bool +func IsIn(str string, params ...string) bool func IsInt(str string) bool func IsJSON(str string) bool func IsLatitude(str string) bool @@ -151,11 +157,14 @@ func IsNumeric(str string) bool func IsPort(str string) bool func IsPositive(value float64) bool func IsPrintableASCII(str string) bool +func IsRFC3339(str string) bool +func IsRFC3339WithoutZone(str string) bool func IsRGBcolor(str string) bool func IsRequestURI(rawurl string) bool func IsRequestURL(rawurl string) bool func IsSSN(str string) bool func IsSemver(str string) bool +func IsTime(str string, format string) bool func IsURL(str string) bool func IsUTFDigit(str string) bool func IsUTFLetter(str string) bool @@ -172,12 +181,20 @@ func LeftTrim(str, chars string) string func Map(array []interface{}, iterator ResultIterator) []interface{} func Matches(str, pattern string) bool func NormalizeEmail(str string) (string, error) +func PadBoth(str string, padStr string, padLen int) string +func PadLeft(str string, padStr string, padLen int) string +func PadRight(str string, padStr string, padLen int) string +func Range(str string, params ...string) bool func RemoveTags(s string) string func ReplacePattern(str, pattern, replace string) string func Reverse(s string) string func RightTrim(str, chars string) string +func RuneLength(str string, params ...string) bool func SafeFileName(str string) string +func SetFieldsRequiredByDefault(value bool) func Sign(value float64) float64 +func StringLength(str string, params ...string) bool +func StringMatches(s string, params ...string) bool func StripLow(str string, keepNewLines bool) string func ToBoolean(str string) (bool, error) func ToFloat(str string) (float64, error) @@ -190,10 +207,12 @@ func UnderscoreToCamelCase(s string) string func ValidateStruct(s interface{}) (bool, error) func WhiteList(str, chars string) string type ConditionIterator +type CustomTypeValidator type Error func (e Error) Error() string type Errors func (es Errors) Error() string +func (es Errors) Errors() []error type ISO3166Entry type Iterator type ParamValidator @@ -253,59 +272,66 @@ For completely custom validators (interface-based), see below. Here is a list of available validators for struct fields (validator - used function): ```go -"alpha": IsAlpha, -"alphanum": IsAlphanumeric, -"ascii": IsASCII, -"base64": IsBase64, -"creditcard": IsCreditCard, -"datauri": IsDataURI, -"dialstring": IsDialString, -"dns": IsDNSName, -"email": IsEmail, -"float": IsFloat, -"fullwidth": IsFullWidth, -"halfwidth": IsHalfWidth, -"hexadecimal": IsHexadecimal, -"hexcolor": IsHexcolor, -"host": IsHost, -"int": IsInt, -"ip": IsIP, -"ipv4": IsIPv4, -"ipv6": IsIPv6, -"isbn10": IsISBN10, -"isbn13": IsISBN13, -"json": IsJSON, -"latitude": IsLatitude, -"longitude": IsLongitude, -"lowercase": IsLowerCase, -"mac": IsMAC, -"multibyte": IsMultibyte, -"null": IsNull, -"numeric": IsNumeric, -"port": IsPort, -"printableascii": IsPrintableASCII, -"requri": IsRequestURI, -"requrl": IsRequestURL, -"rgbcolor": IsRGBcolor, -"ssn": IsSSN, -"semver": IsSemver, -"uppercase": IsUpperCase, -"url": IsURL, -"utfdigit": IsUTFDigit, -"utfletter": IsUTFLetter, -"utfletternum": IsUTFLetterNumeric, -"utfnumeric": IsUTFNumeric, -"uuid": IsUUID, -"uuidv3": IsUUIDv3, -"uuidv4": IsUUIDv4, -"uuidv5": IsUUIDv5, -"variablewidth": IsVariableWidth, +"email": IsEmail, +"url": IsURL, +"dialstring": IsDialString, +"requrl": IsRequestURL, +"requri": IsRequestURI, +"alpha": IsAlpha, +"utfletter": IsUTFLetter, +"alphanum": IsAlphanumeric, +"utfletternum": IsUTFLetterNumeric, +"numeric": IsNumeric, +"utfnumeric": IsUTFNumeric, +"utfdigit": IsUTFDigit, +"hexadecimal": IsHexadecimal, +"hexcolor": IsHexcolor, +"rgbcolor": IsRGBcolor, +"lowercase": IsLowerCase, +"uppercase": IsUpperCase, +"int": IsInt, +"float": IsFloat, +"null": IsNull, +"uuid": IsUUID, +"uuidv3": IsUUIDv3, +"uuidv4": IsUUIDv4, +"uuidv5": IsUUIDv5, +"creditcard": IsCreditCard, +"isbn10": IsISBN10, +"isbn13": IsISBN13, +"json": IsJSON, +"multibyte": IsMultibyte, +"ascii": IsASCII, +"printableascii": IsPrintableASCII, +"fullwidth": IsFullWidth, +"halfwidth": IsHalfWidth, +"variablewidth": IsVariableWidth, +"base64": IsBase64, +"datauri": IsDataURI, +"ip": IsIP, +"port": IsPort, +"ipv4": IsIPv4, +"ipv6": IsIPv6, +"dns": IsDNSName, +"host": IsHost, +"mac": IsMAC, +"latitude": IsLatitude, +"longitude": IsLongitude, +"ssn": IsSSN, +"semver": IsSemver, +"rfc3339": IsRFC3339, +"rfc3339WithoutZone": IsRFC3339WithoutZone, +"ISO3166Alpha2": IsISO3166Alpha2, +"ISO3166Alpha3": IsISO3166Alpha3, ``` Validators with parameters ```go +"range(min|max)": Range, "length(min|max)": ByteLength, +"runelength(min|max)": RuneLength, "matches(pattern)": StringMatches, +"in(string1|string2|...|stringN)": IsIn, ``` And here is small example of usage: @@ -382,12 +408,50 @@ govalidator.CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator })) ``` +###### Custom error messages +Custom error messages are supported via annotations by adding the `~` separator - here's an example of how to use it: +```go +type Ticket struct { + Id int64 `json:"id"` + FirstName string `json:"firstname" valid:"required~First name is blank"` +} +``` + #### Notes Documentation is available here: [godoc.org](https://godoc.org/github.com/asaskevich/govalidator). Full information about code coverage is also available here: [govalidator on gocover.io](http://gocover.io/github.com/asaskevich/govalidator). #### Support -If you do have a contribution for the package feel free to put up a Pull Request or open Issue. +If you do have a contribution to the package, feel free to create a Pull Request or an Issue. + +#### What to contribute +If you don't know what to do, there are some features and functions that need to be done + +- [ ] Refactor code +- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check +- [ ] Create actual list of contributors and projects that currently using this package +- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues) +- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions) +- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new +- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc +- [ ] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224) +- [ ] Implement fuzzing testing +- [ ] Implement some struct/map/array utilities +- [ ] Implement map/array validation +- [ ] Implement benchmarking +- [ ] Implement batch of examples +- [ ] Look at forks for new features and fixes + +#### Advice +Feel free to create what you want, but keep in mind when you implement new features: +- Code must be clear and readable, names of variables/constants clearly describes what they are doing +- Public functions must be documented and described in source file and added to README.md to the list of available functions +- There are must be unit-tests for any new functions and improvements + +## Credits +### Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. #### Special thanks to [contributors](https://github.com/asaskevich/govalidator/graphs/contributors) * [Daniel Lohse](https://github.com/annismckenzie) @@ -399,3 +463,34 @@ If you do have a contribution for the package feel free to put up a Pull Request * [Nathan Davies](https://github.com/nathj07) * [Matt Sanford](https://github.com/mzsanford) * [Simon ccl1115](https://github.com/ccl1115) + + + + +### Backers + +Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/govalidator#backer)] + + + + +### Sponsors + +Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/govalidator#sponsor)] + + + + + + + + + + + + + + + +## License +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_large) \ No newline at end of file diff --git a/vendor/github.com/asaskevich/govalidator/converter.go b/vendor/github.com/asaskevich/govalidator/converter.go index 737a1f1799be9..cf1e5d569ba01 100644 --- a/vendor/github.com/asaskevich/govalidator/converter.go +++ b/vendor/github.com/asaskevich/govalidator/converter.go @@ -3,6 +3,7 @@ package govalidator import ( "encoding/json" "fmt" + "reflect" "strconv" ) @@ -30,20 +31,34 @@ func ToFloat(str string) (float64, error) { return res, err } -// ToInt convert the input string to an integer, or 0 if the input is not an integer. -func ToInt(str string) (int64, error) { - res, err := strconv.ParseInt(str, 0, 64) - if err != nil { +// ToInt convert the input string or any int type to an integer type 64, or 0 if the input is not an integer. +func ToInt(value interface{}) (res int64, err error) { + val := reflect.ValueOf(value) + + switch value.(type) { + case int, int8, int16, int32, int64: + res = val.Int() + case uint, uint8, uint16, uint32, uint64: + res = int64(val.Uint()) + case string: + if IsInt(val.String()) { + res, err = strconv.ParseInt(val.String(), 0, 64) + if err != nil { + res = 0 + } + } else { + err = fmt.Errorf("math: square root of negative number %g", value) + res = 0 + } + default: + err = fmt.Errorf("math: square root of negative number %g", value) res = 0 } - return res, err + + return } // ToBoolean convert the input string to a boolean. func ToBoolean(str string) (bool, error) { - res, err := strconv.ParseBool(str) - if err != nil { - res = false - } - return res, err + return strconv.ParseBool(str) } diff --git a/vendor/github.com/asaskevich/govalidator/error.go b/vendor/github.com/asaskevich/govalidator/error.go index 280b1c455d1c8..655b750cb8f6e 100644 --- a/vendor/github.com/asaskevich/govalidator/error.go +++ b/vendor/github.com/asaskevich/govalidator/error.go @@ -1,5 +1,7 @@ package govalidator +import "strings" + // Errors is an array of multiple errors and conforms to the error interface. type Errors []error @@ -9,11 +11,11 @@ func (es Errors) Errors() []error { } func (es Errors) Error() string { - var err string + var errs []string for _, e := range es { - err += e.Error() + ";" + errs = append(errs, e.Error()) } - return err + return strings.Join(errs, ";") } // Error encapsulates a name, an error and whether there's a custom error message or not. @@ -21,11 +23,21 @@ type Error struct { Name string Err error CustomErrorMessageExists bool + + // Validator indicates the name of the validator that failed + Validator string + Path []string } func (e Error) Error() string { if e.CustomErrorMessageExists { return e.Err.Error() } - return e.Name + ": " + e.Err.Error() + + errName := e.Name + if len(e.Path) > 0 { + errName = strings.Join(append(e.Path, e.Name), ".") + } + + return errName + ": " + e.Err.Error() } diff --git a/vendor/github.com/asaskevich/govalidator/numerics.go b/vendor/github.com/asaskevich/govalidator/numerics.go index 737cd47ca690f..7e6c652e140c6 100644 --- a/vendor/github.com/asaskevich/govalidator/numerics.go +++ b/vendor/github.com/asaskevich/govalidator/numerics.go @@ -1,10 +1,13 @@ package govalidator -import "math" +import ( + "math" + "reflect" +) // Abs returns absolute value of number func Abs(value float64) float64 { - return value * Sign(value) + return math.Abs(value) } // Sign returns signum of number: 1 in case of value > 0, -1 in case of value < 0, 0 otherwise @@ -39,16 +42,53 @@ func IsNonPositive(value float64) bool { } // InRange returns true if value lies between left and right border -func InRange(value, left, right float64) bool { +func InRangeInt(value, left, right interface{}) bool { + value64, _ := ToInt(value) + left64, _ := ToInt(left) + right64, _ := ToInt(right) + if left64 > right64 { + left64, right64 = right64, left64 + } + return value64 >= left64 && value64 <= right64 +} + +// InRange returns true if value lies between left and right border +func InRangeFloat32(value, left, right float32) bool { if left > right { left, right = right, left } return value >= left && value <= right } +// InRange returns true if value lies between left and right border +func InRangeFloat64(value, left, right float64) bool { + if left > right { + left, right = right, left + } + return value >= left && value <= right +} + +// InRange returns true if value lies between left and right border, generic type to handle int, float32 or float64, all types must the same type +func InRange(value interface{}, left interface{}, right interface{}) bool { + + reflectValue := reflect.TypeOf(value).Kind() + reflectLeft := reflect.TypeOf(left).Kind() + reflectRight := reflect.TypeOf(right).Kind() + + if reflectValue == reflect.Int && reflectLeft == reflect.Int && reflectRight == reflect.Int { + return InRangeInt(value.(int), left.(int), right.(int)) + } else if reflectValue == reflect.Float32 && reflectLeft == reflect.Float32 && reflectRight == reflect.Float32 { + return InRangeFloat32(value.(float32), left.(float32), right.(float32)) + } else if reflectValue == reflect.Float64 && reflectLeft == reflect.Float64 && reflectRight == reflect.Float64 { + return InRangeFloat64(value.(float64), left.(float64), right.(float64)) + } else { + return false + } +} + // IsWhole returns true if value is whole number func IsWhole(value float64) bool { - return Abs(math.Remainder(value, 1)) == 0 + return math.Remainder(value, 1) == 0 } // IsNatural returns true if value is natural number (positive and whole) diff --git a/vendor/github.com/asaskevich/govalidator/patterns.go b/vendor/github.com/asaskevich/govalidator/patterns.go index 8761224cd346f..61a05d438e185 100644 --- a/vendor/github.com/asaskevich/govalidator/patterns.go +++ b/vendor/github.com/asaskevich/govalidator/patterns.go @@ -4,38 +4,49 @@ import "regexp" // Basic regular expressions for validating strings const ( - Email string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" - CreditCard string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$" - ISBN10 string = "^(?:[0-9]{9}X|[0-9]{10})$" - ISBN13 string = "^(?:[0-9]{13})$" - UUID3 string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$" - UUID4 string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - UUID5 string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - UUID string = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" - Alpha string = "^[a-zA-Z]+$" - Alphanumeric string = "^[a-zA-Z0-9]+$" - Numeric string = "^[-+]?[0-9]+$" - Int string = "^(?:[-+]?(?:0|[1-9][0-9]*))$" - Float string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$" - Hexadecimal string = "^[0-9a-fA-F]+$" - Hexcolor string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" - RGBcolor string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$" - ASCII string = "^[\x00-\x7F]+$" - Multibyte string = "[^\x00-\x7F]" - FullWidth string = "[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]" - HalfWidth string = "[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]" - Base64 string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" - PrintableASCII string = "^[\x20-\x7E]+$" - DataURI string = "^data:.+\\/(.+);base64$" - Latitude string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" - Longitude string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" - DNSName string = `^([a-zA-Z0-9]{1}[a-zA-Z0-9_-]{1,62}){1}(\.[a-zA-Z0-9]{1}[a-zA-Z0-9_-]{1,62})*$` - URL string = `^((ftp|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]([a-zA-Z0-9-]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$` - SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$` - WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$` - UnixPath string = `^((?:\/[a-zA-Z0-9\.\:]+(?:_[a-zA-Z0-9\:\.]+)*(?:\-[\:a-zA-Z0-9\.]+)*)+\/?)$` - Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$" - tagName string = "valid" + Email string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" + CreditCard string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$" + ISBN10 string = "^(?:[0-9]{9}X|[0-9]{10})$" + ISBN13 string = "^(?:[0-9]{13})$" + UUID3 string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$" + UUID4 string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + UUID5 string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + UUID string = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" + Alpha string = "^[a-zA-Z]+$" + Alphanumeric string = "^[a-zA-Z0-9]+$" + Numeric string = "^[0-9]+$" + Int string = "^(?:[-+]?(?:0|[1-9][0-9]*))$" + Float string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$" + Hexadecimal string = "^[0-9a-fA-F]+$" + Hexcolor string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" + RGBcolor string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$" + ASCII string = "^[\x00-\x7F]+$" + Multibyte string = "[^\x00-\x7F]" + FullWidth string = "[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]" + HalfWidth string = "[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]" + Base64 string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" + PrintableASCII string = "^[\x20-\x7E]+$" + DataURI string = "^data:.+\\/(.+);base64$" + Latitude string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" + Longitude string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" + DNSName string = `^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$` + IP string = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))` + URLSchema string = `((ftp|tcp|udp|wss?|https?):\/\/)` + URLUsername string = `(\S+(:\S*)?@)` + URLPath string = `((\/|\?|#)[^\s]*)` + URLPort string = `(:(\d{1,5}))` + URLIP string = `([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))` + URLSubdomain string = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))` + URL string = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$` + SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$` + WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$` + UnixPath string = `^(/[^/\x00]*)+/?$` + Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$" + tagName string = "valid" + hasLowerCase string = ".*[[:lower:]]" + hasUpperCase string = ".*[[:upper:]]" + hasWhitespace string = ".*[[:space:]]" + hasWhitespaceOnly string = "^[[:space:]]+$" ) // Used by IsFilePath func @@ -49,35 +60,42 @@ const ( ) var ( - rxEmail = regexp.MustCompile(Email) - rxCreditCard = regexp.MustCompile(CreditCard) - rxISBN10 = regexp.MustCompile(ISBN10) - rxISBN13 = regexp.MustCompile(ISBN13) - rxUUID3 = regexp.MustCompile(UUID3) - rxUUID4 = regexp.MustCompile(UUID4) - rxUUID5 = regexp.MustCompile(UUID5) - rxUUID = regexp.MustCompile(UUID) - rxAlpha = regexp.MustCompile(Alpha) - rxAlphanumeric = regexp.MustCompile(Alphanumeric) - rxNumeric = regexp.MustCompile(Numeric) - rxInt = regexp.MustCompile(Int) - rxFloat = regexp.MustCompile(Float) - rxHexadecimal = regexp.MustCompile(Hexadecimal) - rxHexcolor = regexp.MustCompile(Hexcolor) - rxRGBcolor = regexp.MustCompile(RGBcolor) - rxASCII = regexp.MustCompile(ASCII) - rxPrintableASCII = regexp.MustCompile(PrintableASCII) - rxMultibyte = regexp.MustCompile(Multibyte) - rxFullWidth = regexp.MustCompile(FullWidth) - rxHalfWidth = regexp.MustCompile(HalfWidth) - rxBase64 = regexp.MustCompile(Base64) - rxDataURI = regexp.MustCompile(DataURI) - rxLatitude = regexp.MustCompile(Latitude) - rxLongitude = regexp.MustCompile(Longitude) - rxDNSName = regexp.MustCompile(DNSName) - rxURL = regexp.MustCompile(URL) - rxSSN = regexp.MustCompile(SSN) - rxWinPath = regexp.MustCompile(WinPath) - rxUnixPath = regexp.MustCompile(UnixPath) - rxSemver = regexp.MustCompile(Semver) + userRegexp = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+$") + hostRegexp = regexp.MustCompile("^[^\\s]+\\.[^\\s]+$") + userDotRegexp = regexp.MustCompile("(^[.]{1})|([.]{1}$)|([.]{2,})") + rxEmail = regexp.MustCompile(Email) + rxCreditCard = regexp.MustCompile(CreditCard) + rxISBN10 = regexp.MustCompile(ISBN10) + rxISBN13 = regexp.MustCompile(ISBN13) + rxUUID3 = regexp.MustCompile(UUID3) + rxUUID4 = regexp.MustCompile(UUID4) + rxUUID5 = regexp.MustCompile(UUID5) + rxUUID = regexp.MustCompile(UUID) + rxAlpha = regexp.MustCompile(Alpha) + rxAlphanumeric = regexp.MustCompile(Alphanumeric) + rxNumeric = regexp.MustCompile(Numeric) + rxInt = regexp.MustCompile(Int) + rxFloat = regexp.MustCompile(Float) + rxHexadecimal = regexp.MustCompile(Hexadecimal) + rxHexcolor = regexp.MustCompile(Hexcolor) + rxRGBcolor = regexp.MustCompile(RGBcolor) + rxASCII = regexp.MustCompile(ASCII) + rxPrintableASCII = regexp.MustCompile(PrintableASCII) + rxMultibyte = regexp.MustCompile(Multibyte) + rxFullWidth = regexp.MustCompile(FullWidth) + rxHalfWidth = regexp.MustCompile(HalfWidth) + rxBase64 = regexp.MustCompile(Base64) + rxDataURI = regexp.MustCompile(DataURI) + rxLatitude = regexp.MustCompile(Latitude) + rxLongitude = regexp.MustCompile(Longitude) + rxDNSName = regexp.MustCompile(DNSName) + rxURL = regexp.MustCompile(URL) + rxSSN = regexp.MustCompile(SSN) + rxWinPath = regexp.MustCompile(WinPath) + rxUnixPath = regexp.MustCompile(UnixPath) + rxSemver = regexp.MustCompile(Semver) + rxHasLowerCase = regexp.MustCompile(hasLowerCase) + rxHasUpperCase = regexp.MustCompile(hasUpperCase) + rxHasWhitespace = regexp.MustCompile(hasWhitespace) + rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly) ) diff --git a/vendor/github.com/asaskevich/govalidator/types.go b/vendor/github.com/asaskevich/govalidator/types.go index b7156127623b3..4f7e9274ade0c 100644 --- a/vendor/github.com/asaskevich/govalidator/types.go +++ b/vendor/github.com/asaskevich/govalidator/types.go @@ -3,6 +3,7 @@ package govalidator import ( "reflect" "regexp" + "sort" "sync" ) @@ -15,7 +16,26 @@ type CustomTypeValidator func(i interface{}, o interface{}) bool // ParamValidator is a wrapper for validator functions that accepts additional parameters. type ParamValidator func(str string, params ...string) bool -type tagOptionsMap map[string]string +type tagOptionsMap map[string]tagOption + +func (t tagOptionsMap) orderedKeys() []string { + var keys []string + for k := range t { + keys = append(keys, k) + } + + sort.Slice(keys, func(a, b int) bool { + return t[keys[a]].order < t[keys[b]].order + }) + + return keys +} + +type tagOption struct { + name string + customErrorMessage string + order int +} // UnsupportedTypeError is a wrapper for reflect.Type type UnsupportedTypeError struct { @@ -29,15 +49,23 @@ type stringValues []reflect.Value // ParamTagMap is a map of functions accept variants parameters var ParamTagMap = map[string]ParamValidator{ "length": ByteLength, + "range": Range, + "runelength": RuneLength, "stringlength": StringLength, "matches": StringMatches, + "in": isInRaw, + "rsapub": IsRsaPub, } // ParamTagRegexMap maps param tags to their respective regexes. var ParamTagRegexMap = map[string]*regexp.Regexp{ + "range": regexp.MustCompile("^range\\((\\d+)\\|(\\d+)\\)$"), "length": regexp.MustCompile("^length\\((\\d+)\\|(\\d+)\\)$"), + "runelength": regexp.MustCompile("^runelength\\((\\d+)\\|(\\d+)\\)$"), "stringlength": regexp.MustCompile("^stringlength\\((\\d+)\\|(\\d+)\\)$"), - "matches": regexp.MustCompile(`matches\(([^)]+)\)`), + "in": regexp.MustCompile(`^in\((.*)\)`), + "matches": regexp.MustCompile(`^matches\((.+)\)$`), + "rsapub": regexp.MustCompile("^rsapub\\((\\d+)\\)$"), } type customTypeTagMap struct { @@ -66,53 +94,58 @@ var CustomTypeTagMap = &customTypeTagMap{validators: make(map[string]CustomTypeV // TagMap is a map of functions, that can be used as tags for ValidateStruct function. var TagMap = map[string]Validator{ - "email": IsEmail, - "url": IsURL, - "dialstring": IsDialString, - "requrl": IsRequestURL, - "requri": IsRequestURI, - "alpha": IsAlpha, - "utfletter": IsUTFLetter, - "alphanum": IsAlphanumeric, - "utfletternum": IsUTFLetterNumeric, - "numeric": IsNumeric, - "utfnumeric": IsUTFNumeric, - "utfdigit": IsUTFDigit, - "hexadecimal": IsHexadecimal, - "hexcolor": IsHexcolor, - "rgbcolor": IsRGBcolor, - "lowercase": IsLowerCase, - "uppercase": IsUpperCase, - "int": IsInt, - "float": IsFloat, - "null": IsNull, - "uuid": IsUUID, - "uuidv3": IsUUIDv3, - "uuidv4": IsUUIDv4, - "uuidv5": IsUUIDv5, - "creditcard": IsCreditCard, - "isbn10": IsISBN10, - "isbn13": IsISBN13, - "json": IsJSON, - "multibyte": IsMultibyte, - "ascii": IsASCII, - "printableascii": IsPrintableASCII, - "fullwidth": IsFullWidth, - "halfwidth": IsHalfWidth, - "variablewidth": IsVariableWidth, - "base64": IsBase64, - "datauri": IsDataURI, - "ip": IsIP, - "port": IsPort, - "ipv4": IsIPv4, - "ipv6": IsIPv6, - "dns": IsDNSName, - "host": IsHost, - "mac": IsMAC, - "latitude": IsLatitude, - "longitude": IsLongitude, - "ssn": IsSSN, - "semver": IsSemver, + "email": IsEmail, + "url": IsURL, + "dialstring": IsDialString, + "requrl": IsRequestURL, + "requri": IsRequestURI, + "alpha": IsAlpha, + "utfletter": IsUTFLetter, + "alphanum": IsAlphanumeric, + "utfletternum": IsUTFLetterNumeric, + "numeric": IsNumeric, + "utfnumeric": IsUTFNumeric, + "utfdigit": IsUTFDigit, + "hexadecimal": IsHexadecimal, + "hexcolor": IsHexcolor, + "rgbcolor": IsRGBcolor, + "lowercase": IsLowerCase, + "uppercase": IsUpperCase, + "int": IsInt, + "float": IsFloat, + "null": IsNull, + "uuid": IsUUID, + "uuidv3": IsUUIDv3, + "uuidv4": IsUUIDv4, + "uuidv5": IsUUIDv5, + "creditcard": IsCreditCard, + "isbn10": IsISBN10, + "isbn13": IsISBN13, + "json": IsJSON, + "multibyte": IsMultibyte, + "ascii": IsASCII, + "printableascii": IsPrintableASCII, + "fullwidth": IsFullWidth, + "halfwidth": IsHalfWidth, + "variablewidth": IsVariableWidth, + "base64": IsBase64, + "datauri": IsDataURI, + "ip": IsIP, + "port": IsPort, + "ipv4": IsIPv4, + "ipv6": IsIPv6, + "dns": IsDNSName, + "host": IsHost, + "mac": IsMAC, + "latitude": IsLatitude, + "longitude": IsLongitude, + "ssn": IsSSN, + "semver": IsSemver, + "rfc3339": IsRFC3339, + "rfc3339WithoutZone": IsRFC3339WithoutZone, + "ISO3166Alpha2": IsISO3166Alpha2, + "ISO3166Alpha3": IsISO3166Alpha3, + "ISO4217": IsISO4217, } // ISO3166Entry stores country codes @@ -376,3 +409,228 @@ var ISO3166List = []ISO3166Entry{ {"Yemen", "Yémen (le)", "YE", "YEM", "887"}, {"Zambia", "Zambie (la)", "ZM", "ZMB", "894"}, } + +// ISO4217List is the list of ISO currency codes +var ISO4217List = []string{ + "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", + "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYN", "BZD", + "CAD", "CDF", "CHE", "CHF", "CHW", "CLF", "CLP", "CNY", "COP", "COU", "CRC", "CUC", "CUP", "CVE", "CZK", + "DJF", "DKK", "DOP", "DZD", + "EGP", "ERN", "ETB", "EUR", + "FJD", "FKP", + "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", + "HKD", "HNL", "HRK", "HTG", "HUF", + "IDR", "ILS", "INR", "IQD", "IRR", "ISK", + "JMD", "JOD", "JPY", + "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", + "LAK", "LBP", "LKR", "LRD", "LSL", "LYD", + "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MXV", "MYR", "MZN", + "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", + "OMR", + "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", + "QAR", + "RON", "RSD", "RUB", "RWF", + "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "SVC", "SYP", "SZL", + "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", + "UAH", "UGX", "USD", "USN", "UYI", "UYU", "UZS", + "VEF", "VND", "VUV", + "WST", + "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX", + "YER", + "ZAR", "ZMW", "ZWL", +} + +// ISO693Entry stores ISO language codes +type ISO693Entry struct { + Alpha3bCode string + Alpha2Code string + English string +} + +//ISO693List based on http://data.okfn.org/data/core/language-codes/r/language-codes-3b2.json +var ISO693List = []ISO693Entry{ + {Alpha3bCode: "aar", Alpha2Code: "aa", English: "Afar"}, + {Alpha3bCode: "abk", Alpha2Code: "ab", English: "Abkhazian"}, + {Alpha3bCode: "afr", Alpha2Code: "af", English: "Afrikaans"}, + {Alpha3bCode: "aka", Alpha2Code: "ak", English: "Akan"}, + {Alpha3bCode: "alb", Alpha2Code: "sq", English: "Albanian"}, + {Alpha3bCode: "amh", Alpha2Code: "am", English: "Amharic"}, + {Alpha3bCode: "ara", Alpha2Code: "ar", English: "Arabic"}, + {Alpha3bCode: "arg", Alpha2Code: "an", English: "Aragonese"}, + {Alpha3bCode: "arm", Alpha2Code: "hy", English: "Armenian"}, + {Alpha3bCode: "asm", Alpha2Code: "as", English: "Assamese"}, + {Alpha3bCode: "ava", Alpha2Code: "av", English: "Avaric"}, + {Alpha3bCode: "ave", Alpha2Code: "ae", English: "Avestan"}, + {Alpha3bCode: "aym", Alpha2Code: "ay", English: "Aymara"}, + {Alpha3bCode: "aze", Alpha2Code: "az", English: "Azerbaijani"}, + {Alpha3bCode: "bak", Alpha2Code: "ba", English: "Bashkir"}, + {Alpha3bCode: "bam", Alpha2Code: "bm", English: "Bambara"}, + {Alpha3bCode: "baq", Alpha2Code: "eu", English: "Basque"}, + {Alpha3bCode: "bel", Alpha2Code: "be", English: "Belarusian"}, + {Alpha3bCode: "ben", Alpha2Code: "bn", English: "Bengali"}, + {Alpha3bCode: "bih", Alpha2Code: "bh", English: "Bihari languages"}, + {Alpha3bCode: "bis", Alpha2Code: "bi", English: "Bislama"}, + {Alpha3bCode: "bos", Alpha2Code: "bs", English: "Bosnian"}, + {Alpha3bCode: "bre", Alpha2Code: "br", English: "Breton"}, + {Alpha3bCode: "bul", Alpha2Code: "bg", English: "Bulgarian"}, + {Alpha3bCode: "bur", Alpha2Code: "my", English: "Burmese"}, + {Alpha3bCode: "cat", Alpha2Code: "ca", English: "Catalan; Valencian"}, + {Alpha3bCode: "cha", Alpha2Code: "ch", English: "Chamorro"}, + {Alpha3bCode: "che", Alpha2Code: "ce", English: "Chechen"}, + {Alpha3bCode: "chi", Alpha2Code: "zh", English: "Chinese"}, + {Alpha3bCode: "chu", Alpha2Code: "cu", English: "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic"}, + {Alpha3bCode: "chv", Alpha2Code: "cv", English: "Chuvash"}, + {Alpha3bCode: "cor", Alpha2Code: "kw", English: "Cornish"}, + {Alpha3bCode: "cos", Alpha2Code: "co", English: "Corsican"}, + {Alpha3bCode: "cre", Alpha2Code: "cr", English: "Cree"}, + {Alpha3bCode: "cze", Alpha2Code: "cs", English: "Czech"}, + {Alpha3bCode: "dan", Alpha2Code: "da", English: "Danish"}, + {Alpha3bCode: "div", Alpha2Code: "dv", English: "Divehi; Dhivehi; Maldivian"}, + {Alpha3bCode: "dut", Alpha2Code: "nl", English: "Dutch; Flemish"}, + {Alpha3bCode: "dzo", Alpha2Code: "dz", English: "Dzongkha"}, + {Alpha3bCode: "eng", Alpha2Code: "en", English: "English"}, + {Alpha3bCode: "epo", Alpha2Code: "eo", English: "Esperanto"}, + {Alpha3bCode: "est", Alpha2Code: "et", English: "Estonian"}, + {Alpha3bCode: "ewe", Alpha2Code: "ee", English: "Ewe"}, + {Alpha3bCode: "fao", Alpha2Code: "fo", English: "Faroese"}, + {Alpha3bCode: "fij", Alpha2Code: "fj", English: "Fijian"}, + {Alpha3bCode: "fin", Alpha2Code: "fi", English: "Finnish"}, + {Alpha3bCode: "fre", Alpha2Code: "fr", English: "French"}, + {Alpha3bCode: "fry", Alpha2Code: "fy", English: "Western Frisian"}, + {Alpha3bCode: "ful", Alpha2Code: "ff", English: "Fulah"}, + {Alpha3bCode: "geo", Alpha2Code: "ka", English: "Georgian"}, + {Alpha3bCode: "ger", Alpha2Code: "de", English: "German"}, + {Alpha3bCode: "gla", Alpha2Code: "gd", English: "Gaelic; Scottish Gaelic"}, + {Alpha3bCode: "gle", Alpha2Code: "ga", English: "Irish"}, + {Alpha3bCode: "glg", Alpha2Code: "gl", English: "Galician"}, + {Alpha3bCode: "glv", Alpha2Code: "gv", English: "Manx"}, + {Alpha3bCode: "gre", Alpha2Code: "el", English: "Greek, Modern (1453-)"}, + {Alpha3bCode: "grn", Alpha2Code: "gn", English: "Guarani"}, + {Alpha3bCode: "guj", Alpha2Code: "gu", English: "Gujarati"}, + {Alpha3bCode: "hat", Alpha2Code: "ht", English: "Haitian; Haitian Creole"}, + {Alpha3bCode: "hau", Alpha2Code: "ha", English: "Hausa"}, + {Alpha3bCode: "heb", Alpha2Code: "he", English: "Hebrew"}, + {Alpha3bCode: "her", Alpha2Code: "hz", English: "Herero"}, + {Alpha3bCode: "hin", Alpha2Code: "hi", English: "Hindi"}, + {Alpha3bCode: "hmo", Alpha2Code: "ho", English: "Hiri Motu"}, + {Alpha3bCode: "hrv", Alpha2Code: "hr", English: "Croatian"}, + {Alpha3bCode: "hun", Alpha2Code: "hu", English: "Hungarian"}, + {Alpha3bCode: "ibo", Alpha2Code: "ig", English: "Igbo"}, + {Alpha3bCode: "ice", Alpha2Code: "is", English: "Icelandic"}, + {Alpha3bCode: "ido", Alpha2Code: "io", English: "Ido"}, + {Alpha3bCode: "iii", Alpha2Code: "ii", English: "Sichuan Yi; Nuosu"}, + {Alpha3bCode: "iku", Alpha2Code: "iu", English: "Inuktitut"}, + {Alpha3bCode: "ile", Alpha2Code: "ie", English: "Interlingue; Occidental"}, + {Alpha3bCode: "ina", Alpha2Code: "ia", English: "Interlingua (International Auxiliary Language Association)"}, + {Alpha3bCode: "ind", Alpha2Code: "id", English: "Indonesian"}, + {Alpha3bCode: "ipk", Alpha2Code: "ik", English: "Inupiaq"}, + {Alpha3bCode: "ita", Alpha2Code: "it", English: "Italian"}, + {Alpha3bCode: "jav", Alpha2Code: "jv", English: "Javanese"}, + {Alpha3bCode: "jpn", Alpha2Code: "ja", English: "Japanese"}, + {Alpha3bCode: "kal", Alpha2Code: "kl", English: "Kalaallisut; Greenlandic"}, + {Alpha3bCode: "kan", Alpha2Code: "kn", English: "Kannada"}, + {Alpha3bCode: "kas", Alpha2Code: "ks", English: "Kashmiri"}, + {Alpha3bCode: "kau", Alpha2Code: "kr", English: "Kanuri"}, + {Alpha3bCode: "kaz", Alpha2Code: "kk", English: "Kazakh"}, + {Alpha3bCode: "khm", Alpha2Code: "km", English: "Central Khmer"}, + {Alpha3bCode: "kik", Alpha2Code: "ki", English: "Kikuyu; Gikuyu"}, + {Alpha3bCode: "kin", Alpha2Code: "rw", English: "Kinyarwanda"}, + {Alpha3bCode: "kir", Alpha2Code: "ky", English: "Kirghiz; Kyrgyz"}, + {Alpha3bCode: "kom", Alpha2Code: "kv", English: "Komi"}, + {Alpha3bCode: "kon", Alpha2Code: "kg", English: "Kongo"}, + {Alpha3bCode: "kor", Alpha2Code: "ko", English: "Korean"}, + {Alpha3bCode: "kua", Alpha2Code: "kj", English: "Kuanyama; Kwanyama"}, + {Alpha3bCode: "kur", Alpha2Code: "ku", English: "Kurdish"}, + {Alpha3bCode: "lao", Alpha2Code: "lo", English: "Lao"}, + {Alpha3bCode: "lat", Alpha2Code: "la", English: "Latin"}, + {Alpha3bCode: "lav", Alpha2Code: "lv", English: "Latvian"}, + {Alpha3bCode: "lim", Alpha2Code: "li", English: "Limburgan; Limburger; Limburgish"}, + {Alpha3bCode: "lin", Alpha2Code: "ln", English: "Lingala"}, + {Alpha3bCode: "lit", Alpha2Code: "lt", English: "Lithuanian"}, + {Alpha3bCode: "ltz", Alpha2Code: "lb", English: "Luxembourgish; Letzeburgesch"}, + {Alpha3bCode: "lub", Alpha2Code: "lu", English: "Luba-Katanga"}, + {Alpha3bCode: "lug", Alpha2Code: "lg", English: "Ganda"}, + {Alpha3bCode: "mac", Alpha2Code: "mk", English: "Macedonian"}, + {Alpha3bCode: "mah", Alpha2Code: "mh", English: "Marshallese"}, + {Alpha3bCode: "mal", Alpha2Code: "ml", English: "Malayalam"}, + {Alpha3bCode: "mao", Alpha2Code: "mi", English: "Maori"}, + {Alpha3bCode: "mar", Alpha2Code: "mr", English: "Marathi"}, + {Alpha3bCode: "may", Alpha2Code: "ms", English: "Malay"}, + {Alpha3bCode: "mlg", Alpha2Code: "mg", English: "Malagasy"}, + {Alpha3bCode: "mlt", Alpha2Code: "mt", English: "Maltese"}, + {Alpha3bCode: "mon", Alpha2Code: "mn", English: "Mongolian"}, + {Alpha3bCode: "nau", Alpha2Code: "na", English: "Nauru"}, + {Alpha3bCode: "nav", Alpha2Code: "nv", English: "Navajo; Navaho"}, + {Alpha3bCode: "nbl", Alpha2Code: "nr", English: "Ndebele, South; South Ndebele"}, + {Alpha3bCode: "nde", Alpha2Code: "nd", English: "Ndebele, North; North Ndebele"}, + {Alpha3bCode: "ndo", Alpha2Code: "ng", English: "Ndonga"}, + {Alpha3bCode: "nep", Alpha2Code: "ne", English: "Nepali"}, + {Alpha3bCode: "nno", Alpha2Code: "nn", English: "Norwegian Nynorsk; Nynorsk, Norwegian"}, + {Alpha3bCode: "nob", Alpha2Code: "nb", English: "Bokmål, Norwegian; Norwegian Bokmål"}, + {Alpha3bCode: "nor", Alpha2Code: "no", English: "Norwegian"}, + {Alpha3bCode: "nya", Alpha2Code: "ny", English: "Chichewa; Chewa; Nyanja"}, + {Alpha3bCode: "oci", Alpha2Code: "oc", English: "Occitan (post 1500); Provençal"}, + {Alpha3bCode: "oji", Alpha2Code: "oj", English: "Ojibwa"}, + {Alpha3bCode: "ori", Alpha2Code: "or", English: "Oriya"}, + {Alpha3bCode: "orm", Alpha2Code: "om", English: "Oromo"}, + {Alpha3bCode: "oss", Alpha2Code: "os", English: "Ossetian; Ossetic"}, + {Alpha3bCode: "pan", Alpha2Code: "pa", English: "Panjabi; Punjabi"}, + {Alpha3bCode: "per", Alpha2Code: "fa", English: "Persian"}, + {Alpha3bCode: "pli", Alpha2Code: "pi", English: "Pali"}, + {Alpha3bCode: "pol", Alpha2Code: "pl", English: "Polish"}, + {Alpha3bCode: "por", Alpha2Code: "pt", English: "Portuguese"}, + {Alpha3bCode: "pus", Alpha2Code: "ps", English: "Pushto; Pashto"}, + {Alpha3bCode: "que", Alpha2Code: "qu", English: "Quechua"}, + {Alpha3bCode: "roh", Alpha2Code: "rm", English: "Romansh"}, + {Alpha3bCode: "rum", Alpha2Code: "ro", English: "Romanian; Moldavian; Moldovan"}, + {Alpha3bCode: "run", Alpha2Code: "rn", English: "Rundi"}, + {Alpha3bCode: "rus", Alpha2Code: "ru", English: "Russian"}, + {Alpha3bCode: "sag", Alpha2Code: "sg", English: "Sango"}, + {Alpha3bCode: "san", Alpha2Code: "sa", English: "Sanskrit"}, + {Alpha3bCode: "sin", Alpha2Code: "si", English: "Sinhala; Sinhalese"}, + {Alpha3bCode: "slo", Alpha2Code: "sk", English: "Slovak"}, + {Alpha3bCode: "slv", Alpha2Code: "sl", English: "Slovenian"}, + {Alpha3bCode: "sme", Alpha2Code: "se", English: "Northern Sami"}, + {Alpha3bCode: "smo", Alpha2Code: "sm", English: "Samoan"}, + {Alpha3bCode: "sna", Alpha2Code: "sn", English: "Shona"}, + {Alpha3bCode: "snd", Alpha2Code: "sd", English: "Sindhi"}, + {Alpha3bCode: "som", Alpha2Code: "so", English: "Somali"}, + {Alpha3bCode: "sot", Alpha2Code: "st", English: "Sotho, Southern"}, + {Alpha3bCode: "spa", Alpha2Code: "es", English: "Spanish; Castilian"}, + {Alpha3bCode: "srd", Alpha2Code: "sc", English: "Sardinian"}, + {Alpha3bCode: "srp", Alpha2Code: "sr", English: "Serbian"}, + {Alpha3bCode: "ssw", Alpha2Code: "ss", English: "Swati"}, + {Alpha3bCode: "sun", Alpha2Code: "su", English: "Sundanese"}, + {Alpha3bCode: "swa", Alpha2Code: "sw", English: "Swahili"}, + {Alpha3bCode: "swe", Alpha2Code: "sv", English: "Swedish"}, + {Alpha3bCode: "tah", Alpha2Code: "ty", English: "Tahitian"}, + {Alpha3bCode: "tam", Alpha2Code: "ta", English: "Tamil"}, + {Alpha3bCode: "tat", Alpha2Code: "tt", English: "Tatar"}, + {Alpha3bCode: "tel", Alpha2Code: "te", English: "Telugu"}, + {Alpha3bCode: "tgk", Alpha2Code: "tg", English: "Tajik"}, + {Alpha3bCode: "tgl", Alpha2Code: "tl", English: "Tagalog"}, + {Alpha3bCode: "tha", Alpha2Code: "th", English: "Thai"}, + {Alpha3bCode: "tib", Alpha2Code: "bo", English: "Tibetan"}, + {Alpha3bCode: "tir", Alpha2Code: "ti", English: "Tigrinya"}, + {Alpha3bCode: "ton", Alpha2Code: "to", English: "Tonga (Tonga Islands)"}, + {Alpha3bCode: "tsn", Alpha2Code: "tn", English: "Tswana"}, + {Alpha3bCode: "tso", Alpha2Code: "ts", English: "Tsonga"}, + {Alpha3bCode: "tuk", Alpha2Code: "tk", English: "Turkmen"}, + {Alpha3bCode: "tur", Alpha2Code: "tr", English: "Turkish"}, + {Alpha3bCode: "twi", Alpha2Code: "tw", English: "Twi"}, + {Alpha3bCode: "uig", Alpha2Code: "ug", English: "Uighur; Uyghur"}, + {Alpha3bCode: "ukr", Alpha2Code: "uk", English: "Ukrainian"}, + {Alpha3bCode: "urd", Alpha2Code: "ur", English: "Urdu"}, + {Alpha3bCode: "uzb", Alpha2Code: "uz", English: "Uzbek"}, + {Alpha3bCode: "ven", Alpha2Code: "ve", English: "Venda"}, + {Alpha3bCode: "vie", Alpha2Code: "vi", English: "Vietnamese"}, + {Alpha3bCode: "vol", Alpha2Code: "vo", English: "Volapük"}, + {Alpha3bCode: "wel", Alpha2Code: "cy", English: "Welsh"}, + {Alpha3bCode: "wln", Alpha2Code: "wa", English: "Walloon"}, + {Alpha3bCode: "wol", Alpha2Code: "wo", English: "Wolof"}, + {Alpha3bCode: "xho", Alpha2Code: "xh", English: "Xhosa"}, + {Alpha3bCode: "yid", Alpha2Code: "yi", English: "Yiddish"}, + {Alpha3bCode: "yor", Alpha2Code: "yo", English: "Yoruba"}, + {Alpha3bCode: "zha", Alpha2Code: "za", English: "Zhuang; Chuang"}, + {Alpha3bCode: "zul", Alpha2Code: "zu", English: "Zulu"}, +} diff --git a/vendor/github.com/asaskevich/govalidator/utils.go b/vendor/github.com/asaskevich/govalidator/utils.go index 200b9131defa2..a0b706a743ce2 100644 --- a/vendor/github.com/asaskevich/govalidator/utils.go +++ b/vendor/github.com/asaskevich/govalidator/utils.go @@ -4,10 +4,12 @@ import ( "errors" "fmt" "html" + "math" "path" "regexp" "strings" "unicode" + "unicode/utf8" ) // Contains check if the string contains the substring. @@ -25,27 +27,21 @@ func Matches(str, pattern string) bool { // LeftTrim trim characters from the left-side of the input. // If second argument is empty, it's will be remove leading spaces. func LeftTrim(str, chars string) string { - pattern := "" if chars == "" { - pattern = "^\\s+" - } else { - pattern = "^[" + chars + "]+" + return strings.TrimLeftFunc(str, unicode.IsSpace) } - r, _ := regexp.Compile(pattern) - return string(r.ReplaceAll([]byte(str), []byte(""))) + r, _ := regexp.Compile("^[" + chars + "]+") + return r.ReplaceAllString(str, "") } // RightTrim trim characters from the right-side of the input. // If second argument is empty, it's will be remove spaces. func RightTrim(str, chars string) string { - pattern := "" if chars == "" { - pattern = "\\s+$" - } else { - pattern = "[" + chars + "]+$" + return strings.TrimRightFunc(str, unicode.IsSpace) } - r, _ := regexp.Compile(pattern) - return string(r.ReplaceAll([]byte(str), []byte(""))) + r, _ := regexp.Compile("[" + chars + "]+$") + return r.ReplaceAllString(str, "") } // Trim trim characters from both sides of the input. @@ -58,14 +54,14 @@ func Trim(str, chars string) string { func WhiteList(str, chars string) string { pattern := "[^" + chars + "]+" r, _ := regexp.Compile(pattern) - return string(r.ReplaceAll([]byte(str), []byte(""))) + return r.ReplaceAllString(str, "") } // BlackList remove characters that appear in the blacklist. func BlackList(str, chars string) string { pattern := "[" + chars + "]+" r, _ := regexp.Compile(pattern) - return string(r.ReplaceAll([]byte(str), []byte(""))) + return r.ReplaceAllString(str, "") } // StripLow remove characters with a numerical value < 32 and 127, mostly control characters. @@ -83,7 +79,7 @@ func StripLow(str string, keepNewLines bool) string { // ReplacePattern replace regular expression pattern in string func ReplacePattern(str, pattern, replace string) string { r, _ := regexp.Compile(pattern) - return string(r.ReplaceAll([]byte(str), []byte(replace))) + return r.ReplaceAllString(str, replace) } // Escape replace <, >, & and " with HTML entities. @@ -112,7 +108,9 @@ func CamelCaseToUnderscore(str string) string { var output []rune var segment []rune for _, r := range str { - if !unicode.IsLower(r) { + + // not treat number as separate segment + if !unicode.IsLower(r) && string(r) != "_" && !unicode.IsNumber(r) { output = addSegment(output, segment) segment = nil } @@ -211,3 +209,62 @@ func Truncate(str string, length int, ending string) string { return str } + +// PadLeft pad left side of string if size of string is less then indicated pad length +func PadLeft(str string, padStr string, padLen int) string { + return buildPadStr(str, padStr, padLen, true, false) +} + +// PadRight pad right side of string if size of string is less then indicated pad length +func PadRight(str string, padStr string, padLen int) string { + return buildPadStr(str, padStr, padLen, false, true) +} + +// PadBoth pad sides of string if size of string is less then indicated pad length +func PadBoth(str string, padStr string, padLen int) string { + return buildPadStr(str, padStr, padLen, true, true) +} + +// PadString either left, right or both sides, not the padding string can be unicode and more then one +// character +func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string { + + // When padded length is less then the current string size + if padLen < utf8.RuneCountInString(str) { + return str + } + + padLen -= utf8.RuneCountInString(str) + + targetLen := padLen + + targetLenLeft := targetLen + targetLenRight := targetLen + if padLeft && padRight { + targetLenLeft = padLen / 2 + targetLenRight = padLen - targetLenLeft + } + + strToRepeatLen := utf8.RuneCountInString(padStr) + + repeatTimes := int(math.Ceil(float64(targetLen) / float64(strToRepeatLen))) + repeatedString := strings.Repeat(padStr, repeatTimes) + + leftSide := "" + if padLeft { + leftSide = repeatedString[0:targetLenLeft] + } + + rightSide := "" + if padRight { + rightSide = repeatedString[0:targetLenRight] + } + + return leftSide + str + rightSide +} + +// TruncatingErrorf removes extra args from fmt.Errorf if not formatted in the str object +func TruncatingErrorf(str string, args ...interface{}) error { + n := strings.Count(str, "%s") + return fmt.Errorf(str, args[:n]...) +} diff --git a/vendor/github.com/asaskevich/govalidator/validator.go b/vendor/github.com/asaskevich/govalidator/validator.go index a752624fc3b2e..b18bbcb4c99f8 100644 --- a/vendor/github.com/asaskevich/govalidator/validator.go +++ b/vendor/github.com/asaskevich/govalidator/validator.go @@ -2,8 +2,14 @@ package govalidator import ( + "bytes" + "crypto/rsa" + "crypto/x509" + "encoding/base64" "encoding/json" + "encoding/pem" "fmt" + "io/ioutil" "net" "net/url" "reflect" @@ -11,12 +17,22 @@ import ( "sort" "strconv" "strings" - + "time" "unicode" "unicode/utf8" ) -var fieldsRequiredByDefault bool +var ( + fieldsRequiredByDefault bool + nilPtrAllowedByRequired = false + notNumberRegexp = regexp.MustCompile("[^0-9]+") + whiteSpacesAndMinus = regexp.MustCompile(`[\s-]+`) + paramsRegexp = regexp.MustCompile(`\(.*\)$`) +) + +const maxURLRuneCount = 2083 +const minURLRuneCount = 3 +const RF3339WithoutZone = "2006-01-02T15:04:05" // SetFieldsRequiredByDefault causes validation to fail when struct fields // do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). @@ -36,18 +52,66 @@ func SetFieldsRequiredByDefault(value bool) { fieldsRequiredByDefault = value } +// SetNilPtrAllowedByRequired causes validation to pass for nil ptrs when a field is set to required. +// The validation will still reject ptr fields in their zero value state. Example with this enabled: +// type exampleStruct struct { +// Name *string `valid:"required"` +// With `Name` set to "", this will be considered invalid input and will cause a validation error. +// With `Name` set to nil, this will be considered valid by validation. +// By default this is disabled. +func SetNilPtrAllowedByRequired(value bool) { + nilPtrAllowedByRequired = value +} + // IsEmail check if the string is an email. func IsEmail(str string) bool { // TODO uppercase letters are not supported return rxEmail.MatchString(str) } +// IsExistingEmail check if the string is an email of existing domain +func IsExistingEmail(email string) bool { + + if len(email) < 6 || len(email) > 254 { + return false + } + at := strings.LastIndex(email, "@") + if at <= 0 || at > len(email)-3 { + return false + } + user := email[:at] + host := email[at+1:] + if len(user) > 64 { + return false + } + if userDotRegexp.MatchString(user) || !userRegexp.MatchString(user) || !hostRegexp.MatchString(host) { + return false + } + switch host { + case "localhost", "example.com": + return true + } + if _, err := net.LookupMX(host); err != nil { + if _, err := net.LookupIP(host); err != nil { + return false + } + } + + return true +} + // IsURL check if the string is an URL. func IsURL(str string) bool { - if str == "" || len(str) >= 2083 || len(str) <= 3 || strings.HasPrefix(str, ".") { + if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") { return false } - u, err := url.Parse(str) + strTemp := str + if strings.Contains(str, ":") && !strings.Contains(str, "://") { + // support no indicated urlscheme but with colon for port number + // http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString + strTemp = "http://" + str + } + u, err := url.Parse(strTemp) if err != nil { return false } @@ -58,11 +122,10 @@ func IsURL(str string) bool { return false } return rxURL.MatchString(str) - } // IsRequestURL check if the string rawurl, assuming -// it was recieved in an HTTP request, is a valid +// it was received in an HTTP request, is a valid // URL confirm to RFC 3986 func IsRequestURL(rawurl string) bool { url, err := url.ParseRequestURI(rawurl) @@ -76,7 +139,7 @@ func IsRequestURL(rawurl string) bool { } // IsRequestURI check if the string rawurl, assuming -// it was recieved in an HTTP request, is an +// it was received in an HTTP request, is an // absolute URI or an absolute path. func IsRequestURI(rawurl string) bool { _, err := url.ParseRequestURI(rawurl) @@ -151,7 +214,7 @@ func IsUTFNumeric(str string) bool { str = strings.TrimPrefix(str, "+") } for _, c := range str { - if unicode.IsNumber(c) == false { //numbers && minus sign are ok + if !unicode.IsNumber(c) { //numbers && minus sign are ok return false } } @@ -211,6 +274,22 @@ func IsUpperCase(str string) bool { return str == strings.ToUpper(str) } +// HasLowerCase check if the string contains at least 1 lowercase. Empty string is valid. +func HasLowerCase(str string) bool { + if IsNull(str) { + return true + } + return rxHasLowerCase.MatchString(str) +} + +// HasUpperCase check if the string contians as least 1 uppercase. Empty string is valid. +func HasUpperCase(str string) bool { + if IsNull(str) { + return true + } + return rxHasUpperCase.MatchString(str) +} + // IsInt check if the string is an integer. Empty string is valid. func IsInt(str string) bool { if IsNull(str) { @@ -242,6 +321,16 @@ func IsNull(str string) bool { return len(str) == 0 } +// HasWhitespaceOnly checks the string only contains whitespace +func HasWhitespaceOnly(str string) bool { + return len(str) > 0 && rxHasWhitespaceOnly.MatchString(str) +} + +// HasWhitespace checks if the string contains any whitespace +func HasWhitespace(str string) bool { + return len(str) > 0 && rxHasWhitespace.MatchString(str) +} + // IsByteLength check if the string's length (in bytes) falls in a range. func IsByteLength(str string, min, max int) bool { return len(str) >= min && len(str) <= max @@ -269,9 +358,8 @@ func IsUUID(str string) bool { // IsCreditCard check if the string is a credit card. func IsCreditCard(str string) bool { - r, _ := regexp.Compile("[^0-9]+") - sanitized := r.ReplaceAll([]byte(str), []byte("")) - if !rxCreditCard.MatchString(string(sanitized)) { + sanitized := notNumberRegexp.ReplaceAllString(str, "") + if !rxCreditCard.MatchString(sanitized) { return false } var sum int64 @@ -279,7 +367,7 @@ func IsCreditCard(str string) bool { var tmpNum int64 var shouldDouble bool for i := len(sanitized) - 1; i >= 0; i-- { - digit = string(sanitized[i:(i + 1)]) + digit = sanitized[i:(i + 1)] tmpNum, _ = ToInt(digit) if shouldDouble { tmpNum *= 2 @@ -294,10 +382,7 @@ func IsCreditCard(str string) bool { shouldDouble = !shouldDouble } - if sum%10 == 0 { - return true - } - return false + return sum%10 == 0 } // IsISBN10 check if the string is an ISBN version 10. @@ -313,12 +398,11 @@ func IsISBN13(str string) bool { // IsISBN check if the string is an ISBN (version 10 or 13). // If version value is not equal to 10 or 13, it will be check both variants. func IsISBN(str string, version int) bool { - r, _ := regexp.Compile("[\\s-]+") - sanitized := r.ReplaceAll([]byte(str), []byte("")) + sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "") var checksum int32 var i int32 if version == 10 { - if !rxISBN10.MatchString(string(sanitized)) { + if !rxISBN10.MatchString(sanitized) { return false } for i = 0; i < 9; i++ { @@ -334,17 +418,14 @@ func IsISBN(str string, version int) bool { } return false } else if version == 13 { - if !rxISBN13.MatchString(string(sanitized)) { + if !rxISBN13.MatchString(sanitized) { return false } factor := []int32{1, 3} for i = 0; i < 12; i++ { checksum += factor[i%2] * int32(sanitized[i]-'0') } - if (int32(sanitized[12]-'0'))-((10-(checksum%10))%10) == 0 { - return true - } - return false + return (int32(sanitized[12]-'0'))-((10-(checksum%10))%10) == 0 } return IsISBN(str, 10) || IsISBN(str, 13) } @@ -452,13 +533,60 @@ func IsISO3166Alpha3(str string) bool { return false } +// IsISO693Alpha2 checks if a string is valid two-letter language code +func IsISO693Alpha2(str string) bool { + for _, entry := range ISO693List { + if str == entry.Alpha2Code { + return true + } + } + return false +} + +// IsISO693Alpha3b checks if a string is valid three-letter language code +func IsISO693Alpha3b(str string) bool { + for _, entry := range ISO693List { + if str == entry.Alpha3bCode { + return true + } + } + return false +} + // IsDNSName will validate the given string as a DNS name func IsDNSName(str string) bool { if str == "" || len(strings.Replace(str, ".", "", -1)) > 255 { // constraints already violated return false } - return rxDNSName.MatchString(str) + return !IsIP(str) && rxDNSName.MatchString(str) +} + +// IsHash checks if a string is a hash of type algorithm. +// Algorithm is one of ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b'] +func IsHash(str string, algorithm string) bool { + len := "0" + algo := strings.ToLower(algorithm) + + if algo == "crc32" || algo == "crc32b" { + len = "8" + } else if algo == "md5" || algo == "md4" || algo == "ripemd128" || algo == "tiger128" { + len = "32" + } else if algo == "sha1" || algo == "ripemd160" || algo == "tiger160" { + len = "40" + } else if algo == "tiger192" { + len = "48" + } else if algo == "sha256" { + len = "64" + } else if algo == "sha384" { + len = "96" + } else if algo == "sha512" { + len = "128" + } else { + return false + } + + return Matches(str, "^[a-f0-9]{"+len+"}$") } // IsDialString validates the given string for usage with the various Dial() functions @@ -496,6 +624,12 @@ func IsIPv6(str string) bool { return ip != nil && strings.Contains(str, ":") } +// IsCIDR check if the string is an valid CIDR notiation (IPV4 & IPV6) +func IsCIDR(str string) bool { + _, _, err := net.ParseCIDR(str) + return err == nil +} + // IsMAC check if a string is valid MAC address. // Possible MAC formats: // 01:23:45:67:89:ab @@ -529,6 +663,76 @@ func IsLongitude(str string) bool { return rxLongitude.MatchString(str) } +// IsRsaPublicKey check if a string is valid public key with provided length +func IsRsaPublicKey(str string, keylen int) bool { + bb := bytes.NewBufferString(str) + pemBytes, err := ioutil.ReadAll(bb) + if err != nil { + return false + } + block, _ := pem.Decode(pemBytes) + if block != nil && block.Type != "PUBLIC KEY" { + return false + } + var der []byte + + if block != nil { + der = block.Bytes + } else { + der, err = base64.StdEncoding.DecodeString(str) + if err != nil { + return false + } + } + + key, err := x509.ParsePKIXPublicKey(der) + if err != nil { + return false + } + pubkey, ok := key.(*rsa.PublicKey) + if !ok { + return false + } + bitlen := len(pubkey.N.Bytes()) * 8 + return bitlen == int(keylen) +} + +func toJSONName(tag string) string { + if tag == "" { + return "" + } + + // JSON name always comes first. If there's no options then split[0] is + // JSON name, if JSON name is not set, then split[0] is an empty string. + split := strings.SplitN(tag, ",", 2) + + name := split[0] + + // However it is possible that the field is skipped when + // (de-)serializing from/to JSON, in which case assume that there is no + // tag name to use + if name == "-" { + return "" + } + return name +} + +func PrependPathToErrors(err error, path string) error { + switch err2 := err.(type) { + case Error: + err2.Path = append([]string{path}, err2.Path...) + return err2 + case Errors: + errors := err2.Errors() + for i, err3 := range errors { + errors[i] = PrependPathToErrors(err3, path) + } + return err2 + } + fmt.Println(err) + return err +} + // ValidateStruct use tags for fields. // result will be equal to `false` if there are any errors. func ValidateStruct(s interface{}) (bool, error) { @@ -552,11 +756,46 @@ func ValidateStruct(s interface{}) (bool, error) { if typeField.PkgPath != "" { continue // Private field } - resultField, err2 := typeCheck(valueField, typeField, val) + structResult := true + if valueField.Kind() == reflect.Interface { + valueField = valueField.Elem() + } + if (valueField.Kind() == reflect.Struct || + (valueField.Kind() == reflect.Ptr && valueField.Elem().Kind() == reflect.Struct)) && + typeField.Tag.Get(tagName) != "-" { + var err error + structResult, err = ValidateStruct(valueField.Interface()) + if err != nil { + err = PrependPathToErrors(err, typeField.Name) + errs = append(errs, err) + } + } + resultField, err2 := typeCheck(valueField, typeField, val, nil) if err2 != nil { + + // Replace structure name with JSON name if there is a tag on the variable + jsonTag := toJSONName(typeField.Tag.Get("json")) + if jsonTag != "" { + switch jsonError := err2.(type) { + case Error: + jsonError.Name = jsonTag + err2 = jsonError + case Errors: + for i2, err3 := range jsonError { + switch customErr := err3.(type) { + case Error: + customErr.Name = jsonTag + jsonError[i2] = customErr + } + } + + err2 = jsonError + } + } + errs = append(errs, err2) } - result = result && resultField + result = result && resultField && structResult } if len(errs) > 0 { err = errs @@ -567,16 +806,19 @@ func ValidateStruct(s interface{}) (bool, error) { // parseTagIntoMap parses a struct tag `valid:required~Some error message,length(2|3)` into map[string]string{"required": "Some error message", "length(2|3)": ""} func parseTagIntoMap(tag string) tagOptionsMap { optionsMap := make(tagOptionsMap) - options := strings.SplitN(tag, ",", -1) - for _, option := range options { + options := strings.Split(tag, ",") + + for i, option := range options { + option = strings.TrimSpace(option) + validationOptions := strings.Split(option, "~") if !isValidTag(validationOptions[0]) { continue } if len(validationOptions) == 2 { - optionsMap[validationOptions[0]] = validationOptions[1] + optionsMap[validationOptions[0]] = tagOption{validationOptions[0], validationOptions[1], i} } else { - optionsMap[validationOptions[0]] = "" + optionsMap[validationOptions[0]] = tagOption{validationOptions[0], "", i} } } return optionsMap @@ -588,7 +830,7 @@ func isValidTag(s string) bool { } for _, c := range s { switch { - case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): + case strings.ContainsRune("\\'\"!#$%&()*+-./:<=>?@[]^_{|}~ ", c): // Backslash and quote chars are reserved, but // otherwise any punctuation chars are allowed // in a tag name. @@ -614,6 +856,33 @@ func IsSemver(str string) bool { return rxSemver.MatchString(str) } +// IsTime check if string is valid according to given format +func IsTime(str string, format string) bool { + _, err := time.Parse(format, str) + return err == nil +} + +// IsRFC3339 check if string is valid timestamp value according to RFC3339 +func IsRFC3339(str string) bool { + return IsTime(str, time.RFC3339) +} + +// IsRFC3339WithoutZone check if string is valid timestamp value according to RFC3339 which excludes the timezone. +func IsRFC3339WithoutZone(str string) bool { + return IsTime(str, RF3339WithoutZone) +} + +// IsISO4217 check if string is valid ISO currency code +func IsISO4217(str string) bool { + for _, currency := range ISO4217List { + if str == currency { + return true + } + } + + return false +} + // ByteLength check string's length func ByteLength(str string, params ...string) bool { if len(params) == 2 { @@ -625,6 +894,23 @@ func ByteLength(str string, params ...string) bool { return false } +// RuneLength check string's length +// Alias for StringLength +func RuneLength(str string, params ...string) bool { + return StringLength(str, params...) +} + +// IsRsaPub check whether string is valid RSA key +// Alias for IsRsaPublicKey +func IsRsaPub(str string, params ...string) bool { + if len(params) == 1 { + len, _ := ToInt(params[0]) + return IsRsaPublicKey(str, int(len)) + } + + return false +} + // StringMatches checks if a string matches a given pattern. func StringMatches(s string, params ...string) bool { if len(params) == 1 { @@ -647,20 +933,62 @@ func StringLength(str string, params ...string) bool { return false } +// Range check string's length +func Range(str string, params ...string) bool { + if len(params) == 2 { + value, _ := ToFloat(str) + min, _ := ToFloat(params[0]) + max, _ := ToFloat(params[1]) + return InRange(value, min, max) + } + + return false +} + +func isInRaw(str string, params ...string) bool { + if len(params) == 1 { + rawParams := params[0] + + parsedParams := strings.Split(rawParams, "|") + + return IsIn(str, parsedParams...) + } + + return false +} + +// IsIn check if string str is a member of the set of strings params +func IsIn(str string, params ...string) bool { + for _, param := range params { + if str == param { + return true + } + } + + return false +} + func checkRequired(v reflect.Value, t reflect.StructField, options tagOptionsMap) (bool, error) { + if nilPtrAllowedByRequired { + k := v.Kind() + if (k == reflect.Ptr || k == reflect.Interface) && v.IsNil() { + return true, nil + } + } + if requiredOption, isRequired := options["required"]; isRequired { - if len(requiredOption) > 0 { - return false, Error{t.Name, fmt.Errorf(requiredOption), true} + if len(requiredOption.customErrorMessage) > 0 { + return false, Error{t.Name, fmt.Errorf(requiredOption.customErrorMessage), true, "required", []string{}} } - return false, Error{t.Name, fmt.Errorf("non zero value required"), false} + return false, Error{t.Name, fmt.Errorf("non zero value required"), false, "required", []string{}} } else if _, isOptional := options["optional"]; fieldsRequiredByDefault && !isOptional { - return false, Error{t.Name, fmt.Errorf("All fields are required to at least have one validation defined"), false} + return false, Error{t.Name, fmt.Errorf("Missing required field"), false, "required", []string{}} } // not required and empty is valid return true, nil } -func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value) (bool, error) { +func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options tagOptionsMap) (isValid bool, resultErr error) { if !v.IsValid() { return false, nil } @@ -670,39 +998,68 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value) (bool, e // Check if the field should be ignored switch tag { case "": - if !fieldsRequiredByDefault { - return true, nil + if v.Kind() != reflect.Slice && v.Kind() != reflect.Map { + if !fieldsRequiredByDefault { + return true, nil + } + return false, Error{t.Name, fmt.Errorf("All fields are required to at least have one validation defined"), false, "required", []string{}} } - return false, Error{t.Name, fmt.Errorf("All fields are required to at least have one validation defined"), false} case "-": return true, nil } - options := parseTagIntoMap(tag) + isRootType := false + if options == nil { + isRootType = true + options = parseTagIntoMap(tag) + } + + if isEmptyValue(v) { + // an empty value is not validated, check only required + isValid, resultErr = checkRequired(v, t, options) + for key := range options { + delete(options, key) + } + return isValid, resultErr + } + var customTypeErrors Errors - var customTypeValidatorsExist bool - for validatorName, customErrorMessage := range options { + optionsOrder := options.orderedKeys() + for _, validatorName := range optionsOrder { + validatorStruct := options[validatorName] if validatefunc, ok := CustomTypeTagMap.Get(validatorName); ok { - customTypeValidatorsExist = true + delete(options, validatorName) + if result := validatefunc(v.Interface(), o.Interface()); !result { - if len(customErrorMessage) > 0 { - customTypeErrors = append(customTypeErrors, Error{Name: t.Name, Err: fmt.Errorf(customErrorMessage), CustomErrorMessageExists: true}) + if len(validatorStruct.customErrorMessage) > 0 { + customTypeErrors = append(customTypeErrors, Error{Name: t.Name, Err: TruncatingErrorf(validatorStruct.customErrorMessage, fmt.Sprint(v), validatorName), CustomErrorMessageExists: true, Validator: stripParams(validatorName)}) continue } - customTypeErrors = append(customTypeErrors, Error{Name: t.Name, Err: fmt.Errorf("%s does not validate as %s", fmt.Sprint(v), validatorName), CustomErrorMessageExists: false}) + customTypeErrors = append(customTypeErrors, Error{Name: t.Name, Err: fmt.Errorf("%s does not validate as %s", fmt.Sprint(v), validatorName), CustomErrorMessageExists: false, Validator: stripParams(validatorName)}) } } } - if customTypeValidatorsExist { - if len(customTypeErrors.Errors()) > 0 { - return false, customTypeErrors - } - return true, nil + + if len(customTypeErrors.Errors()) > 0 { + return false, customTypeErrors } - if isEmptyValue(v) { - // an empty value is not validated, check only required - return checkRequired(v, t, options) + if isRootType { + // Ensure that we've checked the value by all specified validators before report that the value is valid + defer func() { + delete(options, "optional") + delete(options, "required") + + if isValid && resultErr == nil && len(options) != 0 { + optionsOrder := options.orderedKeys() + for _, validator := range optionsOrder { + isValid = false + resultErr = Error{t.Name, fmt.Errorf( + "The following validator is invalid or can't be applied to the field: %q", validator), false, stripParams(validator), []string{}} + return + } + } + }() } switch v.Kind() { @@ -712,75 +1069,76 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value) (bool, e reflect.Float32, reflect.Float64, reflect.String: // for each tag option check the map of validator functions - for validator, customErrorMessage := range options { + for _, validatorSpec := range optionsOrder { + validatorStruct := options[validatorSpec] var negate bool - customMsgExists := (len(customErrorMessage) > 0) - // Check wether the tag looks like '!something' or 'something' + validator := validatorSpec + customMsgExists := len(validatorStruct.customErrorMessage) > 0 + + // Check whether the tag looks like '!something' or 'something' if validator[0] == '!' { - validator = string(validator[1:]) + validator = validator[1:] negate = true } // Check for param validators for key, value := range ParamTagRegexMap { ps := value.FindStringSubmatch(validator) - if len(ps) > 0 { - if validatefunc, ok := ParamTagMap[key]; ok { - switch v.Kind() { - case reflect.String: - field := fmt.Sprint(v) // make value into string, then validate with regex - if result := validatefunc(field, ps[1:]...); (!result && !negate) || (result && negate) { - var err error - if !negate { - if customMsgExists { - err = fmt.Errorf(customErrorMessage) - } else { - err = fmt.Errorf("%s does not validate as %s", field, validator) - } - - } else { - if customMsgExists { - err = fmt.Errorf(customErrorMessage) - } else { - err = fmt.Errorf("%s does validate as %s", field, validator) - } - } - return false, Error{t.Name, err, customMsgExists} - } - default: - // type not yet supported, fail - return false, Error{t.Name, fmt.Errorf("Validator %s doesn't support kind %s", validator, v.Kind()), false} + if len(ps) == 0 { + continue + } + + validatefunc, ok := ParamTagMap[key] + if !ok { + continue + } + + delete(options, validatorSpec) + + switch v.Kind() { + case reflect.String, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64: + + field := fmt.Sprint(v) // make value into string, then validate with regex + if result := validatefunc(field, ps[1:]...); (!result && !negate) || (result && negate) { + if customMsgExists { + return false, Error{t.Name, TruncatingErrorf(validatorStruct.customErrorMessage, field, validator), customMsgExists, stripParams(validatorSpec), []string{}} } + if negate { + return false, Error{t.Name, fmt.Errorf("%s does validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} + } + return false, Error{t.Name, fmt.Errorf("%s does not validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} } + default: + // type not yet supported, fail + return false, Error{t.Name, fmt.Errorf("Validator %s doesn't support kind %s", validator, v.Kind()), false, stripParams(validatorSpec), []string{}} } } if validatefunc, ok := TagMap[validator]; ok { + delete(options, validatorSpec) + switch v.Kind() { - case reflect.String: + case reflect.String, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64: field := fmt.Sprint(v) // make value into string, then validate with regex if result := validatefunc(field); !result && !negate || result && negate { - var err error - - if !negate { - if customMsgExists { - err = fmt.Errorf(customErrorMessage) - } else { - err = fmt.Errorf("%s does not validate as %s", field, validator) - } - } else { - if customMsgExists { - err = fmt.Errorf(customErrorMessage) - } else { - err = fmt.Errorf("%s does validate as %s", field, validator) - } + if customMsgExists { + return false, Error{t.Name, TruncatingErrorf(validatorStruct.customErrorMessage, field, validator), customMsgExists, stripParams(validatorSpec), []string{}} } - return false, Error{t.Name, err, customMsgExists} + if negate { + return false, Error{t.Name, fmt.Errorf("%s does validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} + } + return false, Error{t.Name, fmt.Errorf("%s does not validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} } default: //Not Yet Supported Types (Fail here!) err := fmt.Errorf("Validator %s doesn't support kind %s for value %v", validator, v.Kind(), v) - return false, Error{t.Name, err, false} + return false, Error{t.Name, err, false, stripParams(validatorSpec), []string{}} } } } @@ -793,46 +1151,38 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value) (bool, e sv = v.MapKeys() sort.Sort(sv) result := true - for _, k := range sv { - resultItem, err := ValidateStruct(v.MapIndex(k).Interface()) - if err != nil { - return false, err - } - result = result && resultItem - } - return result, nil - case reflect.Slice: - result := true - for i := 0; i < v.Len(); i++ { + for i, k := range sv { var resultItem bool var err error - if v.Index(i).Kind() != reflect.Struct { - resultItem, err = typeCheck(v.Index(i), t, o) + if v.MapIndex(k).Kind() != reflect.Struct { + resultItem, err = typeCheck(v.MapIndex(k), t, o, options) if err != nil { return false, err } } else { - resultItem, err = ValidateStruct(v.Index(i).Interface()) + resultItem, err = ValidateStruct(v.MapIndex(k).Interface()) if err != nil { + err = PrependPathToErrors(err, t.Name+"."+sv[i].Interface().(string)) return false, err } } result = result && resultItem } return result, nil - case reflect.Array: + case reflect.Slice, reflect.Array: result := true for i := 0; i < v.Len(); i++ { var resultItem bool var err error if v.Index(i).Kind() != reflect.Struct { - resultItem, err = typeCheck(v.Index(i), t, o) + resultItem, err = typeCheck(v.Index(i), t, o, options) if err != nil { return false, err } } else { resultItem, err = ValidateStruct(v.Index(i).Interface()) if err != nil { + err = PrependPathToErrors(err, t.Name+"."+strconv.Itoa(i)) return false, err } } @@ -850,7 +1200,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value) (bool, e if v.IsNil() { return true, nil } - return typeCheck(v.Elem(), t, o) + return typeCheck(v.Elem(), t, o, options) case reflect.Struct: return ValidateStruct(v.Interface()) default: @@ -858,6 +1208,10 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value) (bool, e } } +func stripParams(validatorString string) string { + return paramsRegexp.ReplaceAllString(validatorString, "") +} + func isEmptyValue(v reflect.Value) bool { switch v.Kind() { case reflect.String, reflect.Array: diff --git a/vendor/github.com/asaskevich/govalidator/wercker.yml b/vendor/github.com/asaskevich/govalidator/wercker.yml index 4840449099604..cac7a5fcf0630 100644 --- a/vendor/github.com/asaskevich/govalidator/wercker.yml +++ b/vendor/github.com/asaskevich/govalidator/wercker.yml @@ -1,4 +1,4 @@ -box: wercker/golang +box: golang build: steps: - setup-go-workspace diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/BUILD b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/BUILD index 3d50d941ff89e..5ae277b7643e1 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/BUILD +++ b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/BUILD @@ -28,6 +28,7 @@ go_library( "//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library", "//vendor/github.com/bazelbuild/bazel-gazelle/internal/version:go_default_library", "//vendor/github.com/bazelbuild/bazel-gazelle/internal/walk:go_default_library", + "//vendor/github.com/pmezard/go-difflib/difflib:go_default_library", ], ) diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/diff.go b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/diff.go index 4e74feafea725..5dbe7934bafcc 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/diff.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/diff.go @@ -16,37 +16,68 @@ limitations under the License. package main import ( - "bytes" + "fmt" + "io" "io/ioutil" "os" - "os/exec" "path/filepath" + + "github.com/bazelbuild/bazel-gazelle/internal/config" + "github.com/bazelbuild/bazel-gazelle/internal/rule" + "github.com/pmezard/go-difflib/difflib" ) -func diffFile(path string, newContents []byte) error { - oldContents, err := ioutil.ReadFile(path) +func diffFile(c *config.Config, f *rule.File) error { + rel, err := filepath.Rel(c.RepoRoot, f.Path) if err != nil { - oldContents = nil + return fmt.Errorf("error getting old path for file %q: %v", f.Path, err) } - if bytes.Equal(oldContents, newContents) { - return nil + rel = filepath.ToSlash(rel) + + date := "1970-01-01 00:00:00.000000000 +0000" + diff := difflib.UnifiedDiff{ + Context: 3, + FromDate: date, + ToDate: date, } - f, err := ioutil.TempFile("", filepath.Base(path)) - if err != nil { - return err + + if oldContent, err := ioutil.ReadFile(f.Path); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("error reading original file: %v", err) + } else if err != nil { + diff.FromFile = "/dev/null" + } else if err == nil { + diff.A = difflib.SplitLines(string(oldContent)) + if c.ReadBuildFilesDir == "" { + path, err := filepath.Rel(c.RepoRoot, f.Path) + if err != nil { + return fmt.Errorf("error getting old path for file %q: %v", f.Path, err) + } + diff.FromFile = filepath.ToSlash(path) + } else { + diff.FromFile = f.Path + } } - f.Close() - defer os.Remove(f.Name()) - if err := ioutil.WriteFile(f.Name(), newContents, 0666); err != nil { - return err + + newContent := f.Format() + diff.B = difflib.SplitLines(string(newContent)) + outPath := findOutputPath(c, f) + if c.WriteBuildFilesDir == "" { + path, err := filepath.Rel(c.RepoRoot, f.Path) + if err != nil { + return fmt.Errorf("error getting new path for file %q: %v", f.Path, err) + } + diff.ToFile = filepath.ToSlash(path) + } else { + diff.ToFile = outPath + } + + uc := getUpdateConfig(c) + var out io.Writer = os.Stdout + if uc.patchPath != "" { + out = &uc.patchBuffer } - cmd := exec.Command("diff", "-u", "--new-file", path, f.Name()) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err = cmd.Run() - if _, ok := err.(*exec.ExitError); ok { - // diff returns non-zero when files are different. This is not an error. - return nil + if err := difflib.WriteUnifiedDiff(out, diff); err != nil { + return fmt.Errorf("error diffing %s: %v", f.Path, err) } - return err + return nil } diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/fix-update.go b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/fix-update.go index a44994ce3716f..81c60f446eebc 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/fix-update.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/fix-update.go @@ -16,6 +16,7 @@ limitations under the License. package main import ( + "bytes" "flag" "fmt" "io/ioutil" @@ -38,11 +39,16 @@ import ( // update commands. This includes everything in config.Config, but it also // includes some additional fields that aren't relevant to other packages. type updateConfig struct { - emit emitFunc - repos []repos.Repo + dirs []string + emit emitFunc + repos []repos.Repo + useIndex bool + walkMode walk.Mode + patchPath string + patchBuffer bytes.Buffer } -type emitFunc func(path string, data []byte) error +type emitFunc func(c *config.Config, f *rule.File) error var modeFromName = map[string]emitFunc{ "print": printFile, @@ -57,7 +63,8 @@ func getUpdateConfig(c *config.Config) *updateConfig { } type updateConfigurer struct { - mode string + mode string + recursive bool } func (ucr *updateConfigurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) { @@ -67,33 +74,49 @@ func (ucr *updateConfigurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *conf c.ShouldFix = cmd == "fix" fs.StringVar(&ucr.mode, "mode", "fix", "print: prints all of the updated BUILD files\n\tfix: rewrites all of the BUILD files in place\n\tdiff: computes the rewrite but then just does a diff") + fs.BoolVar(&uc.useIndex, "index", true, "when true, gazelle will build an index of libraries in the workspace for dependency resolution") + fs.BoolVar(&ucr.recursive, "r", true, "when true, gazelle will update subdirectories recursively") + fs.StringVar(&uc.patchPath, "patch", "", "when set with -mode=diff, gazelle will write to a file instead of stdout") } func (ucr *updateConfigurer) CheckFlags(fs *flag.FlagSet, c *config.Config) error { uc := getUpdateConfig(c) + var ok bool uc.emit, ok = modeFromName[ucr.mode] if !ok { return fmt.Errorf("unrecognized emit mode: %q", ucr.mode) } + if uc.patchPath != "" && ucr.mode != "diff" { + return fmt.Errorf("-patch set but -mode is %s, not diff", ucr.mode) + } - c.Dirs = fs.Args() - if len(c.Dirs) == 0 { - c.Dirs = []string{"."} + dirs := fs.Args() + if len(dirs) == 0 { + dirs = []string{"."} } - for i := range c.Dirs { - dir, err := filepath.Abs(c.Dirs[i]) + uc.dirs = make([]string, len(dirs)) + for i := range dirs { + dir, err := filepath.Abs(dirs[i]) if err != nil { - return fmt.Errorf("%s: failed to find absolute path: %v", c.Dirs[i], err) + return fmt.Errorf("%s: failed to find absolute path: %v", dirs[i], err) } dir, err = filepath.EvalSymlinks(dir) if err != nil { - return fmt.Errorf("%s: failed to resolve symlinks: %v", c.Dirs[i], err) + return fmt.Errorf("%s: failed to resolve symlinks: %v", dirs[i], err) } if !isDescendingDir(dir, c.RepoRoot) { return fmt.Errorf("dir %q is not a subdirectory of repo root %q", dir, c.RepoRoot) } - c.Dirs[i] = dir + uc.dirs[i] = dir + } + + if ucr.recursive { + uc.walkMode = walk.VisitAllUpdateSubdirsMode + } else if uc.useIndex { + uc.walkMode = walk.VisitAllUpdateDirsMode + } else { + uc.walkMode = walk.UpdateDirsMode } return nil @@ -134,8 +157,12 @@ var genericLoads = []rule.LoadInfo{ } func runFixUpdate(cmd command, args []string) error { - cexts := make([]config.Configurer, 0, len(languages)+2) - cexts = append(cexts, &config.CommonConfigurer{}, &updateConfigurer{}) + cexts := make([]config.Configurer, 0, len(languages)+3) + cexts = append(cexts, + &config.CommonConfigurer{}, + &updateConfigurer{}, + &walk.Configurer{}, + &resolve.Configurer{}) kindToResolver := make(map[string]resolve.Resolver) kinds := make(map[string]rule.KindInfo) loads := genericLoads @@ -163,11 +190,12 @@ func runFixUpdate(cmd command, args []string) error { // Visit all directories in the repository. var visits []visitRecord - walk.Walk(c, cexts, func(dir, rel string, c *config.Config, update bool, f *rule.File, subdirs, regularFiles, genFiles []string) { + uc := getUpdateConfig(c) + walk.Walk(c, cexts, uc.dirs, uc.walkMode, func(dir, rel string, c *config.Config, update bool, f *rule.File, subdirs, regularFiles, genFiles []string) { // If this file is ignored or if Gazelle was not asked to update this // directory, just index the build file and move on. if !update { - if f != nil { + if uc.useIndex && f != nil { for _, r := range f.Rules { ruleIndex.AddRule(c, r, f) } @@ -215,8 +243,6 @@ func runFixUpdate(cmd command, args []string) error { } }) - uc := getUpdateConfig(c) - // Finish building the index for dependency resolution. ruleIndex.Finish() @@ -233,12 +259,16 @@ func runFixUpdate(cmd command, args []string) error { // Emit merged files. for _, v := range visits { merger.FixLoads(v.file, loads) - content := v.file.Format() - outputPath := findOutputPath(c, v.file) - if err := uc.emit(outputPath, content); err != nil { + if err := uc.emit(c, v.file); err != nil { log.Print(err) } } + if uc.patchPath != "" { + if err := ioutil.WriteFile(uc.patchPath, uc.patchBuffer.Bytes(), 0666); err != nil { + return err + } + } + return nil } @@ -338,7 +368,7 @@ func fixWorkspace(c *config.Config, workspace *rule.File, loads []rule.LoadInfo) return nil } shouldFix := false - for _, d := range c.Dirs { + for _, d := range uc.dirs { if d == c.RepoRoot { shouldFix = true } @@ -352,7 +382,7 @@ func fixWorkspace(c *config.Config, workspace *rule.File, loads []rule.LoadInfo) if err := merger.CheckGazelleLoaded(workspace); err != nil { return err } - return uc.emit(workspace.Path, workspace.Format()) + return uc.emit(c, workspace) } func findWorkspaceName(f *rule.File) string { diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/fix.go b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/fix.go index 7a1c38874a59e..9e13578c635bd 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/fix.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/fix.go @@ -19,11 +19,15 @@ import ( "io/ioutil" "os" "path/filepath" + + "github.com/bazelbuild/bazel-gazelle/internal/config" + "github.com/bazelbuild/bazel-gazelle/internal/rule" ) -func fixFile(path string, data []byte) error { - if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil { +func fixFile(c *config.Config, f *rule.File) error { + outPath := findOutputPath(c, f) + if err := os.MkdirAll(filepath.Dir(outPath), 0777); err != nil { return err } - return ioutil.WriteFile(path, data, 0666) + return ioutil.WriteFile(outPath, f.Format(), 0666) } diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/gazelle.go b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/gazelle.go index fd44442661c23..5248c26f26d30 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/gazelle.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/gazelle.go @@ -56,7 +56,7 @@ func main() { log.SetPrefix("gazelle: ") log.SetFlags(0) // don't print timestamps - if err := run(os.Args[1:]); err != nil { + if err := run(os.Args[1:]); err != nil && err != flag.ErrHelp { log.Fatal(err) } } @@ -112,7 +112,7 @@ For example: gazelle update -h -Gazelle is under active delevopment, and its interface may change +Gazelle is under active development, and its interface may change without notice. `) diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/print.go b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/print.go index e7dfe135a0aa4..06f92e6f6588d 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/print.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle/print.go @@ -17,9 +17,13 @@ package main import ( "os" + + "github.com/bazelbuild/bazel-gazelle/internal/config" + "github.com/bazelbuild/bazel-gazelle/internal/rule" ) -func printFile(_ string, data []byte) error { - _, err := os.Stdout.Write(data) +func printFile(c *config.Config, f *rule.File) error { + content := f.Format() + _, err := os.Stdout.Write(content) return err } diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/config/config.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/config/config.go index d959d782efe42..5323e8c7d4a3f 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/config/config.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/config/config.go @@ -36,10 +36,6 @@ import ( // information is language-specific and is stored in Exts. This information // is modified by extensions that implement Configurer. type Config struct { - // Dirs is a list of absolute, canonical paths to directories where Gazelle - // should run. - Dirs []string - // RepoRoot is the absolute, canonical path to the root directory of the // repository with all symlinks resolved. RepoRoot string diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/known_go_imports.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/known_go_imports.go index 1443fbe2538bb..3050208febf7b 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/known_go_imports.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/known_go_imports.go @@ -20,117 +20,139 @@ var knownGoProtoImports = map[string]label.Label{ "github.com/golang/protobuf/ptypes/timestamp": label.New("io_bazel_rules_go", "proto/wkt", "timestamp_go_proto"), "google.golang.org/genproto/protobuf/ptype": label.New("io_bazel_rules_go", "proto/wkt", "type_go_proto"), "github.com/golang/protobuf/ptypes/wrappers": label.New("io_bazel_rules_go", "proto/wkt", "wrappers_go_proto"), - "google.golang.org/genproto/googleapis/assistant/embedded/v1alpha2": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_go_proto"), + "google.golang.org/genproto/googleapis/api/annotations": label.New("go_googleapis", "google/api", "annotations_go_proto"), + "google.golang.org/genproto/googleapis/api/serviceconfig": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google.golang.org/genproto/googleapis/api/configchange": label.New("go_googleapis", "google/api", "configchange_go_proto"), + "google.golang.org/genproto/googleapis/api/distribution": label.New("go_googleapis", "google/api", "distribution_go_proto"), + "google.golang.org/genproto/googleapis/api": label.New("go_googleapis", "google/api", "api_go_proto"), + "google.golang.org/genproto/googleapis/api/expr/v1alpha1": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_go_proto"), + "google.golang.org/genproto/googleapis/api/expr/v1beta1": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_go_proto"), + "google.golang.org/genproto/googleapis/api/httpbody": label.New("go_googleapis", "google/api", "httpbody_go_proto"), + "google.golang.org/genproto/googleapis/api/label": label.New("go_googleapis", "google/api", "label_go_proto"), + "google.golang.org/genproto/googleapis/api/metric": label.New("go_googleapis", "google/api", "metric_go_proto"), + "google.golang.org/genproto/googleapis/api/monitoredres": label.New("go_googleapis", "google/api", "monitoredres_go_proto"), + "google.golang.org/genproto/googleapis/api/servicecontrol/v1": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google.golang.org/genproto/googleapis/api/servicemanagement/v1": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"), + "google.golang.org/genproto/googleapis/appengine/legacy": label.New("go_googleapis", "google/appengine/legacy", "legacy_go_proto"), + "google.golang.org/genproto/googleapis/appengine/logging/v1": label.New("go_googleapis", "google/appengine/logging/v1", "logging_go_proto"), + "google.golang.org/genproto/googleapis/appengine/v1": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), "google.golang.org/genproto/googleapis/assistant/embedded/v1alpha1": label.New("go_googleapis", "google/assistant/embedded/v1alpha1", "embedded_go_proto"), - "google.golang.org/genproto/googleapis/home/graph/v1": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"), - "google.golang.org/genproto/googleapis/genomics/v1": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google.golang.org/genproto/googleapis/genomics/v1alpha2": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_go_proto"), - "google.golang.org/genproto/googleapis/bigtable/v1": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"), + "google.golang.org/genproto/googleapis/assistant/embedded/v1alpha2": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_go_proto"), "google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"), - "google.golang.org/genproto/googleapis/bigtable/admin/v2": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), "google.golang.org/genproto/googleapis/bigtable/admin/table/v1": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"), + "google.golang.org/genproto/googleapis/bigtable/admin/v2": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), + "google.golang.org/genproto/googleapis/bigtable/v1": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"), "google.golang.org/genproto/googleapis/bigtable/v2": label.New("go_googleapis", "google/bigtable/v2", "bigtable_go_proto"), - "google.golang.org/genproto/googleapis/privacy/dlp/v2": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"), - "google.golang.org/genproto/googleapis/watcher/v1": label.New("go_googleapis", "google/watcher/v1", "watcher_go_proto"), - "google.golang.org/genproto/googleapis/firestore/admin/v1beta1": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"), - "google.golang.org/genproto/googleapis/firestore/v1beta1": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), - "google.golang.org/genproto/googleapis/example/library/v1": label.New("go_googleapis", "google/example/library/v1", "library_go_proto"), - "google.golang.org/genproto/googleapis/appengine/v1": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google.golang.org/genproto/googleapis/appengine/legacy": label.New("go_googleapis", "google/appengine/legacy", "legacy_go_proto"), - "google.golang.org/genproto/googleapis/appengine/logging/v1": label.New("go_googleapis", "google/appengine/logging/v1", "logging_go_proto"), - "google.golang.org/genproto/googleapis/storagetransfer/v1": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"), - "google.golang.org/genproto/googleapis/longrunning": label.New("go_googleapis", "google/longrunning", "longrunning_go_proto"), - "google.golang.org/genproto/googleapis/container/v1": label.New("go_googleapis", "google/container/v1", "container_go_proto"), - "google.golang.org/genproto/googleapis/container/v1beta1": label.New("go_googleapis", "google/container/v1beta1", "container_go_proto"), - "google.golang.org/genproto/googleapis/container/v1alpha1": label.New("go_googleapis", "google/container/v1alpha1", "container_go_proto"), - "google.golang.org/genproto/googleapis/datastore/v1beta3": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"), - "google.golang.org/genproto/googleapis/datastore/v1": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"), - "google.golang.org/genproto/googleapis/datastore/admin/v1": label.New("go_googleapis", "google/datastore/admin/v1", "admin_go_proto"), - "google.golang.org/genproto/googleapis/datastore/admin/v1beta1": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_go_proto"), "google.golang.org/genproto/googleapis/bytestream": label.New("go_googleapis", "google/bytestream", "bytestream_go_proto"), - "google.golang.org/genproto/googleapis/iam/v1": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"), - "google.golang.org/genproto/googleapis/iam/v1/logging": label.New("go_googleapis", "google/iam/v1/logging", "logging_go_proto"), - "google.golang.org/genproto/googleapis/iam/admin/v1": label.New("go_googleapis", "google/iam/admin/v1", "admin_go_proto"), - "google.golang.org/genproto/googleapis/type/money": label.New("go_googleapis", "google/type", "money_go_proto"), - "google.golang.org/genproto/googleapis/type/latlng": label.New("go_googleapis", "google/type", "latlng_go_proto"), - "google.golang.org/genproto/googleapis/type/color": label.New("go_googleapis", "google/type", "color_go_proto"), - "google.golang.org/genproto/googleapis/type/timeofday": label.New("go_googleapis", "google/type", "timeofday_go_proto"), - "google.golang.org/genproto/googleapis/type/date": label.New("go_googleapis", "google/type", "date_go_proto"), - "google.golang.org/genproto/googleapis/type/dayofweek": label.New("go_googleapis", "google/type", "dayofweek_go_proto"), - "google.golang.org/genproto/googleapis/type/postaladdress": label.New("go_googleapis", "google/type", "postaladdress_go_proto"), - "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), - "google.golang.org/genproto/googleapis/devtools/resultstore/v2": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google.golang.org/genproto/googleapis/devtools/source/v1": label.New("go_googleapis", "google/devtools/source/v1", "source_go_proto"), - "google.golang.org/genproto/googleapis/devtools/remoteexecution/v1test": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_go_proto"), - "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_go_proto"), - "google.golang.org/genproto/googleapis/devtools/sourcerepo/v1": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_go_proto"), - "google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), - "google.golang.org/genproto/googleapis/devtools/cloudtrace/v1": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_go_proto"), - "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"), - "google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_go_proto"), - "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), - "google.golang.org/genproto/googleapis/devtools/build/v1": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"), - "google.golang.org/genproto/googleapis/devtools/clouddebugger/v2": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"), - "google.golang.org/genproto/googleapis/cloud/resourcemanager/v2": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_go_proto"), + "google.golang.org/genproto/googleapis/cloud/asset/v1beta1": label.New("go_googleapis", "google/cloud/asset/v1beta1", "asset_go_proto"), + "google.golang.org/genproto/googleapis/cloud/audit": label.New("go_googleapis", "google/cloud/audit", "audit_go_proto"), + "google.golang.org/genproto/googleapis/cloud/automl/v1beta1": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"), + "google.golang.org/genproto/googleapis/cloud/bigquery/logging/v1": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_go_proto"), + "google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_go_proto"), + "google.golang.org/genproto/googleapis/cloud/billing/v1": label.New("go_googleapis", "google/cloud/billing/v1", "billing_go_proto"), + "google.golang.org/genproto/googleapis/cloud/dataproc/v1": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"), + "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), + "google.golang.org/genproto/googleapis/cloud/dialogflow/v2": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google.golang.org/genproto/googleapis/cloud/functions/v1beta2": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"), + "google.golang.org/genproto/googleapis/cloud/iot/v1": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"), "google.golang.org/genproto/googleapis/cloud/kms/v1": label.New("go_googleapis", "google/cloud/kms/v1", "kms_go_proto"), - "google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"), - "google.golang.org/genproto/googleapis/cloud/tasks/v2beta2": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), + "google.golang.org/genproto/googleapis/cloud/language/v1": label.New("go_googleapis", "google/cloud/language/v1", "language_go_proto"), + "google.golang.org/genproto/googleapis/cloud/language/v1beta1": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_go_proto"), + "google.golang.org/genproto/googleapis/cloud/language/v1beta2": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_go_proto"), + "google.golang.org/genproto/googleapis/cloud/location": label.New("go_googleapis", "google/cloud/location", "location_go_proto"), + "google.golang.org/genproto/googleapis/cloud/ml/v1": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), + "google.golang.org/genproto/googleapis/cloud/oslogin/common": label.New("go_googleapis", "google/cloud/oslogin/common", "common_go_proto"), "google.golang.org/genproto/googleapis/cloud/oslogin/v1": label.New("go_googleapis", "google/cloud/oslogin/v1", "oslogin_go_proto"), "google.golang.org/genproto/googleapis/cloud/oslogin/v1alpha": label.New("go_googleapis", "google/cloud/oslogin/v1alpha", "oslogin_go_proto"), - "google.golang.org/genproto/googleapis/cloud/oslogin/common": label.New("go_googleapis", "google/cloud/oslogin/common", "common_go_proto"), "google.golang.org/genproto/googleapis/cloud/oslogin/v1beta": label.New("go_googleapis", "google/cloud/oslogin/v1beta", "oslogin_go_proto"), - "google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), - "google.golang.org/genproto/googleapis/cloud/dialogflow/v2": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google.golang.org/genproto/googleapis/cloud/redis/v1": label.New("go_googleapis", "google/cloud/redis/v1", "redis_go_proto"), "google.golang.org/genproto/googleapis/cloud/redis/v1beta1": label.New("go_googleapis", "google/cloud/redis/v1beta1", "redis_go_proto"), - "google.golang.org/genproto/googleapis/cloud/location": label.New("go_googleapis", "google/cloud/location", "location_go_proto"), - "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), - "google.golang.org/genproto/googleapis/cloud/language/v1": label.New("go_googleapis", "google/cloud/language/v1", "language_go_proto"), - "google.golang.org/genproto/googleapis/cloud/language/v1beta2": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_go_proto"), - "google.golang.org/genproto/googleapis/cloud/language/v1beta1": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_go_proto"), - "google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"), - "google.golang.org/genproto/googleapis/cloud/bigquery/logging/v1": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_go_proto"), - "google.golang.org/genproto/googleapis/cloud/vision/v1": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), - "google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), - "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), + "google.golang.org/genproto/googleapis/cloud/resourcemanager/v2": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_go_proto"), + "google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"), "google.golang.org/genproto/googleapis/cloud/speech/v1": label.New("go_googleapis", "google/cloud/speech/v1", "speech_go_proto"), - "google.golang.org/genproto/googleapis/cloud/speech/v1beta1": label.New("go_googleapis", "google/cloud/speech/v1beta1", "speech_go_proto"), "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1": label.New("go_googleapis", "google/cloud/speech/v1p1beta1", "speech_go_proto"), - "google.golang.org/genproto/googleapis/cloud/iot/v1": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"), - "google.golang.org/genproto/googleapis/cloud/videointelligence/v1": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_go_proto"), - "google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta2": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_go_proto"), - "google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta1": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_go_proto"), - "google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_go_proto"), - "google.golang.org/genproto/googleapis/cloud/audit": label.New("go_googleapis", "google/cloud/audit", "audit_go_proto"), "google.golang.org/genproto/googleapis/cloud/support/common": label.New("go_googleapis", "google/cloud/support", "common_go_proto"), "google.golang.org/genproto/googleapis/cloud/support/v1alpha1": label.New("go_googleapis", "google/cloud/support/v1alpha1", "support_go_proto"), - "google.golang.org/genproto/googleapis/cloud/ml/v1": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), + "google.golang.org/genproto/googleapis/cloud/tasks/v2beta2": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), + "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_go_proto"), "google.golang.org/genproto/googleapis/cloud/texttospeech/v1": label.New("go_googleapis", "google/cloud/texttospeech/v1", "texttospeech_go_proto"), "google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1": label.New("go_googleapis", "google/cloud/texttospeech/v1beta1", "texttospeech_go_proto"), - "google.golang.org/genproto/googleapis/cloud/functions/v1beta2": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"), - "google.golang.org/genproto/googleapis/cloud/billing/v1": label.New("go_googleapis", "google/cloud/billing/v1", "billing_go_proto"), - "google.golang.org/genproto/googleapis/cloud/dataproc/v1": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"), - "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), - "google.golang.org/genproto/googleapis/api/serviceconfig": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google.golang.org/genproto/googleapis/api/annotations": label.New("go_googleapis", "google/api", "annotations_go_proto"), - "google.golang.org/genproto/googleapis/api/configchange": label.New("go_googleapis", "google/api", "configchange_go_proto"), - "google.golang.org/genproto/googleapis/api/distribution": label.New("go_googleapis", "google/api", "distribution_go_proto"), - "google.golang.org/genproto/googleapis/api/monitoredres": label.New("go_googleapis", "google/api", "monitoredres_go_proto"), - "google.golang.org/genproto/googleapis/api/metric": label.New("go_googleapis", "google/api", "metric_go_proto"), - "google.golang.org/genproto/googleapis/api/label": label.New("go_googleapis", "google/api", "label_go_proto"), - "google.golang.org/genproto/googleapis/api/httpbody": label.New("go_googleapis", "google/api", "httpbody_go_proto"), - "google.golang.org/genproto/googleapis/api": label.New("go_googleapis", "google/api/experimental", "api_go_proto"), - "google.golang.org/genproto/googleapis/api/servicemanagement/v1": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"), - "google.golang.org/genproto/googleapis/api/servicecontrol/v1": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google.golang.org/genproto/googleapis/cloud/videointelligence/v1": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_go_proto"), + "google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta1": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_go_proto"), + "google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta2": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_go_proto"), + "google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_go_proto"), + "google.golang.org/genproto/googleapis/cloud/videointelligence/v1p2beta1": label.New("go_googleapis", "google/cloud/videointelligence/v1p2beta1", "videointelligence_go_proto"), + "google.golang.org/genproto/googleapis/cloud/vision/v1": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), + "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), + "google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), + "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_go_proto"), + "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), + "google.golang.org/genproto/googleapis/container/v1": label.New("go_googleapis", "google/container/v1", "container_go_proto"), + "google.golang.org/genproto/googleapis/container/v1alpha1": label.New("go_googleapis", "google/container/v1alpha1", "container_go_proto"), + "google.golang.org/genproto/googleapis/container/v1beta1": label.New("go_googleapis", "google/container/v1beta1", "container_go_proto"), + "google.golang.org/genproto/googleapis/datastore/admin/v1": label.New("go_googleapis", "google/datastore/admin/v1", "admin_go_proto"), + "google.golang.org/genproto/googleapis/datastore/admin/v1beta1": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_go_proto"), + "google.golang.org/genproto/googleapis/datastore/v1": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"), + "google.golang.org/genproto/googleapis/datastore/v1beta3": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"), + "google.golang.org/genproto/googleapis/devtools/build/v1": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"), + "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_go_proto"), + "google.golang.org/genproto/googleapis/devtools/clouddebugger/v2": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"), + "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), + "google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_go_proto"), + "google.golang.org/genproto/googleapis/devtools/cloudtrace/v1": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_go_proto"), + "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/attestation": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/attestation", "attestation_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/build": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/build", "build_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/common": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/common", "common_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1", "containeranalysis_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/deployment": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/deployment", "deployment_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/discovery": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/discovery", "discovery_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/grafeas": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/grafeas", "grafeas_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/image": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/image", "image_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/package": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/package", "package_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/provenance": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/provenance", "provenance_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/source": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/source", "source_go_proto"), + "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/vulnerability": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/vulnerability", "vulnerability_go_proto"), + "google.golang.org/genproto/googleapis/devtools/remoteexecution/v1test": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_go_proto"), + "google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), + "google.golang.org/genproto/googleapis/devtools/resultstore/v2": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google.golang.org/genproto/googleapis/devtools/source/v1": label.New("go_googleapis", "google/devtools/source/v1", "source_go_proto"), + "google.golang.org/genproto/googleapis/devtools/sourcerepo/v1": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_go_proto"), + "google.golang.org/genproto/googleapis/example/library/v1": label.New("go_googleapis", "google/example/library/v1", "library_go_proto"), + "google.golang.org/genproto/googleapis/firestore/admin/v1beta1": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"), + "google.golang.org/genproto/googleapis/firestore/admin/v1beta2": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_go_proto"), + "google.golang.org/genproto/googleapis/firestore/v1beta1": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), + "google.golang.org/genproto/googleapis/genomics/v1": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google.golang.org/genproto/googleapis/genomics/v1alpha2": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_go_proto"), + "google.golang.org/genproto/googleapis/home/graph/v1": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"), + "google.golang.org/genproto/googleapis/iam/admin/v1": label.New("go_googleapis", "google/iam/admin/v1", "admin_go_proto"), + "google.golang.org/genproto/googleapis/iam/credentials/v1": label.New("go_googleapis", "google/iam/credentials/v1", "credentials_go_proto"), + "google.golang.org/genproto/googleapis/iam/v1": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"), + "google.golang.org/genproto/googleapis/iam/v1/logging": label.New("go_googleapis", "google/iam/v1/logging", "logging_go_proto"), + "google.golang.org/genproto/googleapis/logging/type": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"), + "google.golang.org/genproto/googleapis/logging/v2": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), + "google.golang.org/genproto/googleapis/longrunning": label.New("go_googleapis", "google/longrunning", "longrunning_go_proto"), + "google.golang.org/genproto/googleapis/monitoring/v3": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google.golang.org/genproto/googleapis/privacy/dlp/v2": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"), "google.golang.org/genproto/googleapis/pubsub/v1": label.New("go_googleapis", "google/pubsub/v1", "pubsub_go_proto"), "google.golang.org/genproto/googleapis/pubsub/v1beta2": label.New("go_googleapis", "google/pubsub/v1beta2", "pubsub_go_proto"), - "google.golang.org/genproto/googleapis/spanner/v1": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), - "google.golang.org/genproto/googleapis/spanner/admin/database/v1": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_go_proto"), - "google.golang.org/genproto/googleapis/spanner/admin/instance/v1": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_go_proto"), - "google.golang.org/genproto/googleapis/monitoring/v3": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), "google.golang.org/genproto/googleapis/rpc/code": label.New("go_googleapis", "google/rpc", "code_go_proto"), - "google.golang.org/genproto/googleapis/rpc/status": label.New("go_googleapis", "google/rpc", "status_go_proto"), "google.golang.org/genproto/googleapis/rpc/errdetails": label.New("go_googleapis", "google/rpc", "errdetails_go_proto"), + "google.golang.org/genproto/googleapis/rpc/status": label.New("go_googleapis", "google/rpc", "status_go_proto"), + "google.golang.org/genproto/googleapis/spanner/admin/database/v1": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_go_proto"), + "google.golang.org/genproto/googleapis/spanner/admin/instance/v1": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_go_proto"), + "google.golang.org/genproto/googleapis/spanner/v1": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), + "google.golang.org/genproto/googleapis/storagetransfer/v1": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"), "google.golang.org/genproto/googleapis/streetview/publish/v1": label.New("go_googleapis", "google/streetview/publish/v1", "publish_go_proto"), - "google.golang.org/genproto/googleapis/logging/v2": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), - "google.golang.org/genproto/googleapis/logging/type": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"), + "google.golang.org/genproto/googleapis/type/color": label.New("go_googleapis", "google/type", "color_go_proto"), + "google.golang.org/genproto/googleapis/type/date": label.New("go_googleapis", "google/type", "date_go_proto"), + "google.golang.org/genproto/googleapis/type/dayofweek": label.New("go_googleapis", "google/type", "dayofweek_go_proto"), + "google.golang.org/genproto/googleapis/type/latlng": label.New("go_googleapis", "google/type", "latlng_go_proto"), + "google.golang.org/genproto/googleapis/type/money": label.New("go_googleapis", "google/type", "money_go_proto"), + "google.golang.org/genproto/googleapis/type/postaladdress": label.New("go_googleapis", "google/type", "postaladdress_go_proto"), + "google.golang.org/genproto/googleapis/type/timeofday": label.New("go_googleapis", "google/type", "timeofday_go_proto"), + "google.golang.org/genproto/googleapis/watcher/v1": label.New("go_googleapis", "google/watcher/v1", "watcher_go_proto"), } diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/known_proto_imports.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/known_proto_imports.go index a83178b34ae15..cd9dfc3c32286 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/known_proto_imports.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/known_proto_imports.go @@ -20,281 +20,347 @@ var knownProtoImports = map[string]label.Label{ "google/protobuf/timestamp.proto": label.New("io_bazel_rules_go", "proto/wkt", "timestamp_go_proto"), "google/protobuf/type.proto": label.New("io_bazel_rules_go", "proto/wkt", "type_go_proto"), "google/protobuf/wrappers.proto": label.New("io_bazel_rules_go", "proto/wkt", "wrappers_go_proto"), - "google/assistant/embedded/v1alpha2/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_go_proto"), + "google/api/annotations.proto": label.New("go_googleapis", "google/api", "annotations_go_proto"), + "google/api/auth.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/backend.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/billing.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/config_change.proto": label.New("go_googleapis", "google/api", "configchange_go_proto"), + "google/api/consumer.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/context.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/control.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/distribution.proto": label.New("go_googleapis", "google/api", "distribution_go_proto"), + "google/api/documentation.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/endpoint.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/experimental/authorization_config.proto": label.New("go_googleapis", "google/api", "api_go_proto"), + "google/api/experimental/experimental.proto": label.New("go_googleapis", "google/api", "api_go_proto"), + "google/api/expr/v1alpha1/cel_service.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_go_proto"), + "google/api/expr/v1alpha1/checked.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_go_proto"), + "google/api/expr/v1alpha1/eval.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_go_proto"), + "google/api/expr/v1alpha1/explain.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_go_proto"), + "google/api/expr/v1alpha1/syntax.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_go_proto"), + "google/api/expr/v1alpha1/value.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_go_proto"), + "google/api/expr/v1beta1/decl.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_go_proto"), + "google/api/expr/v1beta1/eval.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_go_proto"), + "google/api/expr/v1beta1/expr.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_go_proto"), + "google/api/expr/v1beta1/source.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_go_proto"), + "google/api/expr/v1beta1/value.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_go_proto"), + "google/api/http.proto": label.New("go_googleapis", "google/api", "annotations_go_proto"), + "google/api/httpbody.proto": label.New("go_googleapis", "google/api", "httpbody_go_proto"), + "google/api/label.proto": label.New("go_googleapis", "google/api", "label_go_proto"), + "google/api/launch_stage.proto": label.New("go_googleapis", "google/api", "api_go_proto"), + "google/api/log.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/logging.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/metric.proto": label.New("go_googleapis", "google/api", "metric_go_proto"), + "google/api/monitored_resource.proto": label.New("go_googleapis", "google/api", "monitoredres_go_proto"), + "google/api/monitoring.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/quota.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/service.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/servicecontrol/v1/check_error.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google/api/servicecontrol/v1/distribution.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google/api/servicecontrol/v1/log_entry.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google/api/servicecontrol/v1/metric_value.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google/api/servicecontrol/v1/operation.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google/api/servicecontrol/v1/quota_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google/api/servicecontrol/v1/service_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), + "google/api/servicemanagement/v1/resources.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"), + "google/api/servicemanagement/v1/servicemanager.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"), + "google/api/source_info.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/system_parameter.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/api/usage.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), + "google/appengine/legacy/audit_data.proto": label.New("go_googleapis", "google/appengine/legacy", "legacy_go_proto"), + "google/appengine/logging/v1/request_log.proto": label.New("go_googleapis", "google/appengine/logging/v1", "logging_go_proto"), + "google/appengine/v1/app_yaml.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/appengine.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/application.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/audit_data.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/deploy.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/instance.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/location.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/operation.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/service.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), + "google/appengine/v1/version.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), "google/assistant/embedded/v1alpha1/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha1", "embedded_go_proto"), - "google/home/graph/v1/device.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"), - "google/home/graph/v1/homegraph.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"), - "google/genomics/v1/operations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/variants.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/position.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/references.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/cigar.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/datasets.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/readalignment.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/annotations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/reads.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/readgroup.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/readgroupset.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1/range.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), - "google/genomics/v1alpha2/pipelines.proto": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_go_proto"), - "google/bigtable/v1/bigtable_service_messages.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"), - "google/bigtable/v1/bigtable_service.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"), - "google/bigtable/v1/bigtable_data.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"), + "google/assistant/embedded/v1alpha2/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_go_proto"), "google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"), - "google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"), "google/bigtable/admin/cluster/v1/bigtable_cluster_service.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"), + "google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"), + "google/bigtable/admin/table/v1/bigtable_table_data.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"), + "google/bigtable/admin/table/v1/bigtable_table_service.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"), + "google/bigtable/admin/table/v1/bigtable_table_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"), "google/bigtable/admin/v2/bigtable_instance_admin.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), - "google/bigtable/admin/v2/instance.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), - "google/bigtable/admin/v2/table.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), "google/bigtable/admin/v2/bigtable_table_admin.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), "google/bigtable/admin/v2/common.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), - "google/bigtable/admin/table/v1/bigtable_table_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"), - "google/bigtable/admin/table/v1/bigtable_table_service.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"), - "google/bigtable/admin/table/v1/bigtable_table_data.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"), + "google/bigtable/admin/v2/instance.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), + "google/bigtable/admin/v2/table.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"), + "google/bigtable/v1/bigtable_data.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"), + "google/bigtable/v1/bigtable_service.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"), + "google/bigtable/v1/bigtable_service_messages.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"), "google/bigtable/v2/bigtable.proto": label.New("go_googleapis", "google/bigtable/v2", "bigtable_go_proto"), "google/bigtable/v2/data.proto": label.New("go_googleapis", "google/bigtable/v2", "bigtable_go_proto"), - "google/privacy/dlp/v2/storage.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"), - "google/privacy/dlp/v2/dlp.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"), - "google/watcher/v1/watch.proto": label.New("go_googleapis", "google/watcher/v1", "watcher_go_proto"), - "google/firestore/admin/v1beta1/firestore_admin.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"), - "google/firestore/admin/v1beta1/index.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"), - "google/firestore/v1beta1/write.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), - "google/firestore/v1beta1/document.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), - "google/firestore/v1beta1/firestore.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), - "google/firestore/v1beta1/query.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), - "google/firestore/v1beta1/common.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), - "google/example/library/v1/library.proto": label.New("go_googleapis", "google/example/library/v1", "library_go_proto"), - "google/appengine/v1/instance.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/audit_data.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/appengine.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/application.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/operation.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/app_yaml.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/location.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/service.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/deploy.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/v1/version.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"), - "google/appengine/legacy/audit_data.proto": label.New("go_googleapis", "google/appengine/legacy", "legacy_go_proto"), - "google/appengine/logging/v1/request_log.proto": label.New("go_googleapis", "google/appengine/logging/v1", "logging_go_proto"), - "google/storagetransfer/v1/transfer.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"), - "google/storagetransfer/v1/transfer_types.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"), - "google/longrunning/operations.proto": label.New("go_googleapis", "google/longrunning", "longrunning_go_proto"), - "google/container/v1/cluster_service.proto": label.New("go_googleapis", "google/container/v1", "container_go_proto"), - "google/container/v1beta1/cluster_service.proto": label.New("go_googleapis", "google/container/v1beta1", "container_go_proto"), - "google/container/v1alpha1/cluster_service.proto": label.New("go_googleapis", "google/container/v1alpha1", "container_go_proto"), - "google/datastore/v1beta3/datastore.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"), - "google/datastore/v1beta3/query.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"), - "google/datastore/v1beta3/entity.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"), - "google/datastore/v1/datastore.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"), - "google/datastore/v1/query.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"), - "google/datastore/v1/entity.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"), - "google/datastore/admin/v1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1", "admin_go_proto"), - "google/datastore/admin/v1beta1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_go_proto"), "google/bytestream/bytestream.proto": label.New("go_googleapis", "google/bytestream", "bytestream_go_proto"), - "google/iam/v1/iam_policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"), - "google/iam/v1/policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"), - "google/iam/v1/logging/audit_data.proto": label.New("go_googleapis", "google/iam/v1/logging", "logging_go_proto"), - "google/iam/admin/v1/iam.proto": label.New("go_googleapis", "google/iam/admin/v1", "admin_go_proto"), - "google/type/money.proto": label.New("go_googleapis", "google/type", "money_go_proto"), - "google/type/latlng.proto": label.New("go_googleapis", "google/type", "latlng_go_proto"), - "google/type/color.proto": label.New("go_googleapis", "google/type", "color_go_proto"), - "google/type/timeofday.proto": label.New("go_googleapis", "google/type", "timeofday_go_proto"), - "google/type/date.proto": label.New("go_googleapis", "google/type", "date_go_proto"), - "google/type/dayofweek.proto": label.New("go_googleapis", "google/type", "dayofweek_go_proto"), - "google/type/postal_address.proto": label.New("go_googleapis", "google/type", "postaladdress_go_proto"), - "google/devtools/clouderrorreporting/v1beta1/report_errors_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), - "google/devtools/clouderrorreporting/v1beta1/error_group_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), - "google/devtools/clouderrorreporting/v1beta1/error_stats_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), - "google/devtools/clouderrorreporting/v1beta1/common.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), - "google/devtools/resultstore/v2/file.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/resultstore_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/configuration.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/action.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/resultstore_file_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/test_suite.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/file_set.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/coverage.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/coverage_summary.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/configured_target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/invocation.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/resultstore/v2/common.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), - "google/devtools/source/v1/source_context.proto": label.New("go_googleapis", "google/devtools/source/v1", "source_go_proto"), - "google/devtools/remoteexecution/v1test/remote_execution.proto": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_go_proto"), - "google/devtools/cloudbuild/v1/cloudbuild.proto": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_go_proto"), - "google/devtools/sourcerepo/v1/sourcerepo.proto": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_go_proto"), - "google/devtools/remoteworkers/v1test2/worker.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), - "google/devtools/remoteworkers/v1test2/tasks.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), - "google/devtools/remoteworkers/v1test2/bots.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), - "google/devtools/remoteworkers/v1test2/command.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), - "google/devtools/cloudtrace/v1/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_go_proto"), - "google/devtools/cloudtrace/v2/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"), - "google/devtools/cloudtrace/v2/tracing.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"), - "google/devtools/cloudprofiler/v2/profiler.proto": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_go_proto"), - "google/devtools/containeranalysis/v1alpha1/containeranalysis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), - "google/devtools/containeranalysis/v1alpha1/bill_of_materials.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), - "google/devtools/containeranalysis/v1alpha1/provenance.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), - "google/devtools/containeranalysis/v1alpha1/package_vulnerability.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), - "google/devtools/containeranalysis/v1alpha1/source_context.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), - "google/devtools/containeranalysis/v1alpha1/image_basis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), - "google/devtools/build/v1/build_events.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"), - "google/devtools/build/v1/build_status.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"), - "google/devtools/build/v1/publish_build_event.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"), - "google/devtools/clouddebugger/v2/debugger.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"), - "google/devtools/clouddebugger/v2/data.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"), - "google/devtools/clouddebugger/v2/controller.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"), - "google/cloud/resourcemanager/v2/folders.proto": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_go_proto"), + "google/cloud/asset/v1beta1/asset_service.proto": label.New("go_googleapis", "google/cloud/asset/v1beta1", "asset_go_proto"), + "google/cloud/asset/v1beta1/assets.proto": label.New("go_googleapis", "google/cloud/asset/v1beta1", "asset_go_proto"), + "google/cloud/audit/audit_log.proto": label.New("go_googleapis", "google/cloud/audit", "audit_go_proto"), + "google/cloud/automl/v1beta1/annotation_payload.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/classification.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/data_items.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/dataset.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/image.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/io.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/model.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/model_evaluation.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/operations.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/prediction_service.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/service.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/text.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/automl/v1beta1/translation.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_go_proto"), + "google/cloud/bigquery/datatransfer/v1/datatransfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"), + "google/cloud/bigquery/datatransfer/v1/transfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"), + "google/cloud/bigquery/logging/v1/audit_data.proto": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_go_proto"), + "google/cloud/bigquery/storage/v1beta1/avro.proto": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_go_proto"), + "google/cloud/bigquery/storage/v1beta1/read_options.proto": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_go_proto"), + "google/cloud/bigquery/storage/v1beta1/storage.proto": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_go_proto"), + "google/cloud/bigquery/storage/v1beta1/table_reference.proto": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_go_proto"), + "google/cloud/billing/v1/cloud_billing.proto": label.New("go_googleapis", "google/cloud/billing/v1", "billing_go_proto"), + "google/cloud/dataproc/v1/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"), + "google/cloud/dataproc/v1/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"), + "google/cloud/dataproc/v1/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"), + "google/cloud/dataproc/v1beta2/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), + "google/cloud/dataproc/v1beta2/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), + "google/cloud/dataproc/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), + "google/cloud/dataproc/v1beta2/shared.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), + "google/cloud/dataproc/v1beta2/workflow_templates.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), + "google/cloud/dialogflow/v2/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/audio_config.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/document.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/knowledge_base.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/dialogflow/v2beta1/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), + "google/cloud/functions/v1beta2/functions.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"), + "google/cloud/functions/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"), + "google/cloud/iot/v1/device_manager.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"), + "google/cloud/iot/v1/resources.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"), "google/cloud/kms/v1/resources.proto": label.New("go_googleapis", "google/cloud/kms/v1", "kms_go_proto"), "google/cloud/kms/v1/service.proto": label.New("go_googleapis", "google/cloud/kms/v1", "kms_go_proto"), - "google/cloud/runtimeconfig/v1beta1/resources.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"), - "google/cloud/runtimeconfig/v1beta1/runtimeconfig.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"), - "google/cloud/tasks/v2beta2/queue.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), - "google/cloud/tasks/v2beta2/task.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), - "google/cloud/tasks/v2beta2/target.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), - "google/cloud/tasks/v2beta2/cloudtasks.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), + "google/cloud/language/v1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1", "language_go_proto"), + "google/cloud/language/v1beta1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_go_proto"), + "google/cloud/language/v1beta2/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_go_proto"), + "google/cloud/location/locations.proto": label.New("go_googleapis", "google/cloud/location", "location_go_proto"), + "google/cloud/ml/v1/job_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), + "google/cloud/ml/v1/model_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), + "google/cloud/ml/v1/operation_metadata.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), + "google/cloud/ml/v1/prediction_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), + "google/cloud/ml/v1/project_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), + "google/cloud/oslogin/common/common.proto": label.New("go_googleapis", "google/cloud/oslogin/common", "common_go_proto"), "google/cloud/oslogin/v1/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1", "oslogin_go_proto"), "google/cloud/oslogin/v1alpha/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1alpha", "oslogin_go_proto"), - "google/cloud/oslogin/common/common.proto": label.New("go_googleapis", "google/cloud/oslogin/common", "common_go_proto"), "google/cloud/oslogin/v1beta/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1beta", "oslogin_go_proto"), - "google/cloud/dialogflow/v2beta1/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2beta1/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2beta1/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2beta1/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2beta1/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2beta1/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2beta1/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), - "google/cloud/dialogflow/v2/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"), + "google/cloud/redis/v1/cloud_redis.proto": label.New("go_googleapis", "google/cloud/redis/v1", "redis_go_proto"), "google/cloud/redis/v1beta1/cloud_redis.proto": label.New("go_googleapis", "google/cloud/redis/v1beta1", "redis_go_proto"), - "google/cloud/location/locations.proto": label.New("go_googleapis", "google/cloud/location", "location_go_proto"), - "google/cloud/websecurityscanner/v1alpha/finding.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), - "google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), - "google/cloud/websecurityscanner/v1alpha/scan_config.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), - "google/cloud/websecurityscanner/v1alpha/crawled_url.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), - "google/cloud/websecurityscanner/v1alpha/scan_run.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), - "google/cloud/websecurityscanner/v1alpha/web_security_scanner.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), - "google/cloud/websecurityscanner/v1alpha/finding_addon.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), - "google/cloud/language/v1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1", "language_go_proto"), - "google/cloud/language/v1beta2/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_go_proto"), - "google/cloud/language/v1beta1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_go_proto"), - "google/cloud/bigquery/datatransfer/v1/transfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"), - "google/cloud/bigquery/datatransfer/v1/datatransfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"), - "google/cloud/bigquery/logging/v1/audit_data.proto": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_go_proto"), - "google/cloud/vision/v1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), - "google/cloud/vision/v1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), - "google/cloud/vision/v1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), - "google/cloud/vision/v1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), - "google/cloud/vision/v1p2beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), - "google/cloud/vision/v1p2beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), - "google/cloud/vision/v1p2beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), - "google/cloud/vision/v1p2beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), - "google/cloud/vision/v1p1beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), - "google/cloud/vision/v1p1beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), - "google/cloud/vision/v1p1beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), - "google/cloud/vision/v1p1beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), + "google/cloud/resourcemanager/v2/folders.proto": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_go_proto"), + "google/cloud/runtimeconfig/v1beta1/resources.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"), + "google/cloud/runtimeconfig/v1beta1/runtimeconfig.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"), "google/cloud/speech/v1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1", "speech_go_proto"), - "google/cloud/speech/v1beta1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1beta1", "speech_go_proto"), "google/cloud/speech/v1p1beta1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1p1beta1", "speech_go_proto"), - "google/cloud/iot/v1/device_manager.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"), - "google/cloud/iot/v1/resources.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"), - "google/cloud/videointelligence/v1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_go_proto"), - "google/cloud/videointelligence/v1beta2/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_go_proto"), - "google/cloud/videointelligence/v1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_go_proto"), - "google/cloud/videointelligence/v1p1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_go_proto"), - "google/cloud/audit/audit_log.proto": label.New("go_googleapis", "google/cloud/audit", "audit_go_proto"), "google/cloud/support/common.proto": label.New("go_googleapis", "google/cloud/support", "common_go_proto"), "google/cloud/support/v1alpha1/cloud_support.proto": label.New("go_googleapis", "google/cloud/support/v1alpha1", "support_go_proto"), - "google/cloud/ml/v1/operation_metadata.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), - "google/cloud/ml/v1/job_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), - "google/cloud/ml/v1/prediction_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), - "google/cloud/ml/v1/model_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), - "google/cloud/ml/v1/project_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"), + "google/cloud/tasks/v2beta2/cloudtasks.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), + "google/cloud/tasks/v2beta2/queue.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), + "google/cloud/tasks/v2beta2/target.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), + "google/cloud/tasks/v2beta2/task.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"), + "google/cloud/tasks/v2beta3/cloudtasks.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_go_proto"), + "google/cloud/tasks/v2beta3/queue.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_go_proto"), + "google/cloud/tasks/v2beta3/target.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_go_proto"), + "google/cloud/tasks/v2beta3/task.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_go_proto"), "google/cloud/texttospeech/v1/cloud_tts.proto": label.New("go_googleapis", "google/cloud/texttospeech/v1", "texttospeech_go_proto"), "google/cloud/texttospeech/v1beta1/cloud_tts.proto": label.New("go_googleapis", "google/cloud/texttospeech/v1beta1", "texttospeech_go_proto"), - "google/cloud/functions/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"), - "google/cloud/functions/v1beta2/functions.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"), - "google/cloud/billing/v1/cloud_billing.proto": label.New("go_googleapis", "google/cloud/billing/v1", "billing_go_proto"), - "google/cloud/dataproc/v1/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"), - "google/cloud/dataproc/v1/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"), - "google/cloud/dataproc/v1/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"), - "google/cloud/dataproc/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), - "google/cloud/dataproc/v1beta2/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), - "google/cloud/dataproc/v1beta2/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), - "google/cloud/dataproc/v1beta2/workflow_templates.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), - "google/cloud/dataproc/v1beta2/shared.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"), - "google/api/context.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/http.proto": label.New("go_googleapis", "google/api", "annotations_go_proto"), - "google/api/config_change.proto": label.New("go_googleapis", "google/api", "configchange_go_proto"), - "google/api/system_parameter.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/monitoring.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/distribution.proto": label.New("go_googleapis", "google/api", "distribution_go_proto"), - "google/api/endpoint.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/usage.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/monitored_resource.proto": label.New("go_googleapis", "google/api", "monitoredres_go_proto"), - "google/api/annotations.proto": label.New("go_googleapis", "google/api", "annotations_go_proto"), - "google/api/control.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/metric.proto": label.New("go_googleapis", "google/api", "metric_go_proto"), - "google/api/label.proto": label.New("go_googleapis", "google/api", "label_go_proto"), - "google/api/consumer.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/log.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/billing.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/service.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/logging.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/documentation.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/quota.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/auth.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/backend.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/source_info.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"), - "google/api/httpbody.proto": label.New("go_googleapis", "google/api", "httpbody_go_proto"), - "google/api/experimental/authorization_config.proto": label.New("go_googleapis", "google/api/experimental", "api_go_proto"), - "google/api/experimental/experimental.proto": label.New("go_googleapis", "google/api/experimental", "api_go_proto"), - "google/api/servicemanagement/v1/servicemanager.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"), - "google/api/servicemanagement/v1/resources.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"), - "google/api/servicecontrol/v1/quota_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), - "google/api/servicecontrol/v1/distribution.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), - "google/api/servicecontrol/v1/check_error.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), - "google/api/servicecontrol/v1/operation.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), - "google/api/servicecontrol/v1/metric_value.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), - "google/api/servicecontrol/v1/log_entry.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), - "google/api/servicecontrol/v1/service_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"), - "google/pubsub/v1/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1", "pubsub_go_proto"), - "google/pubsub/v1beta2/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1beta2", "pubsub_go_proto"), - "google/spanner/v1/mutation.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), - "google/spanner/v1/spanner.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), - "google/spanner/v1/transaction.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), - "google/spanner/v1/keys.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), - "google/spanner/v1/type.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), - "google/spanner/v1/query_plan.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), - "google/spanner/v1/result_set.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), - "google/spanner/admin/database/v1/spanner_database_admin.proto": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_go_proto"), - "google/spanner/admin/instance/v1/spanner_instance_admin.proto": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_go_proto"), - "google/monitoring/v3/group.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), - "google/monitoring/v3/mutation_record.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), - "google/monitoring/v3/notification.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/cloud/videointelligence/v1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_go_proto"), + "google/cloud/videointelligence/v1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_go_proto"), + "google/cloud/videointelligence/v1beta2/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_go_proto"), + "google/cloud/videointelligence/v1p1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_go_proto"), + "google/cloud/videointelligence/v1p2beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1p2beta1", "videointelligence_go_proto"), + "google/cloud/vision/v1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), + "google/cloud/vision/v1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), + "google/cloud/vision/v1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), + "google/cloud/vision/v1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"), + "google/cloud/vision/v1p1beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), + "google/cloud/vision/v1p1beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), + "google/cloud/vision/v1p1beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), + "google/cloud/vision/v1p1beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"), + "google/cloud/vision/v1p2beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), + "google/cloud/vision/v1p2beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), + "google/cloud/vision/v1p2beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), + "google/cloud/vision/v1p2beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"), + "google/cloud/vision/v1p3beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_go_proto"), + "google/cloud/vision/v1p3beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_go_proto"), + "google/cloud/vision/v1p3beta1/product_search.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_go_proto"), + "google/cloud/vision/v1p3beta1/product_search_service.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_go_proto"), + "google/cloud/vision/v1p3beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_go_proto"), + "google/cloud/vision/v1p3beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_go_proto"), + "google/cloud/websecurityscanner/v1alpha/crawled_url.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), + "google/cloud/websecurityscanner/v1alpha/finding.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), + "google/cloud/websecurityscanner/v1alpha/finding_addon.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), + "google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), + "google/cloud/websecurityscanner/v1alpha/scan_config.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), + "google/cloud/websecurityscanner/v1alpha/scan_run.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), + "google/cloud/websecurityscanner/v1alpha/web_security_scanner.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"), + "google/container/v1/cluster_service.proto": label.New("go_googleapis", "google/container/v1", "container_go_proto"), + "google/container/v1alpha1/cluster_service.proto": label.New("go_googleapis", "google/container/v1alpha1", "container_go_proto"), + "google/container/v1beta1/cluster_service.proto": label.New("go_googleapis", "google/container/v1beta1", "container_go_proto"), + "google/datastore/admin/v1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1", "admin_go_proto"), + "google/datastore/admin/v1/index.proto": label.New("go_googleapis", "google/datastore/admin/v1", "admin_go_proto"), + "google/datastore/admin/v1beta1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_go_proto"), + "google/datastore/v1/datastore.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"), + "google/datastore/v1/entity.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"), + "google/datastore/v1/query.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"), + "google/datastore/v1beta3/datastore.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"), + "google/datastore/v1beta3/entity.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"), + "google/datastore/v1beta3/query.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"), + "google/devtools/build/v1/build_events.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"), + "google/devtools/build/v1/build_status.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"), + "google/devtools/build/v1/publish_build_event.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"), + "google/devtools/cloudbuild/v1/cloudbuild.proto": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_go_proto"), + "google/devtools/clouddebugger/v2/controller.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"), + "google/devtools/clouddebugger/v2/data.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"), + "google/devtools/clouddebugger/v2/debugger.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"), + "google/devtools/clouderrorreporting/v1beta1/common.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), + "google/devtools/clouderrorreporting/v1beta1/error_group_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), + "google/devtools/clouderrorreporting/v1beta1/error_stats_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), + "google/devtools/clouderrorreporting/v1beta1/report_errors_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"), + "google/devtools/cloudprofiler/v2/profiler.proto": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_go_proto"), + "google/devtools/cloudtrace/v1/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_go_proto"), + "google/devtools/cloudtrace/v2/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"), + "google/devtools/cloudtrace/v2/tracing.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"), + "google/devtools/containeranalysis/v1alpha1/bill_of_materials.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), + "google/devtools/containeranalysis/v1alpha1/containeranalysis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), + "google/devtools/containeranalysis/v1alpha1/image_basis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), + "google/devtools/containeranalysis/v1alpha1/package_vulnerability.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), + "google/devtools/containeranalysis/v1alpha1/provenance.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), + "google/devtools/containeranalysis/v1alpha1/source_context.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"), + "google/devtools/containeranalysis/v1beta1/attestation/attestation.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/attestation", "attestation_go_proto"), + "google/devtools/containeranalysis/v1beta1/build/build.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/build", "build_go_proto"), + "google/devtools/containeranalysis/v1beta1/common/common.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/common", "common_go_proto"), + "google/devtools/containeranalysis/v1beta1/containeranalysis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1", "containeranalysis_go_proto"), + "google/devtools/containeranalysis/v1beta1/deployment/deployment.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/deployment", "deployment_go_proto"), + "google/devtools/containeranalysis/v1beta1/discovery/discovery.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/discovery", "discovery_go_proto"), + "google/devtools/containeranalysis/v1beta1/grafeas/grafeas.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/grafeas", "grafeas_go_proto"), + "google/devtools/containeranalysis/v1beta1/image/image.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/image", "image_go_proto"), + "google/devtools/containeranalysis/v1beta1/package/package.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/package", "package_go_proto"), + "google/devtools/containeranalysis/v1beta1/provenance/provenance.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/provenance", "provenance_go_proto"), + "google/devtools/containeranalysis/v1beta1/source/source.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/source", "source_go_proto"), + "google/devtools/containeranalysis/v1beta1/vulnerability/vulnerability.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/vulnerability", "vulnerability_go_proto"), + "google/devtools/remoteexecution/v1test/remote_execution.proto": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_go_proto"), + "google/devtools/remoteworkers/v1test2/bots.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), + "google/devtools/remoteworkers/v1test2/command.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), + "google/devtools/remoteworkers/v1test2/tasks.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), + "google/devtools/remoteworkers/v1test2/worker.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"), + "google/devtools/resultstore/v2/action.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/common.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/configuration.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/configured_target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/coverage.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/coverage_summary.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/file.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/file_set.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/invocation.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/resultstore_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/resultstore_file_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/resultstore/v2/test_suite.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"), + "google/devtools/source/v1/source_context.proto": label.New("go_googleapis", "google/devtools/source/v1", "source_go_proto"), + "google/devtools/sourcerepo/v1/sourcerepo.proto": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_go_proto"), + "google/example/library/v1/library.proto": label.New("go_googleapis", "google/example/library/v1", "library_go_proto"), + "google/firestore/admin/v1beta1/firestore_admin.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"), + "google/firestore/admin/v1beta1/index.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"), + "google/firestore/admin/v1beta2/field.proto": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_go_proto"), + "google/firestore/admin/v1beta2/firestore_admin.proto": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_go_proto"), + "google/firestore/admin/v1beta2/index.proto": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_go_proto"), + "google/firestore/admin/v1beta2/operation.proto": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_go_proto"), + "google/firestore/v1beta1/common.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), + "google/firestore/v1beta1/document.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), + "google/firestore/v1beta1/firestore.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), + "google/firestore/v1beta1/query.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), + "google/firestore/v1beta1/write.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"), + "google/genomics/v1/annotations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/cigar.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/datasets.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/operations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/position.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/range.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/readalignment.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/readgroup.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/readgroupset.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/reads.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/references.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1/variants.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"), + "google/genomics/v1alpha2/pipelines.proto": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_go_proto"), + "google/home/graph/v1/device.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"), + "google/home/graph/v1/homegraph.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"), + "google/iam/admin/v1/iam.proto": label.New("go_googleapis", "google/iam/admin/v1", "admin_go_proto"), + "google/iam/credentials/v1/common.proto": label.New("go_googleapis", "google/iam/credentials/v1", "credentials_go_proto"), + "google/iam/credentials/v1/iamcredentials.proto": label.New("go_googleapis", "google/iam/credentials/v1", "credentials_go_proto"), + "google/iam/v1/iam_policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"), + "google/iam/v1/logging/audit_data.proto": label.New("go_googleapis", "google/iam/v1/logging", "logging_go_proto"), + "google/iam/v1/policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"), + "google/logging/type/http_request.proto": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"), + "google/logging/type/log_severity.proto": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"), + "google/logging/v2/log_entry.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), + "google/logging/v2/logging.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), + "google/logging/v2/logging_config.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), + "google/logging/v2/logging_metrics.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), + "google/longrunning/operations.proto": label.New("go_googleapis", "google/longrunning", "longrunning_go_proto"), + "google/monitoring/v3/alert.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), "google/monitoring/v3/alert_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), - "google/monitoring/v3/uptime_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/common.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/dropped_labels.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/group.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), "google/monitoring/v3/group_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), - "google/monitoring/v3/alert.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), - "google/monitoring/v3/uptime.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), "google/monitoring/v3/metric.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), - "google/monitoring/v3/notification_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), "google/monitoring/v3/metric_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), - "google/monitoring/v3/common.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/mutation_record.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/notification.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/notification_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/span_context.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/uptime.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/monitoring/v3/uptime_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"), + "google/privacy/dlp/v2/dlp.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"), + "google/privacy/dlp/v2/storage.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"), + "google/pubsub/v1/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1", "pubsub_go_proto"), + "google/pubsub/v1beta2/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1beta2", "pubsub_go_proto"), "google/rpc/code.proto": label.New("go_googleapis", "google/rpc", "code_go_proto"), - "google/rpc/status.proto": label.New("go_googleapis", "google/rpc", "status_go_proto"), "google/rpc/error_details.proto": label.New("go_googleapis", "google/rpc", "errdetails_go_proto"), + "google/rpc/status.proto": label.New("go_googleapis", "google/rpc", "status_go_proto"), + "google/spanner/admin/database/v1/spanner_database_admin.proto": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_go_proto"), + "google/spanner/admin/instance/v1/spanner_instance_admin.proto": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_go_proto"), + "google/spanner/v1/keys.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), + "google/spanner/v1/mutation.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), + "google/spanner/v1/query_plan.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), + "google/spanner/v1/result_set.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), + "google/spanner/v1/spanner.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), + "google/spanner/v1/transaction.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), + "google/spanner/v1/type.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"), + "google/storagetransfer/v1/transfer.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"), + "google/storagetransfer/v1/transfer_types.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"), "google/streetview/publish/v1/resources.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_go_proto"), "google/streetview/publish/v1/rpcmessages.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_go_proto"), "google/streetview/publish/v1/streetview_publish.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_go_proto"), - "google/logging/v2/logging_metrics.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), - "google/logging/v2/logging_config.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), - "google/logging/v2/log_entry.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), - "google/logging/v2/logging.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"), - "google/logging/type/log_severity.proto": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"), - "google/logging/type/http_request.proto": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"), + "google/type/color.proto": label.New("go_googleapis", "google/type", "color_go_proto"), + "google/type/date.proto": label.New("go_googleapis", "google/type", "date_go_proto"), + "google/type/dayofweek.proto": label.New("go_googleapis", "google/type", "dayofweek_go_proto"), + "google/type/latlng.proto": label.New("go_googleapis", "google/type", "latlng_go_proto"), + "google/type/money.proto": label.New("go_googleapis", "google/type", "money_go_proto"), + "google/type/postal_address.proto": label.New("go_googleapis", "google/type", "postaladdress_go_proto"), + "google/type/timeofday.proto": label.New("go_googleapis", "google/type", "timeofday_go_proto"), + "google/watcher/v1/watch.proto": label.New("go_googleapis", "google/watcher/v1", "watcher_go_proto"), } diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/resolve.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/resolve.go index e1d3098d673bd..283289242e10d 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/resolve.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go/resolve.go @@ -91,7 +91,14 @@ func (gl *goLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repos.Rem log.Print(err) } if !deps.IsEmpty() { - r.SetAttr("deps", deps) + if r.Kind() == "go_proto_library" { + // protos may import the same library multiple times by different names, + // so we need to de-duplicate them. Protos are not platform-specific, + // so it's safe to just flatten them. + r.SetAttr("deps", deps.Flat()) + } else { + r.SetAttr("deps", deps) + } } } @@ -115,6 +122,10 @@ func resolveGo(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r return label.NoLabel, skipImportError } + if l, ok := resolve.FindRuleWithOverride(c, resolve.ImportSpec{Lang: "go", Imp: imp}, "go"); ok { + return l, nil + } + if pc.Mode.ShouldUseKnownImports() { // These are commonly used libraries that depend on Well Known Types. // They depend on the generated versions of these protos to avoid conflicts. @@ -129,6 +140,8 @@ func resolveGo(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r return label.New("com_github_golang_protobuf", "descriptor", "go_default_library_gen"), nil case "github.com/golang/protobuf/ptypes": return label.New("com_github_golang_protobuf", "ptypes", "go_default_library_gen"), nil + case "google.golang.org/grpc": + return label.New("org_golang_google_grpc", "", "go_default_library"), nil } if l, ok := knownGoProtoImports[imp]; ok { return l, nil @@ -236,6 +249,10 @@ func resolveProto(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache return label.NoLabel, skipImportError } + if l, ok := resolve.FindRuleWithOverride(c, resolve.ImportSpec{Lang: "proto", Imp: imp}, "go"); ok { + return l, nil + } + if l, ok := knownProtoImports[imp]; ok && pc.Mode.ShouldUseKnownImports() { if l.Equal(from) { return label.NoLabel, skipImportError diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/known_imports.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/known_imports.go index 525a58dc416cf..344f911e1d359 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/known_imports.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/known_imports.go @@ -20,281 +20,347 @@ var knownImports = map[string]label.Label{ "google/protobuf/timestamp.proto": label.New("com_google_protobuf", "", "timestamp_proto"), "google/protobuf/type.proto": label.New("com_google_protobuf", "", "type_proto"), "google/protobuf/wrappers.proto": label.New("com_google_protobuf", "", "wrappers_proto"), - "google/assistant/embedded/v1alpha2/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_proto"), + "google/api/annotations.proto": label.New("go_googleapis", "google/api", "annotations_proto"), + "google/api/auth.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/backend.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/billing.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/config_change.proto": label.New("go_googleapis", "google/api", "configchange_proto"), + "google/api/consumer.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/context.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/control.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/distribution.proto": label.New("go_googleapis", "google/api", "distribution_proto"), + "google/api/documentation.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/endpoint.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/experimental/authorization_config.proto": label.New("go_googleapis", "google/api", "api_proto"), + "google/api/experimental/experimental.proto": label.New("go_googleapis", "google/api", "api_proto"), + "google/api/expr/v1alpha1/cel_service.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_proto"), + "google/api/expr/v1alpha1/checked.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_proto"), + "google/api/expr/v1alpha1/eval.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_proto"), + "google/api/expr/v1alpha1/explain.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_proto"), + "google/api/expr/v1alpha1/syntax.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_proto"), + "google/api/expr/v1alpha1/value.proto": label.New("go_googleapis", "google/api/expr/v1alpha1", "expr_proto"), + "google/api/expr/v1beta1/decl.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_proto"), + "google/api/expr/v1beta1/eval.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_proto"), + "google/api/expr/v1beta1/expr.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_proto"), + "google/api/expr/v1beta1/source.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_proto"), + "google/api/expr/v1beta1/value.proto": label.New("go_googleapis", "google/api/expr/v1beta1", "expr_proto"), + "google/api/http.proto": label.New("go_googleapis", "google/api", "annotations_proto"), + "google/api/httpbody.proto": label.New("go_googleapis", "google/api", "httpbody_proto"), + "google/api/label.proto": label.New("go_googleapis", "google/api", "label_proto"), + "google/api/launch_stage.proto": label.New("go_googleapis", "google/api", "api_proto"), + "google/api/log.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/logging.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/metric.proto": label.New("go_googleapis", "google/api", "metric_proto"), + "google/api/monitored_resource.proto": label.New("go_googleapis", "google/api", "monitoredres_proto"), + "google/api/monitoring.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/quota.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/service.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/servicecontrol/v1/check_error.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), + "google/api/servicecontrol/v1/distribution.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), + "google/api/servicecontrol/v1/log_entry.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), + "google/api/servicecontrol/v1/metric_value.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), + "google/api/servicecontrol/v1/operation.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), + "google/api/servicecontrol/v1/quota_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), + "google/api/servicecontrol/v1/service_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), + "google/api/servicemanagement/v1/resources.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_proto"), + "google/api/servicemanagement/v1/servicemanager.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_proto"), + "google/api/source_info.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/system_parameter.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/api/usage.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), + "google/appengine/legacy/audit_data.proto": label.New("go_googleapis", "google/appengine/legacy", "legacy_proto"), + "google/appengine/logging/v1/request_log.proto": label.New("go_googleapis", "google/appengine/logging/v1", "logging_proto"), + "google/appengine/v1/app_yaml.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/appengine.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/application.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/audit_data.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/deploy.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/instance.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/location.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/operation.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/service.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), + "google/appengine/v1/version.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), "google/assistant/embedded/v1alpha1/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha1", "embedded_proto"), - "google/home/graph/v1/device.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_proto"), - "google/home/graph/v1/homegraph.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_proto"), - "google/genomics/v1/operations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/variants.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/position.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/references.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/cigar.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/datasets.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/readalignment.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/annotations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/reads.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/readgroup.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/readgroupset.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1/range.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), - "google/genomics/v1alpha2/pipelines.proto": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_proto"), - "google/bigtable/v1/bigtable_service_messages.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"), - "google/bigtable/v1/bigtable_service.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"), - "google/bigtable/v1/bigtable_data.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"), + "google/assistant/embedded/v1alpha2/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_proto"), "google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_proto"), - "google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_proto"), "google/bigtable/admin/cluster/v1/bigtable_cluster_service.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_proto"), + "google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_proto"), + "google/bigtable/admin/table/v1/bigtable_table_data.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"), + "google/bigtable/admin/table/v1/bigtable_table_service.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"), + "google/bigtable/admin/table/v1/bigtable_table_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"), "google/bigtable/admin/v2/bigtable_instance_admin.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"), - "google/bigtable/admin/v2/instance.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"), - "google/bigtable/admin/v2/table.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"), "google/bigtable/admin/v2/bigtable_table_admin.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"), "google/bigtable/admin/v2/common.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"), - "google/bigtable/admin/table/v1/bigtable_table_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"), - "google/bigtable/admin/table/v1/bigtable_table_service.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"), - "google/bigtable/admin/table/v1/bigtable_table_data.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"), + "google/bigtable/admin/v2/instance.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"), + "google/bigtable/admin/v2/table.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"), + "google/bigtable/v1/bigtable_data.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"), + "google/bigtable/v1/bigtable_service.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"), + "google/bigtable/v1/bigtable_service_messages.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"), "google/bigtable/v2/bigtable.proto": label.New("go_googleapis", "google/bigtable/v2", "bigtable_proto"), "google/bigtable/v2/data.proto": label.New("go_googleapis", "google/bigtable/v2", "bigtable_proto"), - "google/privacy/dlp/v2/storage.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_proto"), - "google/privacy/dlp/v2/dlp.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_proto"), - "google/watcher/v1/watch.proto": label.New("go_googleapis", "google/watcher/v1", "watcher_proto"), - "google/firestore/admin/v1beta1/firestore_admin.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_proto"), - "google/firestore/admin/v1beta1/index.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_proto"), - "google/firestore/v1beta1/write.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), - "google/firestore/v1beta1/document.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), - "google/firestore/v1beta1/firestore.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), - "google/firestore/v1beta1/query.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), - "google/firestore/v1beta1/common.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), - "google/example/library/v1/library.proto": label.New("go_googleapis", "google/example/library/v1", "library_proto"), - "google/appengine/v1/instance.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/audit_data.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/appengine.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/application.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/operation.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/app_yaml.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/location.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/service.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/deploy.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/v1/version.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"), - "google/appengine/legacy/audit_data.proto": label.New("go_googleapis", "google/appengine/legacy", "legacy_proto"), - "google/appengine/logging/v1/request_log.proto": label.New("go_googleapis", "google/appengine/logging/v1", "logging_proto"), - "google/storagetransfer/v1/transfer.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_proto"), - "google/storagetransfer/v1/transfer_types.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_proto"), - "google/longrunning/operations.proto": label.New("go_googleapis", "google/longrunning", "longrunning_proto"), - "google/container/v1/cluster_service.proto": label.New("go_googleapis", "google/container/v1", "container_proto"), - "google/container/v1beta1/cluster_service.proto": label.New("go_googleapis", "google/container/v1beta1", "container_proto"), - "google/container/v1alpha1/cluster_service.proto": label.New("go_googleapis", "google/container/v1alpha1", "container_proto"), - "google/datastore/v1beta3/datastore.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"), - "google/datastore/v1beta3/query.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"), - "google/datastore/v1beta3/entity.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"), - "google/datastore/v1/datastore.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"), - "google/datastore/v1/query.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"), - "google/datastore/v1/entity.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"), - "google/datastore/admin/v1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1", "admin_proto"), - "google/datastore/admin/v1beta1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_proto"), "google/bytestream/bytestream.proto": label.New("go_googleapis", "google/bytestream", "bytestream_proto"), - "google/iam/v1/iam_policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_proto"), - "google/iam/v1/policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_proto"), - "google/iam/v1/logging/audit_data.proto": label.New("go_googleapis", "google/iam/v1/logging", "logging_proto"), - "google/iam/admin/v1/iam.proto": label.New("go_googleapis", "google/iam/admin/v1", "admin_proto"), - "google/type/money.proto": label.New("go_googleapis", "google/type", "money_proto"), - "google/type/latlng.proto": label.New("go_googleapis", "google/type", "latlng_proto"), - "google/type/color.proto": label.New("go_googleapis", "google/type", "color_proto"), - "google/type/timeofday.proto": label.New("go_googleapis", "google/type", "timeofday_proto"), - "google/type/date.proto": label.New("go_googleapis", "google/type", "date_proto"), - "google/type/dayofweek.proto": label.New("go_googleapis", "google/type", "dayofweek_proto"), - "google/type/postal_address.proto": label.New("go_googleapis", "google/type", "postaladdress_proto"), - "google/devtools/clouderrorreporting/v1beta1/report_errors_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"), - "google/devtools/clouderrorreporting/v1beta1/error_group_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"), - "google/devtools/clouderrorreporting/v1beta1/error_stats_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"), - "google/devtools/clouderrorreporting/v1beta1/common.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"), - "google/devtools/resultstore/v2/file.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/resultstore_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/configuration.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/action.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/resultstore_file_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/test_suite.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/file_set.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/coverage.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/coverage_summary.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/configured_target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/invocation.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/resultstore/v2/common.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), - "google/devtools/source/v1/source_context.proto": label.New("go_googleapis", "google/devtools/source/v1", "source_proto"), - "google/devtools/remoteexecution/v1test/remote_execution.proto": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_proto"), - "google/devtools/cloudbuild/v1/cloudbuild.proto": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_proto"), - "google/devtools/sourcerepo/v1/sourcerepo.proto": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_proto"), - "google/devtools/remoteworkers/v1test2/worker.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"), - "google/devtools/remoteworkers/v1test2/tasks.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"), - "google/devtools/remoteworkers/v1test2/bots.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"), - "google/devtools/remoteworkers/v1test2/command.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"), - "google/devtools/cloudtrace/v1/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_proto"), - "google/devtools/cloudtrace/v2/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_proto"), - "google/devtools/cloudtrace/v2/tracing.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_proto"), - "google/devtools/cloudprofiler/v2/profiler.proto": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_proto"), - "google/devtools/containeranalysis/v1alpha1/containeranalysis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), - "google/devtools/containeranalysis/v1alpha1/bill_of_materials.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), - "google/devtools/containeranalysis/v1alpha1/provenance.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), - "google/devtools/containeranalysis/v1alpha1/package_vulnerability.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), - "google/devtools/containeranalysis/v1alpha1/source_context.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), - "google/devtools/containeranalysis/v1alpha1/image_basis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), - "google/devtools/build/v1/build_events.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"), - "google/devtools/build/v1/build_status.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"), - "google/devtools/build/v1/publish_build_event.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"), - "google/devtools/clouddebugger/v2/debugger.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"), - "google/devtools/clouddebugger/v2/data.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"), - "google/devtools/clouddebugger/v2/controller.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"), - "google/cloud/resourcemanager/v2/folders.proto": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_proto"), + "google/cloud/asset/v1beta1/asset_service.proto": label.New("go_googleapis", "google/cloud/asset/v1beta1", "asset_proto"), + "google/cloud/asset/v1beta1/assets.proto": label.New("go_googleapis", "google/cloud/asset/v1beta1", "asset_proto"), + "google/cloud/audit/audit_log.proto": label.New("go_googleapis", "google/cloud/audit", "audit_proto"), + "google/cloud/automl/v1beta1/annotation_payload.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/classification.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/data_items.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/dataset.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/image.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/io.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/model.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/model_evaluation.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/operations.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/prediction_service.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/service.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/text.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/automl/v1beta1/translation.proto": label.New("go_googleapis", "google/cloud/automl/v1beta1", "automl_proto"), + "google/cloud/bigquery/datatransfer/v1/datatransfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_proto"), + "google/cloud/bigquery/datatransfer/v1/transfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_proto"), + "google/cloud/bigquery/logging/v1/audit_data.proto": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_proto"), + "google/cloud/bigquery/storage/v1beta1/avro.proto": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_proto"), + "google/cloud/bigquery/storage/v1beta1/read_options.proto": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_proto"), + "google/cloud/bigquery/storage/v1beta1/storage.proto": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_proto"), + "google/cloud/bigquery/storage/v1beta1/table_reference.proto": label.New("go_googleapis", "google/cloud/bigquery/storage/v1beta1", "storage_proto"), + "google/cloud/billing/v1/cloud_billing.proto": label.New("go_googleapis", "google/cloud/billing/v1", "billing_proto"), + "google/cloud/dataproc/v1/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"), + "google/cloud/dataproc/v1/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"), + "google/cloud/dataproc/v1/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"), + "google/cloud/dataproc/v1beta2/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), + "google/cloud/dataproc/v1beta2/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), + "google/cloud/dataproc/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), + "google/cloud/dataproc/v1beta2/shared.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), + "google/cloud/dataproc/v1beta2/workflow_templates.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), + "google/cloud/dialogflow/v2/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), + "google/cloud/dialogflow/v2/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), + "google/cloud/dialogflow/v2/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), + "google/cloud/dialogflow/v2/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), + "google/cloud/dialogflow/v2/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), + "google/cloud/dialogflow/v2/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), + "google/cloud/dialogflow/v2/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/audio_config.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/document.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/knowledge_base.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/dialogflow/v2beta1/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), + "google/cloud/functions/v1beta2/functions.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_proto"), + "google/cloud/functions/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_proto"), + "google/cloud/iot/v1/device_manager.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_proto"), + "google/cloud/iot/v1/resources.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_proto"), "google/cloud/kms/v1/resources.proto": label.New("go_googleapis", "google/cloud/kms/v1", "kms_proto"), "google/cloud/kms/v1/service.proto": label.New("go_googleapis", "google/cloud/kms/v1", "kms_proto"), - "google/cloud/runtimeconfig/v1beta1/resources.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_proto"), - "google/cloud/runtimeconfig/v1beta1/runtimeconfig.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_proto"), - "google/cloud/tasks/v2beta2/queue.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"), - "google/cloud/tasks/v2beta2/task.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"), - "google/cloud/tasks/v2beta2/target.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"), - "google/cloud/tasks/v2beta2/cloudtasks.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"), + "google/cloud/language/v1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1", "language_proto"), + "google/cloud/language/v1beta1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_proto"), + "google/cloud/language/v1beta2/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_proto"), + "google/cloud/location/locations.proto": label.New("go_googleapis", "google/cloud/location", "location_proto"), + "google/cloud/ml/v1/job_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), + "google/cloud/ml/v1/model_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), + "google/cloud/ml/v1/operation_metadata.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), + "google/cloud/ml/v1/prediction_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), + "google/cloud/ml/v1/project_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), + "google/cloud/oslogin/common/common.proto": label.New("go_googleapis", "google/cloud/oslogin/common", "common_proto"), "google/cloud/oslogin/v1/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1", "oslogin_proto"), "google/cloud/oslogin/v1alpha/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1alpha", "oslogin_proto"), - "google/cloud/oslogin/common/common.proto": label.New("go_googleapis", "google/cloud/oslogin/common", "common_proto"), "google/cloud/oslogin/v1beta/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1beta", "oslogin_proto"), - "google/cloud/dialogflow/v2beta1/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), - "google/cloud/dialogflow/v2beta1/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), - "google/cloud/dialogflow/v2beta1/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), - "google/cloud/dialogflow/v2beta1/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), - "google/cloud/dialogflow/v2beta1/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), - "google/cloud/dialogflow/v2beta1/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), - "google/cloud/dialogflow/v2beta1/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"), - "google/cloud/dialogflow/v2/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), - "google/cloud/dialogflow/v2/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), - "google/cloud/dialogflow/v2/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), - "google/cloud/dialogflow/v2/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), - "google/cloud/dialogflow/v2/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), - "google/cloud/dialogflow/v2/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), - "google/cloud/dialogflow/v2/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"), + "google/cloud/redis/v1/cloud_redis.proto": label.New("go_googleapis", "google/cloud/redis/v1", "redis_proto"), "google/cloud/redis/v1beta1/cloud_redis.proto": label.New("go_googleapis", "google/cloud/redis/v1beta1", "redis_proto"), - "google/cloud/location/locations.proto": label.New("go_googleapis", "google/cloud/location", "location_proto"), - "google/cloud/websecurityscanner/v1alpha/finding.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), - "google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), - "google/cloud/websecurityscanner/v1alpha/scan_config.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), - "google/cloud/websecurityscanner/v1alpha/crawled_url.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), - "google/cloud/websecurityscanner/v1alpha/scan_run.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), - "google/cloud/websecurityscanner/v1alpha/web_security_scanner.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), - "google/cloud/websecurityscanner/v1alpha/finding_addon.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), - "google/cloud/language/v1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1", "language_proto"), - "google/cloud/language/v1beta2/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_proto"), - "google/cloud/language/v1beta1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_proto"), - "google/cloud/bigquery/datatransfer/v1/transfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_proto"), - "google/cloud/bigquery/datatransfer/v1/datatransfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_proto"), - "google/cloud/bigquery/logging/v1/audit_data.proto": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_proto"), - "google/cloud/vision/v1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"), - "google/cloud/vision/v1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"), - "google/cloud/vision/v1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"), - "google/cloud/vision/v1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"), - "google/cloud/vision/v1p2beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"), - "google/cloud/vision/v1p2beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"), - "google/cloud/vision/v1p2beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"), - "google/cloud/vision/v1p2beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"), - "google/cloud/vision/v1p1beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"), - "google/cloud/vision/v1p1beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"), - "google/cloud/vision/v1p1beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"), - "google/cloud/vision/v1p1beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"), + "google/cloud/resourcemanager/v2/folders.proto": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_proto"), + "google/cloud/runtimeconfig/v1beta1/resources.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_proto"), + "google/cloud/runtimeconfig/v1beta1/runtimeconfig.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_proto"), "google/cloud/speech/v1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1", "speech_proto"), - "google/cloud/speech/v1beta1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1beta1", "speech_proto"), "google/cloud/speech/v1p1beta1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1p1beta1", "speech_proto"), - "google/cloud/iot/v1/device_manager.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_proto"), - "google/cloud/iot/v1/resources.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_proto"), - "google/cloud/videointelligence/v1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_proto"), - "google/cloud/videointelligence/v1beta2/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_proto"), - "google/cloud/videointelligence/v1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_proto"), - "google/cloud/videointelligence/v1p1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_proto"), - "google/cloud/audit/audit_log.proto": label.New("go_googleapis", "google/cloud/audit", "audit_proto"), "google/cloud/support/common.proto": label.New("go_googleapis", "google/cloud/support", "common_proto"), "google/cloud/support/v1alpha1/cloud_support.proto": label.New("go_googleapis", "google/cloud/support/v1alpha1", "support_proto"), - "google/cloud/ml/v1/operation_metadata.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), - "google/cloud/ml/v1/job_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), - "google/cloud/ml/v1/prediction_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), - "google/cloud/ml/v1/model_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), - "google/cloud/ml/v1/project_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"), + "google/cloud/tasks/v2beta2/cloudtasks.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"), + "google/cloud/tasks/v2beta2/queue.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"), + "google/cloud/tasks/v2beta2/target.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"), + "google/cloud/tasks/v2beta2/task.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"), + "google/cloud/tasks/v2beta3/cloudtasks.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_proto"), + "google/cloud/tasks/v2beta3/queue.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_proto"), + "google/cloud/tasks/v2beta3/target.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_proto"), + "google/cloud/tasks/v2beta3/task.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta3", "tasks_proto"), "google/cloud/texttospeech/v1/cloud_tts.proto": label.New("go_googleapis", "google/cloud/texttospeech/v1", "texttospeech_proto"), "google/cloud/texttospeech/v1beta1/cloud_tts.proto": label.New("go_googleapis", "google/cloud/texttospeech/v1beta1", "texttospeech_proto"), - "google/cloud/functions/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_proto"), - "google/cloud/functions/v1beta2/functions.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_proto"), - "google/cloud/billing/v1/cloud_billing.proto": label.New("go_googleapis", "google/cloud/billing/v1", "billing_proto"), - "google/cloud/dataproc/v1/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"), - "google/cloud/dataproc/v1/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"), - "google/cloud/dataproc/v1/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"), - "google/cloud/dataproc/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), - "google/cloud/dataproc/v1beta2/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), - "google/cloud/dataproc/v1beta2/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), - "google/cloud/dataproc/v1beta2/workflow_templates.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), - "google/cloud/dataproc/v1beta2/shared.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"), - "google/api/context.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/http.proto": label.New("go_googleapis", "google/api", "annotations_proto"), - "google/api/config_change.proto": label.New("go_googleapis", "google/api", "configchange_proto"), - "google/api/system_parameter.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/monitoring.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/distribution.proto": label.New("go_googleapis", "google/api", "distribution_proto"), - "google/api/endpoint.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/usage.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/monitored_resource.proto": label.New("go_googleapis", "google/api", "monitoredres_proto"), - "google/api/annotations.proto": label.New("go_googleapis", "google/api", "annotations_proto"), - "google/api/control.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/metric.proto": label.New("go_googleapis", "google/api", "metric_proto"), - "google/api/label.proto": label.New("go_googleapis", "google/api", "label_proto"), - "google/api/consumer.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/log.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/billing.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/service.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/logging.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/documentation.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/quota.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/auth.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/backend.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/source_info.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"), - "google/api/httpbody.proto": label.New("go_googleapis", "google/api", "httpbody_proto"), - "google/api/experimental/authorization_config.proto": label.New("go_googleapis", "google/api/experimental", "api_proto"), - "google/api/experimental/experimental.proto": label.New("go_googleapis", "google/api/experimental", "api_proto"), - "google/api/servicemanagement/v1/servicemanager.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_proto"), - "google/api/servicemanagement/v1/resources.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_proto"), - "google/api/servicecontrol/v1/quota_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), - "google/api/servicecontrol/v1/distribution.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), - "google/api/servicecontrol/v1/check_error.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), - "google/api/servicecontrol/v1/operation.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), - "google/api/servicecontrol/v1/metric_value.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), - "google/api/servicecontrol/v1/log_entry.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), - "google/api/servicecontrol/v1/service_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"), - "google/pubsub/v1/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1", "pubsub_proto"), - "google/pubsub/v1beta2/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1beta2", "pubsub_proto"), - "google/spanner/v1/mutation.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), - "google/spanner/v1/spanner.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), - "google/spanner/v1/transaction.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), - "google/spanner/v1/keys.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), - "google/spanner/v1/type.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), - "google/spanner/v1/query_plan.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), - "google/spanner/v1/result_set.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), - "google/spanner/admin/database/v1/spanner_database_admin.proto": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_proto"), - "google/spanner/admin/instance/v1/spanner_instance_admin.proto": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_proto"), - "google/monitoring/v3/group.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), - "google/monitoring/v3/mutation_record.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), - "google/monitoring/v3/notification.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/cloud/videointelligence/v1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_proto"), + "google/cloud/videointelligence/v1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_proto"), + "google/cloud/videointelligence/v1beta2/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_proto"), + "google/cloud/videointelligence/v1p1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_proto"), + "google/cloud/videointelligence/v1p2beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1p2beta1", "videointelligence_proto"), + "google/cloud/vision/v1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"), + "google/cloud/vision/v1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"), + "google/cloud/vision/v1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"), + "google/cloud/vision/v1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"), + "google/cloud/vision/v1p1beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"), + "google/cloud/vision/v1p1beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"), + "google/cloud/vision/v1p1beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"), + "google/cloud/vision/v1p1beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"), + "google/cloud/vision/v1p2beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"), + "google/cloud/vision/v1p2beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"), + "google/cloud/vision/v1p2beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"), + "google/cloud/vision/v1p2beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"), + "google/cloud/vision/v1p3beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_proto"), + "google/cloud/vision/v1p3beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_proto"), + "google/cloud/vision/v1p3beta1/product_search.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_proto"), + "google/cloud/vision/v1p3beta1/product_search_service.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_proto"), + "google/cloud/vision/v1p3beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_proto"), + "google/cloud/vision/v1p3beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p3beta1", "vision_proto"), + "google/cloud/websecurityscanner/v1alpha/crawled_url.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), + "google/cloud/websecurityscanner/v1alpha/finding.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), + "google/cloud/websecurityscanner/v1alpha/finding_addon.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), + "google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), + "google/cloud/websecurityscanner/v1alpha/scan_config.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), + "google/cloud/websecurityscanner/v1alpha/scan_run.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), + "google/cloud/websecurityscanner/v1alpha/web_security_scanner.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"), + "google/container/v1/cluster_service.proto": label.New("go_googleapis", "google/container/v1", "container_proto"), + "google/container/v1alpha1/cluster_service.proto": label.New("go_googleapis", "google/container/v1alpha1", "container_proto"), + "google/container/v1beta1/cluster_service.proto": label.New("go_googleapis", "google/container/v1beta1", "container_proto"), + "google/datastore/admin/v1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1", "admin_proto"), + "google/datastore/admin/v1/index.proto": label.New("go_googleapis", "google/datastore/admin/v1", "admin_proto"), + "google/datastore/admin/v1beta1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_proto"), + "google/datastore/v1/datastore.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"), + "google/datastore/v1/entity.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"), + "google/datastore/v1/query.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"), + "google/datastore/v1beta3/datastore.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"), + "google/datastore/v1beta3/entity.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"), + "google/datastore/v1beta3/query.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"), + "google/devtools/build/v1/build_events.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"), + "google/devtools/build/v1/build_status.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"), + "google/devtools/build/v1/publish_build_event.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"), + "google/devtools/cloudbuild/v1/cloudbuild.proto": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_proto"), + "google/devtools/clouddebugger/v2/controller.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"), + "google/devtools/clouddebugger/v2/data.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"), + "google/devtools/clouddebugger/v2/debugger.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"), + "google/devtools/clouderrorreporting/v1beta1/common.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"), + "google/devtools/clouderrorreporting/v1beta1/error_group_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"), + "google/devtools/clouderrorreporting/v1beta1/error_stats_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"), + "google/devtools/clouderrorreporting/v1beta1/report_errors_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"), + "google/devtools/cloudprofiler/v2/profiler.proto": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_proto"), + "google/devtools/cloudtrace/v1/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_proto"), + "google/devtools/cloudtrace/v2/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_proto"), + "google/devtools/cloudtrace/v2/tracing.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_proto"), + "google/devtools/containeranalysis/v1alpha1/bill_of_materials.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), + "google/devtools/containeranalysis/v1alpha1/containeranalysis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), + "google/devtools/containeranalysis/v1alpha1/image_basis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), + "google/devtools/containeranalysis/v1alpha1/package_vulnerability.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), + "google/devtools/containeranalysis/v1alpha1/provenance.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), + "google/devtools/containeranalysis/v1alpha1/source_context.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"), + "google/devtools/containeranalysis/v1beta1/attestation/attestation.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/attestation", "attestation_proto"), + "google/devtools/containeranalysis/v1beta1/build/build.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/build", "build_proto"), + "google/devtools/containeranalysis/v1beta1/common/common.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/common", "common_proto"), + "google/devtools/containeranalysis/v1beta1/containeranalysis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1", "containeranalysis_proto"), + "google/devtools/containeranalysis/v1beta1/deployment/deployment.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/deployment", "deployment_proto"), + "google/devtools/containeranalysis/v1beta1/discovery/discovery.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/discovery", "discovery_proto"), + "google/devtools/containeranalysis/v1beta1/grafeas/grafeas.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/grafeas", "grafeas_proto"), + "google/devtools/containeranalysis/v1beta1/image/image.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/image", "image_proto"), + "google/devtools/containeranalysis/v1beta1/package/package.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/package", "package_proto"), + "google/devtools/containeranalysis/v1beta1/provenance/provenance.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/provenance", "provenance_proto"), + "google/devtools/containeranalysis/v1beta1/source/source.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/source", "source_proto"), + "google/devtools/containeranalysis/v1beta1/vulnerability/vulnerability.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1beta1/vulnerability", "vulnerability_proto"), + "google/devtools/remoteexecution/v1test/remote_execution.proto": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_proto"), + "google/devtools/remoteworkers/v1test2/bots.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"), + "google/devtools/remoteworkers/v1test2/command.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"), + "google/devtools/remoteworkers/v1test2/tasks.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"), + "google/devtools/remoteworkers/v1test2/worker.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"), + "google/devtools/resultstore/v2/action.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/common.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/configuration.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/configured_target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/coverage.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/coverage_summary.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/file.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/file_set.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/invocation.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/resultstore_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/resultstore_file_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/resultstore/v2/test_suite.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"), + "google/devtools/source/v1/source_context.proto": label.New("go_googleapis", "google/devtools/source/v1", "source_proto"), + "google/devtools/sourcerepo/v1/sourcerepo.proto": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_proto"), + "google/example/library/v1/library.proto": label.New("go_googleapis", "google/example/library/v1", "library_proto"), + "google/firestore/admin/v1beta1/firestore_admin.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_proto"), + "google/firestore/admin/v1beta1/index.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_proto"), + "google/firestore/admin/v1beta2/field.proto": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_proto"), + "google/firestore/admin/v1beta2/firestore_admin.proto": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_proto"), + "google/firestore/admin/v1beta2/index.proto": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_proto"), + "google/firestore/admin/v1beta2/operation.proto": label.New("go_googleapis", "google/firestore/admin/v1beta2", "admin_proto"), + "google/firestore/v1beta1/common.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), + "google/firestore/v1beta1/document.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), + "google/firestore/v1beta1/firestore.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), + "google/firestore/v1beta1/query.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), + "google/firestore/v1beta1/write.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"), + "google/genomics/v1/annotations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/cigar.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/datasets.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/operations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/position.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/range.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/readalignment.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/readgroup.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/readgroupset.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/reads.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/references.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1/variants.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"), + "google/genomics/v1alpha2/pipelines.proto": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_proto"), + "google/home/graph/v1/device.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_proto"), + "google/home/graph/v1/homegraph.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_proto"), + "google/iam/admin/v1/iam.proto": label.New("go_googleapis", "google/iam/admin/v1", "admin_proto"), + "google/iam/credentials/v1/common.proto": label.New("go_googleapis", "google/iam/credentials/v1", "credentials_proto"), + "google/iam/credentials/v1/iamcredentials.proto": label.New("go_googleapis", "google/iam/credentials/v1", "credentials_proto"), + "google/iam/v1/iam_policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_proto"), + "google/iam/v1/logging/audit_data.proto": label.New("go_googleapis", "google/iam/v1/logging", "logging_proto"), + "google/iam/v1/policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_proto"), + "google/logging/type/http_request.proto": label.New("go_googleapis", "google/logging/type", "ltype_proto"), + "google/logging/type/log_severity.proto": label.New("go_googleapis", "google/logging/type", "ltype_proto"), + "google/logging/v2/log_entry.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"), + "google/logging/v2/logging.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"), + "google/logging/v2/logging_config.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"), + "google/logging/v2/logging_metrics.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"), + "google/longrunning/operations.proto": label.New("go_googleapis", "google/longrunning", "longrunning_proto"), + "google/monitoring/v3/alert.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), "google/monitoring/v3/alert_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), - "google/monitoring/v3/uptime_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/common.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/dropped_labels.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/group.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), "google/monitoring/v3/group_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), - "google/monitoring/v3/alert.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), - "google/monitoring/v3/uptime.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), "google/monitoring/v3/metric.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), - "google/monitoring/v3/notification_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), "google/monitoring/v3/metric_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), - "google/monitoring/v3/common.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/mutation_record.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/notification.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/notification_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/span_context.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/uptime.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/monitoring/v3/uptime_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"), + "google/privacy/dlp/v2/dlp.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_proto"), + "google/privacy/dlp/v2/storage.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_proto"), + "google/pubsub/v1/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1", "pubsub_proto"), + "google/pubsub/v1beta2/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1beta2", "pubsub_proto"), "google/rpc/code.proto": label.New("go_googleapis", "google/rpc", "code_proto"), - "google/rpc/status.proto": label.New("go_googleapis", "google/rpc", "status_proto"), "google/rpc/error_details.proto": label.New("go_googleapis", "google/rpc", "errdetails_proto"), + "google/rpc/status.proto": label.New("go_googleapis", "google/rpc", "status_proto"), + "google/spanner/admin/database/v1/spanner_database_admin.proto": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_proto"), + "google/spanner/admin/instance/v1/spanner_instance_admin.proto": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_proto"), + "google/spanner/v1/keys.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), + "google/spanner/v1/mutation.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), + "google/spanner/v1/query_plan.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), + "google/spanner/v1/result_set.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), + "google/spanner/v1/spanner.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), + "google/spanner/v1/transaction.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), + "google/spanner/v1/type.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"), + "google/storagetransfer/v1/transfer.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_proto"), + "google/storagetransfer/v1/transfer_types.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_proto"), "google/streetview/publish/v1/resources.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_proto"), "google/streetview/publish/v1/rpcmessages.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_proto"), "google/streetview/publish/v1/streetview_publish.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_proto"), - "google/logging/v2/logging_metrics.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"), - "google/logging/v2/logging_config.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"), - "google/logging/v2/log_entry.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"), - "google/logging/v2/logging.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"), - "google/logging/type/log_severity.proto": label.New("go_googleapis", "google/logging/type", "ltype_proto"), - "google/logging/type/http_request.proto": label.New("go_googleapis", "google/logging/type", "ltype_proto"), + "google/type/color.proto": label.New("go_googleapis", "google/type", "color_proto"), + "google/type/date.proto": label.New("go_googleapis", "google/type", "date_proto"), + "google/type/dayofweek.proto": label.New("go_googleapis", "google/type", "dayofweek_proto"), + "google/type/latlng.proto": label.New("go_googleapis", "google/type", "latlng_proto"), + "google/type/money.proto": label.New("go_googleapis", "google/type", "money_proto"), + "google/type/postal_address.proto": label.New("go_googleapis", "google/type", "postaladdress_proto"), + "google/type/timeofday.proto": label.New("go_googleapis", "google/type", "timeofday_proto"), + "google/watcher/v1/watch.proto": label.New("go_googleapis", "google/watcher/v1", "watcher_proto"), } diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/proto.csv b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/proto.csv index bbad8e8da8b90..e004b9c4c861f 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/proto.csv +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/proto.csv @@ -1,6 +1,9 @@ # This file lists special protos that Gazelle knows how to import. This is used to generate # code for proto and Go resolvers. # +# Generated by internal/language/proto/gen/update_proto_csv.go +# Do not edit directly. +# # proto name,proto label,go import path,go proto label google/protobuf/any.proto,@com_google_protobuf//:any_proto,github.com/golang/protobuf/ptypes/any,@io_bazel_rules_go//proto/wkt:any_go_proto google/protobuf/api.proto,@com_google_protobuf//:api_proto,google.golang.org/genproto/protobuf/api,@io_bazel_rules_go//proto/wkt:api_go_proto @@ -14,280 +17,346 @@ google/protobuf/struct.proto,@com_google_protobuf//:struct_proto,github.com/gola google/protobuf/timestamp.proto,@com_google_protobuf//:timestamp_proto,github.com/golang/protobuf/ptypes/timestamp,@io_bazel_rules_go//proto/wkt:timestamp_go_proto google/protobuf/type.proto,@com_google_protobuf//:type_proto,google.golang.org/genproto/protobuf/ptype,@io_bazel_rules_go//proto/wkt:type_go_proto google/protobuf/wrappers.proto,@com_google_protobuf//:wrappers_proto,github.com/golang/protobuf/ptypes/wrappers,@io_bazel_rules_go//proto/wkt:wrappers_go_proto -google/assistant/embedded/v1alpha2/embedded_assistant.proto,@go_googleapis//google/assistant/embedded/v1alpha2:embedded_proto,google.golang.org/genproto/googleapis/assistant/embedded/v1alpha2,@go_googleapis//google/assistant/embedded/v1alpha2:embedded_go_proto +google/api/annotations.proto,@go_googleapis//google/api:annotations_proto,google.golang.org/genproto/googleapis/api/annotations,@go_googleapis//google/api:annotations_go_proto +google/api/auth.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/backend.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/billing.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/config_change.proto,@go_googleapis//google/api:configchange_proto,google.golang.org/genproto/googleapis/api/configchange,@go_googleapis//google/api:configchange_go_proto +google/api/consumer.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/context.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/control.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/distribution.proto,@go_googleapis//google/api:distribution_proto,google.golang.org/genproto/googleapis/api/distribution,@go_googleapis//google/api:distribution_go_proto +google/api/documentation.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/endpoint.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/experimental/authorization_config.proto,@go_googleapis//google/api:api_proto,google.golang.org/genproto/googleapis/api,@go_googleapis//google/api:api_go_proto +google/api/experimental/experimental.proto,@go_googleapis//google/api:api_proto,google.golang.org/genproto/googleapis/api,@go_googleapis//google/api:api_go_proto +google/api/expr/v1alpha1/cel_service.proto,@go_googleapis//google/api/expr/v1alpha1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1alpha1,@go_googleapis//google/api/expr/v1alpha1:expr_go_proto +google/api/expr/v1alpha1/checked.proto,@go_googleapis//google/api/expr/v1alpha1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1alpha1,@go_googleapis//google/api/expr/v1alpha1:expr_go_proto +google/api/expr/v1alpha1/eval.proto,@go_googleapis//google/api/expr/v1alpha1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1alpha1,@go_googleapis//google/api/expr/v1alpha1:expr_go_proto +google/api/expr/v1alpha1/explain.proto,@go_googleapis//google/api/expr/v1alpha1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1alpha1,@go_googleapis//google/api/expr/v1alpha1:expr_go_proto +google/api/expr/v1alpha1/syntax.proto,@go_googleapis//google/api/expr/v1alpha1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1alpha1,@go_googleapis//google/api/expr/v1alpha1:expr_go_proto +google/api/expr/v1alpha1/value.proto,@go_googleapis//google/api/expr/v1alpha1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1alpha1,@go_googleapis//google/api/expr/v1alpha1:expr_go_proto +google/api/expr/v1beta1/decl.proto,@go_googleapis//google/api/expr/v1beta1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1beta1,@go_googleapis//google/api/expr/v1beta1:expr_go_proto +google/api/expr/v1beta1/eval.proto,@go_googleapis//google/api/expr/v1beta1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1beta1,@go_googleapis//google/api/expr/v1beta1:expr_go_proto +google/api/expr/v1beta1/expr.proto,@go_googleapis//google/api/expr/v1beta1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1beta1,@go_googleapis//google/api/expr/v1beta1:expr_go_proto +google/api/expr/v1beta1/source.proto,@go_googleapis//google/api/expr/v1beta1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1beta1,@go_googleapis//google/api/expr/v1beta1:expr_go_proto +google/api/expr/v1beta1/value.proto,@go_googleapis//google/api/expr/v1beta1:expr_proto,google.golang.org/genproto/googleapis/api/expr/v1beta1,@go_googleapis//google/api/expr/v1beta1:expr_go_proto +google/api/http.proto,@go_googleapis//google/api:annotations_proto,google.golang.org/genproto/googleapis/api/annotations,@go_googleapis//google/api:annotations_go_proto +google/api/httpbody.proto,@go_googleapis//google/api:httpbody_proto,google.golang.org/genproto/googleapis/api/httpbody,@go_googleapis//google/api:httpbody_go_proto +google/api/label.proto,@go_googleapis//google/api:label_proto,google.golang.org/genproto/googleapis/api/label,@go_googleapis//google/api:label_go_proto +google/api/launch_stage.proto,@go_googleapis//google/api:api_proto,google.golang.org/genproto/googleapis/api,@go_googleapis//google/api:api_go_proto +google/api/log.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/logging.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/metric.proto,@go_googleapis//google/api:metric_proto,google.golang.org/genproto/googleapis/api/metric,@go_googleapis//google/api:metric_go_proto +google/api/monitored_resource.proto,@go_googleapis//google/api:monitoredres_proto,google.golang.org/genproto/googleapis/api/monitoredres,@go_googleapis//google/api:monitoredres_go_proto +google/api/monitoring.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/quota.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/service.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/servicecontrol/v1/check_error.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto +google/api/servicecontrol/v1/distribution.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto +google/api/servicecontrol/v1/log_entry.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto +google/api/servicecontrol/v1/metric_value.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto +google/api/servicecontrol/v1/operation.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto +google/api/servicecontrol/v1/quota_controller.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto +google/api/servicecontrol/v1/service_controller.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto +google/api/servicemanagement/v1/resources.proto,@go_googleapis//google/api/servicemanagement/v1:servicemanagement_proto,google.golang.org/genproto/googleapis/api/servicemanagement/v1,@go_googleapis//google/api/servicemanagement/v1:servicemanagement_go_proto +google/api/servicemanagement/v1/servicemanager.proto,@go_googleapis//google/api/servicemanagement/v1:servicemanagement_proto,google.golang.org/genproto/googleapis/api/servicemanagement/v1,@go_googleapis//google/api/servicemanagement/v1:servicemanagement_go_proto +google/api/source_info.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/system_parameter.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/api/usage.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto +google/appengine/legacy/audit_data.proto,@go_googleapis//google/appengine/legacy:legacy_proto,google.golang.org/genproto/googleapis/appengine/legacy,@go_googleapis//google/appengine/legacy:legacy_go_proto +google/appengine/logging/v1/request_log.proto,@go_googleapis//google/appengine/logging/v1:logging_proto,google.golang.org/genproto/googleapis/appengine/logging/v1,@go_googleapis//google/appengine/logging/v1:logging_go_proto +google/appengine/v1/app_yaml.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/appengine.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/application.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/audit_data.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/deploy.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/instance.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/location.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/operation.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/service.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto +google/appengine/v1/version.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto google/assistant/embedded/v1alpha1/embedded_assistant.proto,@go_googleapis//google/assistant/embedded/v1alpha1:embedded_proto,google.golang.org/genproto/googleapis/assistant/embedded/v1alpha1,@go_googleapis//google/assistant/embedded/v1alpha1:embedded_go_proto -google/home/graph/v1/device.proto,@go_googleapis//google/home/graph/v1:graph_proto,google.golang.org/genproto/googleapis/home/graph/v1,@go_googleapis//google/home/graph/v1:graph_go_proto -google/home/graph/v1/homegraph.proto,@go_googleapis//google/home/graph/v1:graph_proto,google.golang.org/genproto/googleapis/home/graph/v1,@go_googleapis//google/home/graph/v1:graph_go_proto -google/genomics/v1/operations.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/variants.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/position.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/references.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/cigar.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/datasets.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/readalignment.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/annotations.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/reads.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/readgroup.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/readgroupset.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1/range.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto -google/genomics/v1alpha2/pipelines.proto,@go_googleapis//google/genomics/v1alpha2:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1alpha2,@go_googleapis//google/genomics/v1alpha2:genomics_go_proto -google/bigtable/v1/bigtable_service_messages.proto,@go_googleapis//google/bigtable/v1:bigtable_proto,google.golang.org/genproto/googleapis/bigtable/v1,@go_googleapis//google/bigtable/v1:bigtable_go_proto -google/bigtable/v1/bigtable_service.proto,@go_googleapis//google/bigtable/v1:bigtable_proto,google.golang.org/genproto/googleapis/bigtable/v1,@go_googleapis//google/bigtable/v1:bigtable_go_proto -google/bigtable/v1/bigtable_data.proto,@go_googleapis//google/bigtable/v1:bigtable_proto,google.golang.org/genproto/googleapis/bigtable/v1,@go_googleapis//google/bigtable/v1:bigtable_go_proto +google/assistant/embedded/v1alpha2/embedded_assistant.proto,@go_googleapis//google/assistant/embedded/v1alpha2:embedded_proto,google.golang.org/genproto/googleapis/assistant/embedded/v1alpha2,@go_googleapis//google/assistant/embedded/v1alpha2:embedded_go_proto google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto,@go_googleapis//google/bigtable/admin/cluster/v1:cluster_proto,google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1,@go_googleapis//google/bigtable/admin/cluster/v1:cluster_go_proto -google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto,@go_googleapis//google/bigtable/admin/cluster/v1:cluster_proto,google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1,@go_googleapis//google/bigtable/admin/cluster/v1:cluster_go_proto google/bigtable/admin/cluster/v1/bigtable_cluster_service.proto,@go_googleapis//google/bigtable/admin/cluster/v1:cluster_proto,google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1,@go_googleapis//google/bigtable/admin/cluster/v1:cluster_go_proto +google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto,@go_googleapis//google/bigtable/admin/cluster/v1:cluster_proto,google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1,@go_googleapis//google/bigtable/admin/cluster/v1:cluster_go_proto +google/bigtable/admin/table/v1/bigtable_table_data.proto,@go_googleapis//google/bigtable/admin/table/v1:table_proto,google.golang.org/genproto/googleapis/bigtable/admin/table/v1,@go_googleapis//google/bigtable/admin/table/v1:table_go_proto +google/bigtable/admin/table/v1/bigtable_table_service.proto,@go_googleapis//google/bigtable/admin/table/v1:table_proto,google.golang.org/genproto/googleapis/bigtable/admin/table/v1,@go_googleapis//google/bigtable/admin/table/v1:table_go_proto +google/bigtable/admin/table/v1/bigtable_table_service_messages.proto,@go_googleapis//google/bigtable/admin/table/v1:table_proto,google.golang.org/genproto/googleapis/bigtable/admin/table/v1,@go_googleapis//google/bigtable/admin/table/v1:table_go_proto google/bigtable/admin/v2/bigtable_instance_admin.proto,@go_googleapis//google/bigtable/admin/v2:admin_proto,google.golang.org/genproto/googleapis/bigtable/admin/v2,@go_googleapis//google/bigtable/admin/v2:admin_go_proto -google/bigtable/admin/v2/instance.proto,@go_googleapis//google/bigtable/admin/v2:admin_proto,google.golang.org/genproto/googleapis/bigtable/admin/v2,@go_googleapis//google/bigtable/admin/v2:admin_go_proto -google/bigtable/admin/v2/table.proto,@go_googleapis//google/bigtable/admin/v2:admin_proto,google.golang.org/genproto/googleapis/bigtable/admin/v2,@go_googleapis//google/bigtable/admin/v2:admin_go_proto google/bigtable/admin/v2/bigtable_table_admin.proto,@go_googleapis//google/bigtable/admin/v2:admin_proto,google.golang.org/genproto/googleapis/bigtable/admin/v2,@go_googleapis//google/bigtable/admin/v2:admin_go_proto google/bigtable/admin/v2/common.proto,@go_googleapis//google/bigtable/admin/v2:admin_proto,google.golang.org/genproto/googleapis/bigtable/admin/v2,@go_googleapis//google/bigtable/admin/v2:admin_go_proto -google/bigtable/admin/table/v1/bigtable_table_service_messages.proto,@go_googleapis//google/bigtable/admin/table/v1:table_proto,google.golang.org/genproto/googleapis/bigtable/admin/table/v1,@go_googleapis//google/bigtable/admin/table/v1:table_go_proto -google/bigtable/admin/table/v1/bigtable_table_service.proto,@go_googleapis//google/bigtable/admin/table/v1:table_proto,google.golang.org/genproto/googleapis/bigtable/admin/table/v1,@go_googleapis//google/bigtable/admin/table/v1:table_go_proto -google/bigtable/admin/table/v1/bigtable_table_data.proto,@go_googleapis//google/bigtable/admin/table/v1:table_proto,google.golang.org/genproto/googleapis/bigtable/admin/table/v1,@go_googleapis//google/bigtable/admin/table/v1:table_go_proto +google/bigtable/admin/v2/instance.proto,@go_googleapis//google/bigtable/admin/v2:admin_proto,google.golang.org/genproto/googleapis/bigtable/admin/v2,@go_googleapis//google/bigtable/admin/v2:admin_go_proto +google/bigtable/admin/v2/table.proto,@go_googleapis//google/bigtable/admin/v2:admin_proto,google.golang.org/genproto/googleapis/bigtable/admin/v2,@go_googleapis//google/bigtable/admin/v2:admin_go_proto +google/bigtable/v1/bigtable_data.proto,@go_googleapis//google/bigtable/v1:bigtable_proto,google.golang.org/genproto/googleapis/bigtable/v1,@go_googleapis//google/bigtable/v1:bigtable_go_proto +google/bigtable/v1/bigtable_service.proto,@go_googleapis//google/bigtable/v1:bigtable_proto,google.golang.org/genproto/googleapis/bigtable/v1,@go_googleapis//google/bigtable/v1:bigtable_go_proto +google/bigtable/v1/bigtable_service_messages.proto,@go_googleapis//google/bigtable/v1:bigtable_proto,google.golang.org/genproto/googleapis/bigtable/v1,@go_googleapis//google/bigtable/v1:bigtable_go_proto google/bigtable/v2/bigtable.proto,@go_googleapis//google/bigtable/v2:bigtable_proto,google.golang.org/genproto/googleapis/bigtable/v2,@go_googleapis//google/bigtable/v2:bigtable_go_proto google/bigtable/v2/data.proto,@go_googleapis//google/bigtable/v2:bigtable_proto,google.golang.org/genproto/googleapis/bigtable/v2,@go_googleapis//google/bigtable/v2:bigtable_go_proto -google/privacy/dlp/v2/storage.proto,@go_googleapis//google/privacy/dlp/v2:dlp_proto,google.golang.org/genproto/googleapis/privacy/dlp/v2,@go_googleapis//google/privacy/dlp/v2:dlp_go_proto -google/privacy/dlp/v2/dlp.proto,@go_googleapis//google/privacy/dlp/v2:dlp_proto,google.golang.org/genproto/googleapis/privacy/dlp/v2,@go_googleapis//google/privacy/dlp/v2:dlp_go_proto -google/watcher/v1/watch.proto,@go_googleapis//google/watcher/v1:watcher_proto,google.golang.org/genproto/googleapis/watcher/v1,@go_googleapis//google/watcher/v1:watcher_go_proto -google/firestore/admin/v1beta1/firestore_admin.proto,@go_googleapis//google/firestore/admin/v1beta1:admin_proto,google.golang.org/genproto/googleapis/firestore/admin/v1beta1,@go_googleapis//google/firestore/admin/v1beta1:admin_go_proto -google/firestore/admin/v1beta1/index.proto,@go_googleapis//google/firestore/admin/v1beta1:admin_proto,google.golang.org/genproto/googleapis/firestore/admin/v1beta1,@go_googleapis//google/firestore/admin/v1beta1:admin_go_proto -google/firestore/v1beta1/write.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto -google/firestore/v1beta1/document.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto -google/firestore/v1beta1/firestore.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto -google/firestore/v1beta1/query.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto -google/firestore/v1beta1/common.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto -google/example/library/v1/library.proto,@go_googleapis//google/example/library/v1:library_proto,google.golang.org/genproto/googleapis/example/library/v1,@go_googleapis//google/example/library/v1:library_go_proto -google/appengine/v1/instance.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/audit_data.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/appengine.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/application.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/operation.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/app_yaml.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/location.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/service.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/deploy.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/v1/version.proto,@go_googleapis//google/appengine/v1:appengine_proto,google.golang.org/genproto/googleapis/appengine/v1,@go_googleapis//google/appengine/v1:appengine_go_proto -google/appengine/legacy/audit_data.proto,@go_googleapis//google/appengine/legacy:legacy_proto,google.golang.org/genproto/googleapis/appengine/legacy,@go_googleapis//google/appengine/legacy:legacy_go_proto -google/appengine/logging/v1/request_log.proto,@go_googleapis//google/appengine/logging/v1:logging_proto,google.golang.org/genproto/googleapis/appengine/logging/v1,@go_googleapis//google/appengine/logging/v1:logging_go_proto -google/storagetransfer/v1/transfer.proto,@go_googleapis//google/storagetransfer/v1:storagetransfer_proto,google.golang.org/genproto/googleapis/storagetransfer/v1,@go_googleapis//google/storagetransfer/v1:storagetransfer_go_proto -google/storagetransfer/v1/transfer_types.proto,@go_googleapis//google/storagetransfer/v1:storagetransfer_proto,google.golang.org/genproto/googleapis/storagetransfer/v1,@go_googleapis//google/storagetransfer/v1:storagetransfer_go_proto -google/longrunning/operations.proto,@go_googleapis//google/longrunning:longrunning_proto,google.golang.org/genproto/googleapis/longrunning,@go_googleapis//google/longrunning:longrunning_go_proto -google/container/v1/cluster_service.proto,@go_googleapis//google/container/v1:container_proto,google.golang.org/genproto/googleapis/container/v1,@go_googleapis//google/container/v1:container_go_proto -google/container/v1beta1/cluster_service.proto,@go_googleapis//google/container/v1beta1:container_proto,google.golang.org/genproto/googleapis/container/v1beta1,@go_googleapis//google/container/v1beta1:container_go_proto -google/container/v1alpha1/cluster_service.proto,@go_googleapis//google/container/v1alpha1:container_proto,google.golang.org/genproto/googleapis/container/v1alpha1,@go_googleapis//google/container/v1alpha1:container_go_proto -google/datastore/v1beta3/datastore.proto,@go_googleapis//google/datastore/v1beta3:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1beta3,@go_googleapis//google/datastore/v1beta3:datastore_go_proto -google/datastore/v1beta3/query.proto,@go_googleapis//google/datastore/v1beta3:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1beta3,@go_googleapis//google/datastore/v1beta3:datastore_go_proto -google/datastore/v1beta3/entity.proto,@go_googleapis//google/datastore/v1beta3:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1beta3,@go_googleapis//google/datastore/v1beta3:datastore_go_proto -google/datastore/v1/datastore.proto,@go_googleapis//google/datastore/v1:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1,@go_googleapis//google/datastore/v1:datastore_go_proto -google/datastore/v1/query.proto,@go_googleapis//google/datastore/v1:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1,@go_googleapis//google/datastore/v1:datastore_go_proto -google/datastore/v1/entity.proto,@go_googleapis//google/datastore/v1:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1,@go_googleapis//google/datastore/v1:datastore_go_proto -google/datastore/admin/v1/datastore_admin.proto,@go_googleapis//google/datastore/admin/v1:admin_proto,google.golang.org/genproto/googleapis/datastore/admin/v1,@go_googleapis//google/datastore/admin/v1:admin_go_proto -google/datastore/admin/v1beta1/datastore_admin.proto,@go_googleapis//google/datastore/admin/v1beta1:admin_proto,google.golang.org/genproto/googleapis/datastore/admin/v1beta1,@go_googleapis//google/datastore/admin/v1beta1:admin_go_proto google/bytestream/bytestream.proto,@go_googleapis//google/bytestream:bytestream_proto,google.golang.org/genproto/googleapis/bytestream,@go_googleapis//google/bytestream:bytestream_go_proto -google/iam/v1/iam_policy.proto,@go_googleapis//google/iam/v1:iam_proto,google.golang.org/genproto/googleapis/iam/v1,@go_googleapis//google/iam/v1:iam_go_proto -google/iam/v1/policy.proto,@go_googleapis//google/iam/v1:iam_proto,google.golang.org/genproto/googleapis/iam/v1,@go_googleapis//google/iam/v1:iam_go_proto -google/iam/v1/logging/audit_data.proto,@go_googleapis//google/iam/v1/logging:logging_proto,google.golang.org/genproto/googleapis/iam/v1/logging,@go_googleapis//google/iam/v1/logging:logging_go_proto -google/iam/admin/v1/iam.proto,@go_googleapis//google/iam/admin/v1:admin_proto,google.golang.org/genproto/googleapis/iam/admin/v1,@go_googleapis//google/iam/admin/v1:admin_go_proto -google/type/money.proto,@go_googleapis//google/type:money_proto,google.golang.org/genproto/googleapis/type/money,@go_googleapis//google/type:money_go_proto -google/type/latlng.proto,@go_googleapis//google/type:latlng_proto,google.golang.org/genproto/googleapis/type/latlng,@go_googleapis//google/type:latlng_go_proto -google/type/color.proto,@go_googleapis//google/type:color_proto,google.golang.org/genproto/googleapis/type/color,@go_googleapis//google/type:color_go_proto -google/type/timeofday.proto,@go_googleapis//google/type:timeofday_proto,google.golang.org/genproto/googleapis/type/timeofday,@go_googleapis//google/type:timeofday_go_proto -google/type/date.proto,@go_googleapis//google/type:date_proto,google.golang.org/genproto/googleapis/type/date,@go_googleapis//google/type:date_go_proto -google/type/dayofweek.proto,@go_googleapis//google/type:dayofweek_proto,google.golang.org/genproto/googleapis/type/dayofweek,@go_googleapis//google/type:dayofweek_go_proto -google/type/postal_address.proto,@go_googleapis//google/type:postaladdress_proto,google.golang.org/genproto/googleapis/type/postaladdress,@go_googleapis//google/type:postaladdress_go_proto -google/devtools/clouderrorreporting/v1beta1/report_errors_service.proto,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_proto,google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_go_proto -google/devtools/clouderrorreporting/v1beta1/error_group_service.proto,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_proto,google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_go_proto -google/devtools/clouderrorreporting/v1beta1/error_stats_service.proto,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_proto,google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_go_proto -google/devtools/clouderrorreporting/v1beta1/common.proto,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_proto,google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_go_proto -google/devtools/resultstore/v2/file.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/resultstore_download.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/configuration.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/action.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/resultstore_file_download.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/test_suite.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/file_set.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/coverage.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/coverage_summary.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/configured_target.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/target.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/invocation.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/resultstore/v2/common.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto -google/devtools/source/v1/source_context.proto,@go_googleapis//google/devtools/source/v1:source_proto,google.golang.org/genproto/googleapis/devtools/source/v1,@go_googleapis//google/devtools/source/v1:source_go_proto -google/devtools/remoteexecution/v1test/remote_execution.proto,@go_googleapis//google/devtools/remoteexecution/v1test:remoteexecution_proto,google.golang.org/genproto/googleapis/devtools/remoteexecution/v1test,@go_googleapis//google/devtools/remoteexecution/v1test:remoteexecution_go_proto -google/devtools/cloudbuild/v1/cloudbuild.proto,@go_googleapis//google/devtools/cloudbuild/v1:cloudbuild_proto,google.golang.org/genproto/googleapis/devtools/cloudbuild/v1,@go_googleapis//google/devtools/cloudbuild/v1:cloudbuild_go_proto -google/devtools/sourcerepo/v1/sourcerepo.proto,@go_googleapis//google/devtools/sourcerepo/v1:sourcerepo_proto,google.golang.org/genproto/googleapis/devtools/sourcerepo/v1,@go_googleapis//google/devtools/sourcerepo/v1:sourcerepo_go_proto -google/devtools/remoteworkers/v1test2/worker.proto,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_proto,google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_go_proto -google/devtools/remoteworkers/v1test2/tasks.proto,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_proto,google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_go_proto -google/devtools/remoteworkers/v1test2/bots.proto,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_proto,google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_go_proto -google/devtools/remoteworkers/v1test2/command.proto,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_proto,google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_go_proto -google/devtools/cloudtrace/v1/trace.proto,@go_googleapis//google/devtools/cloudtrace/v1:cloudtrace_proto,google.golang.org/genproto/googleapis/devtools/cloudtrace/v1,@go_googleapis//google/devtools/cloudtrace/v1:cloudtrace_go_proto -google/devtools/cloudtrace/v2/trace.proto,@go_googleapis//google/devtools/cloudtrace/v2:cloudtrace_proto,google.golang.org/genproto/googleapis/devtools/cloudtrace/v2,@go_googleapis//google/devtools/cloudtrace/v2:cloudtrace_go_proto -google/devtools/cloudtrace/v2/tracing.proto,@go_googleapis//google/devtools/cloudtrace/v2:cloudtrace_proto,google.golang.org/genproto/googleapis/devtools/cloudtrace/v2,@go_googleapis//google/devtools/cloudtrace/v2:cloudtrace_go_proto -google/devtools/cloudprofiler/v2/profiler.proto,@go_googleapis//google/devtools/cloudprofiler/v2:cloudprofiler_proto,google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2,@go_googleapis//google/devtools/cloudprofiler/v2:cloudprofiler_go_proto -google/devtools/containeranalysis/v1alpha1/containeranalysis.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto -google/devtools/containeranalysis/v1alpha1/bill_of_materials.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto -google/devtools/containeranalysis/v1alpha1/provenance.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto -google/devtools/containeranalysis/v1alpha1/package_vulnerability.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto -google/devtools/containeranalysis/v1alpha1/source_context.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto -google/devtools/containeranalysis/v1alpha1/image_basis.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto -google/devtools/build/v1/build_events.proto,@go_googleapis//google/devtools/build/v1:build_proto,google.golang.org/genproto/googleapis/devtools/build/v1,@go_googleapis//google/devtools/build/v1:build_go_proto -google/devtools/build/v1/build_status.proto,@go_googleapis//google/devtools/build/v1:build_proto,google.golang.org/genproto/googleapis/devtools/build/v1,@go_googleapis//google/devtools/build/v1:build_go_proto -google/devtools/build/v1/publish_build_event.proto,@go_googleapis//google/devtools/build/v1:build_proto,google.golang.org/genproto/googleapis/devtools/build/v1,@go_googleapis//google/devtools/build/v1:build_go_proto -google/devtools/clouddebugger/v2/debugger.proto,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_proto,google.golang.org/genproto/googleapis/devtools/clouddebugger/v2,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_go_proto -google/devtools/clouddebugger/v2/data.proto,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_proto,google.golang.org/genproto/googleapis/devtools/clouddebugger/v2,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_go_proto -google/devtools/clouddebugger/v2/controller.proto,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_proto,google.golang.org/genproto/googleapis/devtools/clouddebugger/v2,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_go_proto -google/cloud/resourcemanager/v2/folders.proto,@go_googleapis//google/cloud/resourcemanager/v2:resourcemanager_proto,google.golang.org/genproto/googleapis/cloud/resourcemanager/v2,@go_googleapis//google/cloud/resourcemanager/v2:resourcemanager_go_proto +google/cloud/asset/v1beta1/asset_service.proto,@go_googleapis//google/cloud/asset/v1beta1:asset_proto,google.golang.org/genproto/googleapis/cloud/asset/v1beta1,@go_googleapis//google/cloud/asset/v1beta1:asset_go_proto +google/cloud/asset/v1beta1/assets.proto,@go_googleapis//google/cloud/asset/v1beta1:asset_proto,google.golang.org/genproto/googleapis/cloud/asset/v1beta1,@go_googleapis//google/cloud/asset/v1beta1:asset_go_proto +google/cloud/audit/audit_log.proto,@go_googleapis//google/cloud/audit:audit_proto,google.golang.org/genproto/googleapis/cloud/audit,@go_googleapis//google/cloud/audit:audit_go_proto +google/cloud/automl/v1beta1/annotation_payload.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/classification.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/data_items.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/dataset.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/image.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/io.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/model.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/model_evaluation.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/operations.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/prediction_service.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/service.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/text.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/automl/v1beta1/translation.proto,@go_googleapis//google/cloud/automl/v1beta1:automl_proto,google.golang.org/genproto/googleapis/cloud/automl/v1beta1,@go_googleapis//google/cloud/automl/v1beta1:automl_go_proto +google/cloud/bigquery/datatransfer/v1/datatransfer.proto,@go_googleapis//google/cloud/bigquery/datatransfer/v1:datatransfer_proto,google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1,@go_googleapis//google/cloud/bigquery/datatransfer/v1:datatransfer_go_proto +google/cloud/bigquery/datatransfer/v1/transfer.proto,@go_googleapis//google/cloud/bigquery/datatransfer/v1:datatransfer_proto,google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1,@go_googleapis//google/cloud/bigquery/datatransfer/v1:datatransfer_go_proto +google/cloud/bigquery/logging/v1/audit_data.proto,@go_googleapis//google/cloud/bigquery/logging/v1:logging_proto,google.golang.org/genproto/googleapis/cloud/bigquery/logging/v1,@go_googleapis//google/cloud/bigquery/logging/v1:logging_go_proto +google/cloud/bigquery/storage/v1beta1/avro.proto,@go_googleapis//google/cloud/bigquery/storage/v1beta1:storage_proto,google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1,@go_googleapis//google/cloud/bigquery/storage/v1beta1:storage_go_proto +google/cloud/bigquery/storage/v1beta1/read_options.proto,@go_googleapis//google/cloud/bigquery/storage/v1beta1:storage_proto,google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1,@go_googleapis//google/cloud/bigquery/storage/v1beta1:storage_go_proto +google/cloud/bigquery/storage/v1beta1/storage.proto,@go_googleapis//google/cloud/bigquery/storage/v1beta1:storage_proto,google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1,@go_googleapis//google/cloud/bigquery/storage/v1beta1:storage_go_proto +google/cloud/bigquery/storage/v1beta1/table_reference.proto,@go_googleapis//google/cloud/bigquery/storage/v1beta1:storage_proto,google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1,@go_googleapis//google/cloud/bigquery/storage/v1beta1:storage_go_proto +google/cloud/billing/v1/cloud_billing.proto,@go_googleapis//google/cloud/billing/v1:billing_proto,google.golang.org/genproto/googleapis/cloud/billing/v1,@go_googleapis//google/cloud/billing/v1:billing_go_proto +google/cloud/dataproc/v1/clusters.proto,@go_googleapis//google/cloud/dataproc/v1:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1,@go_googleapis//google/cloud/dataproc/v1:dataproc_go_proto +google/cloud/dataproc/v1/jobs.proto,@go_googleapis//google/cloud/dataproc/v1:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1,@go_googleapis//google/cloud/dataproc/v1:dataproc_go_proto +google/cloud/dataproc/v1/operations.proto,@go_googleapis//google/cloud/dataproc/v1:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1,@go_googleapis//google/cloud/dataproc/v1:dataproc_go_proto +google/cloud/dataproc/v1beta2/clusters.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto +google/cloud/dataproc/v1beta2/jobs.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto +google/cloud/dataproc/v1beta2/operations.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto +google/cloud/dataproc/v1beta2/shared.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto +google/cloud/dataproc/v1beta2/workflow_templates.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto +google/cloud/dialogflow/v2/agent.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto +google/cloud/dialogflow/v2/context.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto +google/cloud/dialogflow/v2/entity_type.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto +google/cloud/dialogflow/v2/intent.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto +google/cloud/dialogflow/v2/session.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto +google/cloud/dialogflow/v2/session_entity_type.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto +google/cloud/dialogflow/v2/webhook.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/agent.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/audio_config.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/context.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/document.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/entity_type.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/intent.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/knowledge_base.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/session.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/session_entity_type.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/dialogflow/v2beta1/webhook.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto +google/cloud/functions/v1beta2/functions.proto,@go_googleapis//google/cloud/functions/v1beta2:functions_proto,google.golang.org/genproto/googleapis/cloud/functions/v1beta2,@go_googleapis//google/cloud/functions/v1beta2:functions_go_proto +google/cloud/functions/v1beta2/operations.proto,@go_googleapis//google/cloud/functions/v1beta2:functions_proto,google.golang.org/genproto/googleapis/cloud/functions/v1beta2,@go_googleapis//google/cloud/functions/v1beta2:functions_go_proto +google/cloud/iot/v1/device_manager.proto,@go_googleapis//google/cloud/iot/v1:iot_proto,google.golang.org/genproto/googleapis/cloud/iot/v1,@go_googleapis//google/cloud/iot/v1:iot_go_proto +google/cloud/iot/v1/resources.proto,@go_googleapis//google/cloud/iot/v1:iot_proto,google.golang.org/genproto/googleapis/cloud/iot/v1,@go_googleapis//google/cloud/iot/v1:iot_go_proto google/cloud/kms/v1/resources.proto,@go_googleapis//google/cloud/kms/v1:kms_proto,google.golang.org/genproto/googleapis/cloud/kms/v1,@go_googleapis//google/cloud/kms/v1:kms_go_proto google/cloud/kms/v1/service.proto,@go_googleapis//google/cloud/kms/v1:kms_proto,google.golang.org/genproto/googleapis/cloud/kms/v1,@go_googleapis//google/cloud/kms/v1:kms_go_proto -google/cloud/runtimeconfig/v1beta1/resources.proto,@go_googleapis//google/cloud/runtimeconfig/v1beta1:runtimeconfig_proto,google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1,@go_googleapis//google/cloud/runtimeconfig/v1beta1:runtimeconfig_go_proto -google/cloud/runtimeconfig/v1beta1/runtimeconfig.proto,@go_googleapis//google/cloud/runtimeconfig/v1beta1:runtimeconfig_proto,google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1,@go_googleapis//google/cloud/runtimeconfig/v1beta1:runtimeconfig_go_proto -google/cloud/tasks/v2beta2/queue.proto,@go_googleapis//google/cloud/tasks/v2beta2:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta2,@go_googleapis//google/cloud/tasks/v2beta2:tasks_go_proto -google/cloud/tasks/v2beta2/task.proto,@go_googleapis//google/cloud/tasks/v2beta2:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta2,@go_googleapis//google/cloud/tasks/v2beta2:tasks_go_proto -google/cloud/tasks/v2beta2/target.proto,@go_googleapis//google/cloud/tasks/v2beta2:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta2,@go_googleapis//google/cloud/tasks/v2beta2:tasks_go_proto -google/cloud/tasks/v2beta2/cloudtasks.proto,@go_googleapis//google/cloud/tasks/v2beta2:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta2,@go_googleapis//google/cloud/tasks/v2beta2:tasks_go_proto +google/cloud/language/v1/language_service.proto,@go_googleapis//google/cloud/language/v1:language_proto,google.golang.org/genproto/googleapis/cloud/language/v1,@go_googleapis//google/cloud/language/v1:language_go_proto +google/cloud/language/v1beta1/language_service.proto,@go_googleapis//google/cloud/language/v1beta1:language_proto,google.golang.org/genproto/googleapis/cloud/language/v1beta1,@go_googleapis//google/cloud/language/v1beta1:language_go_proto +google/cloud/language/v1beta2/language_service.proto,@go_googleapis//google/cloud/language/v1beta2:language_proto,google.golang.org/genproto/googleapis/cloud/language/v1beta2,@go_googleapis//google/cloud/language/v1beta2:language_go_proto +google/cloud/location/locations.proto,@go_googleapis//google/cloud/location:location_proto,google.golang.org/genproto/googleapis/cloud/location,@go_googleapis//google/cloud/location:location_go_proto +google/cloud/ml/v1/job_service.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto +google/cloud/ml/v1/model_service.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto +google/cloud/ml/v1/operation_metadata.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto +google/cloud/ml/v1/prediction_service.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto +google/cloud/ml/v1/project_service.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto +google/cloud/oslogin/common/common.proto,@go_googleapis//google/cloud/oslogin/common:common_proto,google.golang.org/genproto/googleapis/cloud/oslogin/common,@go_googleapis//google/cloud/oslogin/common:common_go_proto google/cloud/oslogin/v1/oslogin.proto,@go_googleapis//google/cloud/oslogin/v1:oslogin_proto,google.golang.org/genproto/googleapis/cloud/oslogin/v1,@go_googleapis//google/cloud/oslogin/v1:oslogin_go_proto google/cloud/oslogin/v1alpha/oslogin.proto,@go_googleapis//google/cloud/oslogin/v1alpha:oslogin_proto,google.golang.org/genproto/googleapis/cloud/oslogin/v1alpha,@go_googleapis//google/cloud/oslogin/v1alpha:oslogin_go_proto -google/cloud/oslogin/common/common.proto,@go_googleapis//google/cloud/oslogin/common:common_proto,google.golang.org/genproto/googleapis/cloud/oslogin/common,@go_googleapis//google/cloud/oslogin/common:common_go_proto google/cloud/oslogin/v1beta/oslogin.proto,@go_googleapis//google/cloud/oslogin/v1beta:oslogin_proto,google.golang.org/genproto/googleapis/cloud/oslogin/v1beta,@go_googleapis//google/cloud/oslogin/v1beta:oslogin_go_proto -google/cloud/dialogflow/v2beta1/context.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto -google/cloud/dialogflow/v2beta1/session_entity_type.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto -google/cloud/dialogflow/v2beta1/intent.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto -google/cloud/dialogflow/v2beta1/entity_type.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto -google/cloud/dialogflow/v2beta1/webhook.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto -google/cloud/dialogflow/v2beta1/session.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto -google/cloud/dialogflow/v2beta1/agent.proto,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1,@go_googleapis//google/cloud/dialogflow/v2beta1:dialogflow_go_proto -google/cloud/dialogflow/v2/context.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto -google/cloud/dialogflow/v2/session_entity_type.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto -google/cloud/dialogflow/v2/intent.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto -google/cloud/dialogflow/v2/entity_type.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto -google/cloud/dialogflow/v2/webhook.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto -google/cloud/dialogflow/v2/session.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto -google/cloud/dialogflow/v2/agent.proto,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_proto,google.golang.org/genproto/googleapis/cloud/dialogflow/v2,@go_googleapis//google/cloud/dialogflow/v2:dialogflow_go_proto +google/cloud/redis/v1/cloud_redis.proto,@go_googleapis//google/cloud/redis/v1:redis_proto,google.golang.org/genproto/googleapis/cloud/redis/v1,@go_googleapis//google/cloud/redis/v1:redis_go_proto google/cloud/redis/v1beta1/cloud_redis.proto,@go_googleapis//google/cloud/redis/v1beta1:redis_proto,google.golang.org/genproto/googleapis/cloud/redis/v1beta1,@go_googleapis//google/cloud/redis/v1beta1:redis_go_proto -google/cloud/location/locations.proto,@go_googleapis//google/cloud/location:location_proto,google.golang.org/genproto/googleapis/cloud/location,@go_googleapis//google/cloud/location:location_go_proto -google/cloud/websecurityscanner/v1alpha/finding.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto -google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto -google/cloud/websecurityscanner/v1alpha/scan_config.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto -google/cloud/websecurityscanner/v1alpha/crawled_url.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto -google/cloud/websecurityscanner/v1alpha/scan_run.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto -google/cloud/websecurityscanner/v1alpha/web_security_scanner.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto -google/cloud/websecurityscanner/v1alpha/finding_addon.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto -google/cloud/language/v1/language_service.proto,@go_googleapis//google/cloud/language/v1:language_proto,google.golang.org/genproto/googleapis/cloud/language/v1,@go_googleapis//google/cloud/language/v1:language_go_proto -google/cloud/language/v1beta2/language_service.proto,@go_googleapis//google/cloud/language/v1beta2:language_proto,google.golang.org/genproto/googleapis/cloud/language/v1beta2,@go_googleapis//google/cloud/language/v1beta2:language_go_proto -google/cloud/language/v1beta1/language_service.proto,@go_googleapis//google/cloud/language/v1beta1:language_proto,google.golang.org/genproto/googleapis/cloud/language/v1beta1,@go_googleapis//google/cloud/language/v1beta1:language_go_proto -google/cloud/bigquery/datatransfer/v1/transfer.proto,@go_googleapis//google/cloud/bigquery/datatransfer/v1:datatransfer_proto,google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1,@go_googleapis//google/cloud/bigquery/datatransfer/v1:datatransfer_go_proto -google/cloud/bigquery/datatransfer/v1/datatransfer.proto,@go_googleapis//google/cloud/bigquery/datatransfer/v1:datatransfer_proto,google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1,@go_googleapis//google/cloud/bigquery/datatransfer/v1:datatransfer_go_proto -google/cloud/bigquery/logging/v1/audit_data.proto,@go_googleapis//google/cloud/bigquery/logging/v1:logging_proto,google.golang.org/genproto/googleapis/cloud/bigquery/logging/v1,@go_googleapis//google/cloud/bigquery/logging/v1:logging_go_proto -google/cloud/vision/v1/image_annotator.proto,@go_googleapis//google/cloud/vision/v1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1,@go_googleapis//google/cloud/vision/v1:vision_go_proto -google/cloud/vision/v1/geometry.proto,@go_googleapis//google/cloud/vision/v1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1,@go_googleapis//google/cloud/vision/v1:vision_go_proto -google/cloud/vision/v1/web_detection.proto,@go_googleapis//google/cloud/vision/v1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1,@go_googleapis//google/cloud/vision/v1:vision_go_proto -google/cloud/vision/v1/text_annotation.proto,@go_googleapis//google/cloud/vision/v1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1,@go_googleapis//google/cloud/vision/v1:vision_go_proto -google/cloud/vision/v1p2beta1/image_annotator.proto,@go_googleapis//google/cloud/vision/v1p2beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1,@go_googleapis//google/cloud/vision/v1p2beta1:vision_go_proto -google/cloud/vision/v1p2beta1/geometry.proto,@go_googleapis//google/cloud/vision/v1p2beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1,@go_googleapis//google/cloud/vision/v1p2beta1:vision_go_proto -google/cloud/vision/v1p2beta1/web_detection.proto,@go_googleapis//google/cloud/vision/v1p2beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1,@go_googleapis//google/cloud/vision/v1p2beta1:vision_go_proto -google/cloud/vision/v1p2beta1/text_annotation.proto,@go_googleapis//google/cloud/vision/v1p2beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1,@go_googleapis//google/cloud/vision/v1p2beta1:vision_go_proto -google/cloud/vision/v1p1beta1/image_annotator.proto,@go_googleapis//google/cloud/vision/v1p1beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1,@go_googleapis//google/cloud/vision/v1p1beta1:vision_go_proto -google/cloud/vision/v1p1beta1/geometry.proto,@go_googleapis//google/cloud/vision/v1p1beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1,@go_googleapis//google/cloud/vision/v1p1beta1:vision_go_proto -google/cloud/vision/v1p1beta1/web_detection.proto,@go_googleapis//google/cloud/vision/v1p1beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1,@go_googleapis//google/cloud/vision/v1p1beta1:vision_go_proto -google/cloud/vision/v1p1beta1/text_annotation.proto,@go_googleapis//google/cloud/vision/v1p1beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1,@go_googleapis//google/cloud/vision/v1p1beta1:vision_go_proto +google/cloud/resourcemanager/v2/folders.proto,@go_googleapis//google/cloud/resourcemanager/v2:resourcemanager_proto,google.golang.org/genproto/googleapis/cloud/resourcemanager/v2,@go_googleapis//google/cloud/resourcemanager/v2:resourcemanager_go_proto +google/cloud/runtimeconfig/v1beta1/resources.proto,@go_googleapis//google/cloud/runtimeconfig/v1beta1:runtimeconfig_proto,google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1,@go_googleapis//google/cloud/runtimeconfig/v1beta1:runtimeconfig_go_proto +google/cloud/runtimeconfig/v1beta1/runtimeconfig.proto,@go_googleapis//google/cloud/runtimeconfig/v1beta1:runtimeconfig_proto,google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1,@go_googleapis//google/cloud/runtimeconfig/v1beta1:runtimeconfig_go_proto google/cloud/speech/v1/cloud_speech.proto,@go_googleapis//google/cloud/speech/v1:speech_proto,google.golang.org/genproto/googleapis/cloud/speech/v1,@go_googleapis//google/cloud/speech/v1:speech_go_proto -google/cloud/speech/v1beta1/cloud_speech.proto,@go_googleapis//google/cloud/speech/v1beta1:speech_proto,google.golang.org/genproto/googleapis/cloud/speech/v1beta1,@go_googleapis//google/cloud/speech/v1beta1:speech_go_proto google/cloud/speech/v1p1beta1/cloud_speech.proto,@go_googleapis//google/cloud/speech/v1p1beta1:speech_proto,google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1,@go_googleapis//google/cloud/speech/v1p1beta1:speech_go_proto -google/cloud/iot/v1/device_manager.proto,@go_googleapis//google/cloud/iot/v1:iot_proto,google.golang.org/genproto/googleapis/cloud/iot/v1,@go_googleapis//google/cloud/iot/v1:iot_go_proto -google/cloud/iot/v1/resources.proto,@go_googleapis//google/cloud/iot/v1:iot_proto,google.golang.org/genproto/googleapis/cloud/iot/v1,@go_googleapis//google/cloud/iot/v1:iot_go_proto -google/cloud/videointelligence/v1/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1,@go_googleapis//google/cloud/videointelligence/v1:videointelligence_go_proto -google/cloud/videointelligence/v1beta2/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1beta2:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta2,@go_googleapis//google/cloud/videointelligence/v1beta2:videointelligence_go_proto -google/cloud/videointelligence/v1beta1/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1beta1:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta1,@go_googleapis//google/cloud/videointelligence/v1beta1:videointelligence_go_proto -google/cloud/videointelligence/v1p1beta1/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1p1beta1:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1,@go_googleapis//google/cloud/videointelligence/v1p1beta1:videointelligence_go_proto -google/cloud/audit/audit_log.proto,@go_googleapis//google/cloud/audit:audit_proto,google.golang.org/genproto/googleapis/cloud/audit,@go_googleapis//google/cloud/audit:audit_go_proto google/cloud/support/common.proto,@go_googleapis//google/cloud/support:common_proto,google.golang.org/genproto/googleapis/cloud/support/common,@go_googleapis//google/cloud/support:common_go_proto google/cloud/support/v1alpha1/cloud_support.proto,@go_googleapis//google/cloud/support/v1alpha1:support_proto,google.golang.org/genproto/googleapis/cloud/support/v1alpha1,@go_googleapis//google/cloud/support/v1alpha1:support_go_proto -google/cloud/ml/v1/operation_metadata.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto -google/cloud/ml/v1/job_service.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto -google/cloud/ml/v1/prediction_service.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto -google/cloud/ml/v1/model_service.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto -google/cloud/ml/v1/project_service.proto,@go_googleapis//google/cloud/ml/v1:ml_proto,google.golang.org/genproto/googleapis/cloud/ml/v1,@go_googleapis//google/cloud/ml/v1:ml_go_proto +google/cloud/tasks/v2beta2/cloudtasks.proto,@go_googleapis//google/cloud/tasks/v2beta2:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta2,@go_googleapis//google/cloud/tasks/v2beta2:tasks_go_proto +google/cloud/tasks/v2beta2/queue.proto,@go_googleapis//google/cloud/tasks/v2beta2:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta2,@go_googleapis//google/cloud/tasks/v2beta2:tasks_go_proto +google/cloud/tasks/v2beta2/target.proto,@go_googleapis//google/cloud/tasks/v2beta2:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta2,@go_googleapis//google/cloud/tasks/v2beta2:tasks_go_proto +google/cloud/tasks/v2beta2/task.proto,@go_googleapis//google/cloud/tasks/v2beta2:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta2,@go_googleapis//google/cloud/tasks/v2beta2:tasks_go_proto +google/cloud/tasks/v2beta3/cloudtasks.proto,@go_googleapis//google/cloud/tasks/v2beta3:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta3,@go_googleapis//google/cloud/tasks/v2beta3:tasks_go_proto +google/cloud/tasks/v2beta3/queue.proto,@go_googleapis//google/cloud/tasks/v2beta3:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta3,@go_googleapis//google/cloud/tasks/v2beta3:tasks_go_proto +google/cloud/tasks/v2beta3/target.proto,@go_googleapis//google/cloud/tasks/v2beta3:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta3,@go_googleapis//google/cloud/tasks/v2beta3:tasks_go_proto +google/cloud/tasks/v2beta3/task.proto,@go_googleapis//google/cloud/tasks/v2beta3:tasks_proto,google.golang.org/genproto/googleapis/cloud/tasks/v2beta3,@go_googleapis//google/cloud/tasks/v2beta3:tasks_go_proto google/cloud/texttospeech/v1/cloud_tts.proto,@go_googleapis//google/cloud/texttospeech/v1:texttospeech_proto,google.golang.org/genproto/googleapis/cloud/texttospeech/v1,@go_googleapis//google/cloud/texttospeech/v1:texttospeech_go_proto google/cloud/texttospeech/v1beta1/cloud_tts.proto,@go_googleapis//google/cloud/texttospeech/v1beta1:texttospeech_proto,google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1,@go_googleapis//google/cloud/texttospeech/v1beta1:texttospeech_go_proto -google/cloud/functions/v1beta2/operations.proto,@go_googleapis//google/cloud/functions/v1beta2:functions_proto,google.golang.org/genproto/googleapis/cloud/functions/v1beta2,@go_googleapis//google/cloud/functions/v1beta2:functions_go_proto -google/cloud/functions/v1beta2/functions.proto,@go_googleapis//google/cloud/functions/v1beta2:functions_proto,google.golang.org/genproto/googleapis/cloud/functions/v1beta2,@go_googleapis//google/cloud/functions/v1beta2:functions_go_proto -google/cloud/billing/v1/cloud_billing.proto,@go_googleapis//google/cloud/billing/v1:billing_proto,google.golang.org/genproto/googleapis/cloud/billing/v1,@go_googleapis//google/cloud/billing/v1:billing_go_proto -google/cloud/dataproc/v1/operations.proto,@go_googleapis//google/cloud/dataproc/v1:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1,@go_googleapis//google/cloud/dataproc/v1:dataproc_go_proto -google/cloud/dataproc/v1/clusters.proto,@go_googleapis//google/cloud/dataproc/v1:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1,@go_googleapis//google/cloud/dataproc/v1:dataproc_go_proto -google/cloud/dataproc/v1/jobs.proto,@go_googleapis//google/cloud/dataproc/v1:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1,@go_googleapis//google/cloud/dataproc/v1:dataproc_go_proto -google/cloud/dataproc/v1beta2/operations.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto -google/cloud/dataproc/v1beta2/clusters.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto -google/cloud/dataproc/v1beta2/jobs.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto -google/cloud/dataproc/v1beta2/workflow_templates.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto -google/cloud/dataproc/v1beta2/shared.proto,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_proto,google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2,@go_googleapis//google/cloud/dataproc/v1beta2:dataproc_go_proto -google/api/context.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/http.proto,@go_googleapis//google/api:annotations_proto,google.golang.org/genproto/googleapis/api/annotations,@go_googleapis//google/api:annotations_go_proto -google/api/config_change.proto,@go_googleapis//google/api:configchange_proto,google.golang.org/genproto/googleapis/api/configchange,@go_googleapis//google/api:configchange_go_proto -google/api/system_parameter.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/monitoring.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/distribution.proto,@go_googleapis//google/api:distribution_proto,google.golang.org/genproto/googleapis/api/distribution,@go_googleapis//google/api:distribution_go_proto -google/api/endpoint.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/usage.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/monitored_resource.proto,@go_googleapis//google/api:monitoredres_proto,google.golang.org/genproto/googleapis/api/monitoredres,@go_googleapis//google/api:monitoredres_go_proto -google/api/annotations.proto,@go_googleapis//google/api:annotations_proto,google.golang.org/genproto/googleapis/api/annotations,@go_googleapis//google/api:annotations_go_proto -google/api/control.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/metric.proto,@go_googleapis//google/api:metric_proto,google.golang.org/genproto/googleapis/api/metric,@go_googleapis//google/api:metric_go_proto -google/api/label.proto,@go_googleapis//google/api:label_proto,google.golang.org/genproto/googleapis/api/label,@go_googleapis//google/api:label_go_proto -google/api/consumer.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/log.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/billing.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/service.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/logging.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/documentation.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/quota.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/auth.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/backend.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/source_info.proto,@go_googleapis//google/api:serviceconfig_proto,google.golang.org/genproto/googleapis/api/serviceconfig,@go_googleapis//google/api:serviceconfig_go_proto -google/api/httpbody.proto,@go_googleapis//google/api:httpbody_proto,google.golang.org/genproto/googleapis/api/httpbody,@go_googleapis//google/api:httpbody_go_proto -google/api/experimental/authorization_config.proto,@go_googleapis//google/api/experimental:api_proto,google.golang.org/genproto/googleapis/api,@go_googleapis//google/api/experimental:api_go_proto -google/api/experimental/experimental.proto,@go_googleapis//google/api/experimental:api_proto,google.golang.org/genproto/googleapis/api,@go_googleapis//google/api/experimental:api_go_proto -google/api/servicemanagement/v1/servicemanager.proto,@go_googleapis//google/api/servicemanagement/v1:servicemanagement_proto,google.golang.org/genproto/googleapis/api/servicemanagement/v1,@go_googleapis//google/api/servicemanagement/v1:servicemanagement_go_proto -google/api/servicemanagement/v1/resources.proto,@go_googleapis//google/api/servicemanagement/v1:servicemanagement_proto,google.golang.org/genproto/googleapis/api/servicemanagement/v1,@go_googleapis//google/api/servicemanagement/v1:servicemanagement_go_proto -google/api/servicecontrol/v1/quota_controller.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto -google/api/servicecontrol/v1/distribution.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto -google/api/servicecontrol/v1/check_error.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto -google/api/servicecontrol/v1/operation.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto -google/api/servicecontrol/v1/metric_value.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto -google/api/servicecontrol/v1/log_entry.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto -google/api/servicecontrol/v1/service_controller.proto,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_proto,google.golang.org/genproto/googleapis/api/servicecontrol/v1,@go_googleapis//google/api/servicecontrol/v1:servicecontrol_go_proto -google/pubsub/v1/pubsub.proto,@go_googleapis//google/pubsub/v1:pubsub_proto,google.golang.org/genproto/googleapis/pubsub/v1,@go_googleapis//google/pubsub/v1:pubsub_go_proto -google/pubsub/v1beta2/pubsub.proto,@go_googleapis//google/pubsub/v1beta2:pubsub_proto,google.golang.org/genproto/googleapis/pubsub/v1beta2,@go_googleapis//google/pubsub/v1beta2:pubsub_go_proto -google/spanner/v1/mutation.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto -google/spanner/v1/spanner.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto -google/spanner/v1/transaction.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto -google/spanner/v1/keys.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto -google/spanner/v1/type.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto -google/spanner/v1/query_plan.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto -google/spanner/v1/result_set.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto -google/spanner/admin/database/v1/spanner_database_admin.proto,@go_googleapis//google/spanner/admin/database/v1:database_proto,google.golang.org/genproto/googleapis/spanner/admin/database/v1,@go_googleapis//google/spanner/admin/database/v1:database_go_proto -google/spanner/admin/instance/v1/spanner_instance_admin.proto,@go_googleapis//google/spanner/admin/instance/v1:instance_proto,google.golang.org/genproto/googleapis/spanner/admin/instance/v1,@go_googleapis//google/spanner/admin/instance/v1:instance_go_proto -google/monitoring/v3/group.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto -google/monitoring/v3/mutation_record.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto -google/monitoring/v3/notification.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/cloud/videointelligence/v1/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1,@go_googleapis//google/cloud/videointelligence/v1:videointelligence_go_proto +google/cloud/videointelligence/v1beta1/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1beta1:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta1,@go_googleapis//google/cloud/videointelligence/v1beta1:videointelligence_go_proto +google/cloud/videointelligence/v1beta2/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1beta2:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta2,@go_googleapis//google/cloud/videointelligence/v1beta2:videointelligence_go_proto +google/cloud/videointelligence/v1p1beta1/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1p1beta1:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1,@go_googleapis//google/cloud/videointelligence/v1p1beta1:videointelligence_go_proto +google/cloud/videointelligence/v1p2beta1/video_intelligence.proto,@go_googleapis//google/cloud/videointelligence/v1p2beta1:videointelligence_proto,google.golang.org/genproto/googleapis/cloud/videointelligence/v1p2beta1,@go_googleapis//google/cloud/videointelligence/v1p2beta1:videointelligence_go_proto +google/cloud/vision/v1/geometry.proto,@go_googleapis//google/cloud/vision/v1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1,@go_googleapis//google/cloud/vision/v1:vision_go_proto +google/cloud/vision/v1/image_annotator.proto,@go_googleapis//google/cloud/vision/v1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1,@go_googleapis//google/cloud/vision/v1:vision_go_proto +google/cloud/vision/v1/text_annotation.proto,@go_googleapis//google/cloud/vision/v1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1,@go_googleapis//google/cloud/vision/v1:vision_go_proto +google/cloud/vision/v1/web_detection.proto,@go_googleapis//google/cloud/vision/v1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1,@go_googleapis//google/cloud/vision/v1:vision_go_proto +google/cloud/vision/v1p1beta1/geometry.proto,@go_googleapis//google/cloud/vision/v1p1beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1,@go_googleapis//google/cloud/vision/v1p1beta1:vision_go_proto +google/cloud/vision/v1p1beta1/image_annotator.proto,@go_googleapis//google/cloud/vision/v1p1beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1,@go_googleapis//google/cloud/vision/v1p1beta1:vision_go_proto +google/cloud/vision/v1p1beta1/text_annotation.proto,@go_googleapis//google/cloud/vision/v1p1beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1,@go_googleapis//google/cloud/vision/v1p1beta1:vision_go_proto +google/cloud/vision/v1p1beta1/web_detection.proto,@go_googleapis//google/cloud/vision/v1p1beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1,@go_googleapis//google/cloud/vision/v1p1beta1:vision_go_proto +google/cloud/vision/v1p2beta1/geometry.proto,@go_googleapis//google/cloud/vision/v1p2beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1,@go_googleapis//google/cloud/vision/v1p2beta1:vision_go_proto +google/cloud/vision/v1p2beta1/image_annotator.proto,@go_googleapis//google/cloud/vision/v1p2beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1,@go_googleapis//google/cloud/vision/v1p2beta1:vision_go_proto +google/cloud/vision/v1p2beta1/text_annotation.proto,@go_googleapis//google/cloud/vision/v1p2beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1,@go_googleapis//google/cloud/vision/v1p2beta1:vision_go_proto +google/cloud/vision/v1p2beta1/web_detection.proto,@go_googleapis//google/cloud/vision/v1p2beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1,@go_googleapis//google/cloud/vision/v1p2beta1:vision_go_proto +google/cloud/vision/v1p3beta1/geometry.proto,@go_googleapis//google/cloud/vision/v1p3beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1,@go_googleapis//google/cloud/vision/v1p3beta1:vision_go_proto +google/cloud/vision/v1p3beta1/image_annotator.proto,@go_googleapis//google/cloud/vision/v1p3beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1,@go_googleapis//google/cloud/vision/v1p3beta1:vision_go_proto +google/cloud/vision/v1p3beta1/product_search.proto,@go_googleapis//google/cloud/vision/v1p3beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1,@go_googleapis//google/cloud/vision/v1p3beta1:vision_go_proto +google/cloud/vision/v1p3beta1/product_search_service.proto,@go_googleapis//google/cloud/vision/v1p3beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1,@go_googleapis//google/cloud/vision/v1p3beta1:vision_go_proto +google/cloud/vision/v1p3beta1/text_annotation.proto,@go_googleapis//google/cloud/vision/v1p3beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1,@go_googleapis//google/cloud/vision/v1p3beta1:vision_go_proto +google/cloud/vision/v1p3beta1/web_detection.proto,@go_googleapis//google/cloud/vision/v1p3beta1:vision_proto,google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1,@go_googleapis//google/cloud/vision/v1p3beta1:vision_go_proto +google/cloud/websecurityscanner/v1alpha/crawled_url.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto +google/cloud/websecurityscanner/v1alpha/finding.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto +google/cloud/websecurityscanner/v1alpha/finding_addon.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto +google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto +google/cloud/websecurityscanner/v1alpha/scan_config.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto +google/cloud/websecurityscanner/v1alpha/scan_run.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto +google/cloud/websecurityscanner/v1alpha/web_security_scanner.proto,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_proto,google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha,@go_googleapis//google/cloud/websecurityscanner/v1alpha:websecurityscanner_go_proto +google/container/v1/cluster_service.proto,@go_googleapis//google/container/v1:container_proto,google.golang.org/genproto/googleapis/container/v1,@go_googleapis//google/container/v1:container_go_proto +google/container/v1alpha1/cluster_service.proto,@go_googleapis//google/container/v1alpha1:container_proto,google.golang.org/genproto/googleapis/container/v1alpha1,@go_googleapis//google/container/v1alpha1:container_go_proto +google/container/v1beta1/cluster_service.proto,@go_googleapis//google/container/v1beta1:container_proto,google.golang.org/genproto/googleapis/container/v1beta1,@go_googleapis//google/container/v1beta1:container_go_proto +google/datastore/admin/v1/datastore_admin.proto,@go_googleapis//google/datastore/admin/v1:admin_proto,google.golang.org/genproto/googleapis/datastore/admin/v1,@go_googleapis//google/datastore/admin/v1:admin_go_proto +google/datastore/admin/v1/index.proto,@go_googleapis//google/datastore/admin/v1:admin_proto,google.golang.org/genproto/googleapis/datastore/admin/v1,@go_googleapis//google/datastore/admin/v1:admin_go_proto +google/datastore/admin/v1beta1/datastore_admin.proto,@go_googleapis//google/datastore/admin/v1beta1:admin_proto,google.golang.org/genproto/googleapis/datastore/admin/v1beta1,@go_googleapis//google/datastore/admin/v1beta1:admin_go_proto +google/datastore/v1/datastore.proto,@go_googleapis//google/datastore/v1:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1,@go_googleapis//google/datastore/v1:datastore_go_proto +google/datastore/v1/entity.proto,@go_googleapis//google/datastore/v1:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1,@go_googleapis//google/datastore/v1:datastore_go_proto +google/datastore/v1/query.proto,@go_googleapis//google/datastore/v1:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1,@go_googleapis//google/datastore/v1:datastore_go_proto +google/datastore/v1beta3/datastore.proto,@go_googleapis//google/datastore/v1beta3:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1beta3,@go_googleapis//google/datastore/v1beta3:datastore_go_proto +google/datastore/v1beta3/entity.proto,@go_googleapis//google/datastore/v1beta3:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1beta3,@go_googleapis//google/datastore/v1beta3:datastore_go_proto +google/datastore/v1beta3/query.proto,@go_googleapis//google/datastore/v1beta3:datastore_proto,google.golang.org/genproto/googleapis/datastore/v1beta3,@go_googleapis//google/datastore/v1beta3:datastore_go_proto +google/devtools/build/v1/build_events.proto,@go_googleapis//google/devtools/build/v1:build_proto,google.golang.org/genproto/googleapis/devtools/build/v1,@go_googleapis//google/devtools/build/v1:build_go_proto +google/devtools/build/v1/build_status.proto,@go_googleapis//google/devtools/build/v1:build_proto,google.golang.org/genproto/googleapis/devtools/build/v1,@go_googleapis//google/devtools/build/v1:build_go_proto +google/devtools/build/v1/publish_build_event.proto,@go_googleapis//google/devtools/build/v1:build_proto,google.golang.org/genproto/googleapis/devtools/build/v1,@go_googleapis//google/devtools/build/v1:build_go_proto +google/devtools/cloudbuild/v1/cloudbuild.proto,@go_googleapis//google/devtools/cloudbuild/v1:cloudbuild_proto,google.golang.org/genproto/googleapis/devtools/cloudbuild/v1,@go_googleapis//google/devtools/cloudbuild/v1:cloudbuild_go_proto +google/devtools/clouddebugger/v2/controller.proto,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_proto,google.golang.org/genproto/googleapis/devtools/clouddebugger/v2,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_go_proto +google/devtools/clouddebugger/v2/data.proto,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_proto,google.golang.org/genproto/googleapis/devtools/clouddebugger/v2,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_go_proto +google/devtools/clouddebugger/v2/debugger.proto,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_proto,google.golang.org/genproto/googleapis/devtools/clouddebugger/v2,@go_googleapis//google/devtools/clouddebugger/v2:clouddebugger_go_proto +google/devtools/clouderrorreporting/v1beta1/common.proto,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_proto,google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_go_proto +google/devtools/clouderrorreporting/v1beta1/error_group_service.proto,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_proto,google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_go_proto +google/devtools/clouderrorreporting/v1beta1/error_stats_service.proto,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_proto,google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_go_proto +google/devtools/clouderrorreporting/v1beta1/report_errors_service.proto,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_proto,google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1,@go_googleapis//google/devtools/clouderrorreporting/v1beta1:clouderrorreporting_go_proto +google/devtools/cloudprofiler/v2/profiler.proto,@go_googleapis//google/devtools/cloudprofiler/v2:cloudprofiler_proto,google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2,@go_googleapis//google/devtools/cloudprofiler/v2:cloudprofiler_go_proto +google/devtools/cloudtrace/v1/trace.proto,@go_googleapis//google/devtools/cloudtrace/v1:cloudtrace_proto,google.golang.org/genproto/googleapis/devtools/cloudtrace/v1,@go_googleapis//google/devtools/cloudtrace/v1:cloudtrace_go_proto +google/devtools/cloudtrace/v2/trace.proto,@go_googleapis//google/devtools/cloudtrace/v2:cloudtrace_proto,google.golang.org/genproto/googleapis/devtools/cloudtrace/v2,@go_googleapis//google/devtools/cloudtrace/v2:cloudtrace_go_proto +google/devtools/cloudtrace/v2/tracing.proto,@go_googleapis//google/devtools/cloudtrace/v2:cloudtrace_proto,google.golang.org/genproto/googleapis/devtools/cloudtrace/v2,@go_googleapis//google/devtools/cloudtrace/v2:cloudtrace_go_proto +google/devtools/containeranalysis/v1alpha1/bill_of_materials.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto +google/devtools/containeranalysis/v1alpha1/containeranalysis.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto +google/devtools/containeranalysis/v1alpha1/image_basis.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto +google/devtools/containeranalysis/v1alpha1/package_vulnerability.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto +google/devtools/containeranalysis/v1alpha1/provenance.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto +google/devtools/containeranalysis/v1alpha1/source_context.proto,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1,@go_googleapis//google/devtools/containeranalysis/v1alpha1:containeranalysis_go_proto +google/devtools/containeranalysis/v1beta1/attestation/attestation.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/attestation:attestation_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/attestation,@go_googleapis//google/devtools/containeranalysis/v1beta1/attestation:attestation_go_proto +google/devtools/containeranalysis/v1beta1/build/build.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/build:build_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/build,@go_googleapis//google/devtools/containeranalysis/v1beta1/build:build_go_proto +google/devtools/containeranalysis/v1beta1/common/common.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/common:common_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/common,@go_googleapis//google/devtools/containeranalysis/v1beta1/common:common_go_proto +google/devtools/containeranalysis/v1beta1/containeranalysis.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1:containeranalysis_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1,@go_googleapis//google/devtools/containeranalysis/v1beta1:containeranalysis_go_proto +google/devtools/containeranalysis/v1beta1/deployment/deployment.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/deployment:deployment_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/deployment,@go_googleapis//google/devtools/containeranalysis/v1beta1/deployment:deployment_go_proto +google/devtools/containeranalysis/v1beta1/discovery/discovery.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/discovery:discovery_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/discovery,@go_googleapis//google/devtools/containeranalysis/v1beta1/discovery:discovery_go_proto +google/devtools/containeranalysis/v1beta1/grafeas/grafeas.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/grafeas:grafeas_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/grafeas,@go_googleapis//google/devtools/containeranalysis/v1beta1/grafeas:grafeas_go_proto +google/devtools/containeranalysis/v1beta1/image/image.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/image:image_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/image,@go_googleapis//google/devtools/containeranalysis/v1beta1/image:image_go_proto +google/devtools/containeranalysis/v1beta1/package/package.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/package:package_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/package,@go_googleapis//google/devtools/containeranalysis/v1beta1/package:package_go_proto +google/devtools/containeranalysis/v1beta1/provenance/provenance.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/provenance:provenance_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/provenance,@go_googleapis//google/devtools/containeranalysis/v1beta1/provenance:provenance_go_proto +google/devtools/containeranalysis/v1beta1/source/source.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/source:source_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/source,@go_googleapis//google/devtools/containeranalysis/v1beta1/source:source_go_proto +google/devtools/containeranalysis/v1beta1/vulnerability/vulnerability.proto,@go_googleapis//google/devtools/containeranalysis/v1beta1/vulnerability:vulnerability_proto,google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/vulnerability,@go_googleapis//google/devtools/containeranalysis/v1beta1/vulnerability:vulnerability_go_proto +google/devtools/remoteexecution/v1test/remote_execution.proto,@go_googleapis//google/devtools/remoteexecution/v1test:remoteexecution_proto,google.golang.org/genproto/googleapis/devtools/remoteexecution/v1test,@go_googleapis//google/devtools/remoteexecution/v1test:remoteexecution_go_proto +google/devtools/remoteworkers/v1test2/bots.proto,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_proto,google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_go_proto +google/devtools/remoteworkers/v1test2/command.proto,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_proto,google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_go_proto +google/devtools/remoteworkers/v1test2/tasks.proto,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_proto,google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_go_proto +google/devtools/remoteworkers/v1test2/worker.proto,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_proto,google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2,@go_googleapis//google/devtools/remoteworkers/v1test2:remoteworkers_go_proto +google/devtools/resultstore/v2/action.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/common.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/configuration.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/configured_target.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/coverage.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/coverage_summary.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/file.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/file_set.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/invocation.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/resultstore_download.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/resultstore_file_download.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/target.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/resultstore/v2/test_suite.proto,@go_googleapis//google/devtools/resultstore/v2:resultstore_proto,google.golang.org/genproto/googleapis/devtools/resultstore/v2,@go_googleapis//google/devtools/resultstore/v2:resultstore_go_proto +google/devtools/source/v1/source_context.proto,@go_googleapis//google/devtools/source/v1:source_proto,google.golang.org/genproto/googleapis/devtools/source/v1,@go_googleapis//google/devtools/source/v1:source_go_proto +google/devtools/sourcerepo/v1/sourcerepo.proto,@go_googleapis//google/devtools/sourcerepo/v1:sourcerepo_proto,google.golang.org/genproto/googleapis/devtools/sourcerepo/v1,@go_googleapis//google/devtools/sourcerepo/v1:sourcerepo_go_proto +google/example/library/v1/library.proto,@go_googleapis//google/example/library/v1:library_proto,google.golang.org/genproto/googleapis/example/library/v1,@go_googleapis//google/example/library/v1:library_go_proto +google/firestore/admin/v1beta1/firestore_admin.proto,@go_googleapis//google/firestore/admin/v1beta1:admin_proto,google.golang.org/genproto/googleapis/firestore/admin/v1beta1,@go_googleapis//google/firestore/admin/v1beta1:admin_go_proto +google/firestore/admin/v1beta1/index.proto,@go_googleapis//google/firestore/admin/v1beta1:admin_proto,google.golang.org/genproto/googleapis/firestore/admin/v1beta1,@go_googleapis//google/firestore/admin/v1beta1:admin_go_proto +google/firestore/admin/v1beta2/field.proto,@go_googleapis//google/firestore/admin/v1beta2:admin_proto,google.golang.org/genproto/googleapis/firestore/admin/v1beta2,@go_googleapis//google/firestore/admin/v1beta2:admin_go_proto +google/firestore/admin/v1beta2/firestore_admin.proto,@go_googleapis//google/firestore/admin/v1beta2:admin_proto,google.golang.org/genproto/googleapis/firestore/admin/v1beta2,@go_googleapis//google/firestore/admin/v1beta2:admin_go_proto +google/firestore/admin/v1beta2/index.proto,@go_googleapis//google/firestore/admin/v1beta2:admin_proto,google.golang.org/genproto/googleapis/firestore/admin/v1beta2,@go_googleapis//google/firestore/admin/v1beta2:admin_go_proto +google/firestore/admin/v1beta2/operation.proto,@go_googleapis//google/firestore/admin/v1beta2:admin_proto,google.golang.org/genproto/googleapis/firestore/admin/v1beta2,@go_googleapis//google/firestore/admin/v1beta2:admin_go_proto +google/firestore/v1beta1/common.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto +google/firestore/v1beta1/document.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto +google/firestore/v1beta1/firestore.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto +google/firestore/v1beta1/query.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto +google/firestore/v1beta1/write.proto,@go_googleapis//google/firestore/v1beta1:firestore_proto,google.golang.org/genproto/googleapis/firestore/v1beta1,@go_googleapis//google/firestore/v1beta1:firestore_go_proto +google/genomics/v1/annotations.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/cigar.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/datasets.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/operations.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/position.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/range.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/readalignment.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/readgroup.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/readgroupset.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/reads.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/references.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1/variants.proto,@go_googleapis//google/genomics/v1:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1,@go_googleapis//google/genomics/v1:genomics_go_proto +google/genomics/v1alpha2/pipelines.proto,@go_googleapis//google/genomics/v1alpha2:genomics_proto,google.golang.org/genproto/googleapis/genomics/v1alpha2,@go_googleapis//google/genomics/v1alpha2:genomics_go_proto +google/home/graph/v1/device.proto,@go_googleapis//google/home/graph/v1:graph_proto,google.golang.org/genproto/googleapis/home/graph/v1,@go_googleapis//google/home/graph/v1:graph_go_proto +google/home/graph/v1/homegraph.proto,@go_googleapis//google/home/graph/v1:graph_proto,google.golang.org/genproto/googleapis/home/graph/v1,@go_googleapis//google/home/graph/v1:graph_go_proto +google/iam/admin/v1/iam.proto,@go_googleapis//google/iam/admin/v1:admin_proto,google.golang.org/genproto/googleapis/iam/admin/v1,@go_googleapis//google/iam/admin/v1:admin_go_proto +google/iam/credentials/v1/common.proto,@go_googleapis//google/iam/credentials/v1:credentials_proto,google.golang.org/genproto/googleapis/iam/credentials/v1,@go_googleapis//google/iam/credentials/v1:credentials_go_proto +google/iam/credentials/v1/iamcredentials.proto,@go_googleapis//google/iam/credentials/v1:credentials_proto,google.golang.org/genproto/googleapis/iam/credentials/v1,@go_googleapis//google/iam/credentials/v1:credentials_go_proto +google/iam/v1/iam_policy.proto,@go_googleapis//google/iam/v1:iam_proto,google.golang.org/genproto/googleapis/iam/v1,@go_googleapis//google/iam/v1:iam_go_proto +google/iam/v1/logging/audit_data.proto,@go_googleapis//google/iam/v1/logging:logging_proto,google.golang.org/genproto/googleapis/iam/v1/logging,@go_googleapis//google/iam/v1/logging:logging_go_proto +google/iam/v1/policy.proto,@go_googleapis//google/iam/v1:iam_proto,google.golang.org/genproto/googleapis/iam/v1,@go_googleapis//google/iam/v1:iam_go_proto +google/logging/type/http_request.proto,@go_googleapis//google/logging/type:ltype_proto,google.golang.org/genproto/googleapis/logging/type,@go_googleapis//google/logging/type:ltype_go_proto +google/logging/type/log_severity.proto,@go_googleapis//google/logging/type:ltype_proto,google.golang.org/genproto/googleapis/logging/type,@go_googleapis//google/logging/type:ltype_go_proto +google/logging/v2/log_entry.proto,@go_googleapis//google/logging/v2:logging_proto,google.golang.org/genproto/googleapis/logging/v2,@go_googleapis//google/logging/v2:logging_go_proto +google/logging/v2/logging.proto,@go_googleapis//google/logging/v2:logging_proto,google.golang.org/genproto/googleapis/logging/v2,@go_googleapis//google/logging/v2:logging_go_proto +google/logging/v2/logging_config.proto,@go_googleapis//google/logging/v2:logging_proto,google.golang.org/genproto/googleapis/logging/v2,@go_googleapis//google/logging/v2:logging_go_proto +google/logging/v2/logging_metrics.proto,@go_googleapis//google/logging/v2:logging_proto,google.golang.org/genproto/googleapis/logging/v2,@go_googleapis//google/logging/v2:logging_go_proto +google/longrunning/operations.proto,@go_googleapis//google/longrunning:longrunning_proto,google.golang.org/genproto/googleapis/longrunning,@go_googleapis//google/longrunning:longrunning_go_proto +google/monitoring/v3/alert.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto google/monitoring/v3/alert_service.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto -google/monitoring/v3/uptime_service.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/common.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/dropped_labels.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/group.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto google/monitoring/v3/group_service.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto -google/monitoring/v3/alert.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto -google/monitoring/v3/uptime.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto google/monitoring/v3/metric.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto -google/monitoring/v3/notification_service.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto google/monitoring/v3/metric_service.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto -google/monitoring/v3/common.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/mutation_record.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/notification.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/notification_service.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/span_context.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/uptime.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/monitoring/v3/uptime_service.proto,@go_googleapis//google/monitoring/v3:monitoring_proto,google.golang.org/genproto/googleapis/monitoring/v3,@go_googleapis//google/monitoring/v3:monitoring_go_proto +google/privacy/dlp/v2/dlp.proto,@go_googleapis//google/privacy/dlp/v2:dlp_proto,google.golang.org/genproto/googleapis/privacy/dlp/v2,@go_googleapis//google/privacy/dlp/v2:dlp_go_proto +google/privacy/dlp/v2/storage.proto,@go_googleapis//google/privacy/dlp/v2:dlp_proto,google.golang.org/genproto/googleapis/privacy/dlp/v2,@go_googleapis//google/privacy/dlp/v2:dlp_go_proto +google/pubsub/v1/pubsub.proto,@go_googleapis//google/pubsub/v1:pubsub_proto,google.golang.org/genproto/googleapis/pubsub/v1,@go_googleapis//google/pubsub/v1:pubsub_go_proto +google/pubsub/v1beta2/pubsub.proto,@go_googleapis//google/pubsub/v1beta2:pubsub_proto,google.golang.org/genproto/googleapis/pubsub/v1beta2,@go_googleapis//google/pubsub/v1beta2:pubsub_go_proto google/rpc/code.proto,@go_googleapis//google/rpc:code_proto,google.golang.org/genproto/googleapis/rpc/code,@go_googleapis//google/rpc:code_go_proto -google/rpc/status.proto,@go_googleapis//google/rpc:status_proto,google.golang.org/genproto/googleapis/rpc/status,@go_googleapis//google/rpc:status_go_proto google/rpc/error_details.proto,@go_googleapis//google/rpc:errdetails_proto,google.golang.org/genproto/googleapis/rpc/errdetails,@go_googleapis//google/rpc:errdetails_go_proto +google/rpc/status.proto,@go_googleapis//google/rpc:status_proto,google.golang.org/genproto/googleapis/rpc/status,@go_googleapis//google/rpc:status_go_proto +google/spanner/admin/database/v1/spanner_database_admin.proto,@go_googleapis//google/spanner/admin/database/v1:database_proto,google.golang.org/genproto/googleapis/spanner/admin/database/v1,@go_googleapis//google/spanner/admin/database/v1:database_go_proto +google/spanner/admin/instance/v1/spanner_instance_admin.proto,@go_googleapis//google/spanner/admin/instance/v1:instance_proto,google.golang.org/genproto/googleapis/spanner/admin/instance/v1,@go_googleapis//google/spanner/admin/instance/v1:instance_go_proto +google/spanner/v1/keys.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto +google/spanner/v1/mutation.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto +google/spanner/v1/query_plan.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto +google/spanner/v1/result_set.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto +google/spanner/v1/spanner.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto +google/spanner/v1/transaction.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto +google/spanner/v1/type.proto,@go_googleapis//google/spanner/v1:spanner_proto,google.golang.org/genproto/googleapis/spanner/v1,@go_googleapis//google/spanner/v1:spanner_go_proto +google/storagetransfer/v1/transfer.proto,@go_googleapis//google/storagetransfer/v1:storagetransfer_proto,google.golang.org/genproto/googleapis/storagetransfer/v1,@go_googleapis//google/storagetransfer/v1:storagetransfer_go_proto +google/storagetransfer/v1/transfer_types.proto,@go_googleapis//google/storagetransfer/v1:storagetransfer_proto,google.golang.org/genproto/googleapis/storagetransfer/v1,@go_googleapis//google/storagetransfer/v1:storagetransfer_go_proto google/streetview/publish/v1/resources.proto,@go_googleapis//google/streetview/publish/v1:publish_proto,google.golang.org/genproto/googleapis/streetview/publish/v1,@go_googleapis//google/streetview/publish/v1:publish_go_proto google/streetview/publish/v1/rpcmessages.proto,@go_googleapis//google/streetview/publish/v1:publish_proto,google.golang.org/genproto/googleapis/streetview/publish/v1,@go_googleapis//google/streetview/publish/v1:publish_go_proto google/streetview/publish/v1/streetview_publish.proto,@go_googleapis//google/streetview/publish/v1:publish_proto,google.golang.org/genproto/googleapis/streetview/publish/v1,@go_googleapis//google/streetview/publish/v1:publish_go_proto -google/logging/v2/logging_metrics.proto,@go_googleapis//google/logging/v2:logging_proto,google.golang.org/genproto/googleapis/logging/v2,@go_googleapis//google/logging/v2:logging_go_proto -google/logging/v2/logging_config.proto,@go_googleapis//google/logging/v2:logging_proto,google.golang.org/genproto/googleapis/logging/v2,@go_googleapis//google/logging/v2:logging_go_proto -google/logging/v2/log_entry.proto,@go_googleapis//google/logging/v2:logging_proto,google.golang.org/genproto/googleapis/logging/v2,@go_googleapis//google/logging/v2:logging_go_proto -google/logging/v2/logging.proto,@go_googleapis//google/logging/v2:logging_proto,google.golang.org/genproto/googleapis/logging/v2,@go_googleapis//google/logging/v2:logging_go_proto -google/logging/type/log_severity.proto,@go_googleapis//google/logging/type:ltype_proto,google.golang.org/genproto/googleapis/logging/type,@go_googleapis//google/logging/type:ltype_go_proto -google/logging/type/http_request.proto,@go_googleapis//google/logging/type:ltype_proto,google.golang.org/genproto/googleapis/logging/type,@go_googleapis//google/logging/type:ltype_go_proto +google/type/color.proto,@go_googleapis//google/type:color_proto,google.golang.org/genproto/googleapis/type/color,@go_googleapis//google/type:color_go_proto +google/type/date.proto,@go_googleapis//google/type:date_proto,google.golang.org/genproto/googleapis/type/date,@go_googleapis//google/type:date_go_proto +google/type/dayofweek.proto,@go_googleapis//google/type:dayofweek_proto,google.golang.org/genproto/googleapis/type/dayofweek,@go_googleapis//google/type:dayofweek_go_proto +google/type/latlng.proto,@go_googleapis//google/type:latlng_proto,google.golang.org/genproto/googleapis/type/latlng,@go_googleapis//google/type:latlng_go_proto +google/type/money.proto,@go_googleapis//google/type:money_proto,google.golang.org/genproto/googleapis/type/money,@go_googleapis//google/type:money_go_proto +google/type/postal_address.proto,@go_googleapis//google/type:postaladdress_proto,google.golang.org/genproto/googleapis/type/postaladdress,@go_googleapis//google/type:postaladdress_go_proto +google/type/timeofday.proto,@go_googleapis//google/type:timeofday_proto,google.golang.org/genproto/googleapis/type/timeofday,@go_googleapis//google/type:timeofday_go_proto +google/watcher/v1/watch.proto,@go_googleapis//google/watcher/v1:watcher_proto,google.golang.org/genproto/googleapis/watcher/v1,@go_googleapis//google/watcher/v1:watcher_go_proto diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/resolve.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/resolve.go index 0d25ad3e1e20e..b153f8c026ef7 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/resolve.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto/resolve.go @@ -20,6 +20,7 @@ import ( "fmt" "log" "path" + "sort" "strings" "github.com/bazelbuild/bazel-gazelle/internal/config" @@ -44,7 +45,6 @@ func (_ *protoLang) Embeds(r *rule.Rule, from label.Label) []label.Label { } func (_ *protoLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, from label.Label) { - pc := GetProtoConfig(c) importsRaw := r.PrivateAttr(config.GazelleImportsKey) if importsRaw == nil { // may not be set in tests. @@ -52,19 +52,24 @@ func (_ *protoLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repos.R } imports := importsRaw.([]string) r.DelAttr("deps") - deps := make([]string, 0, len(imports)) + depSet := make(map[string]bool) for _, imp := range imports { - l, err := resolveProto(pc, ix, r, imp, from) + l, err := resolveProto(c, ix, r, imp, from) if err == skipImportError { continue } else if err != nil { log.Print(err) } else { l = l.Rel(from.Repo, from.Pkg) - deps = append(deps, l.String()) + depSet[l.String()] = true } } - if len(deps) > 0 { + if len(depSet) > 0 { + deps := make([]string, 0, len(depSet)) + for dep := range depSet { + deps = append(deps, dep) + } + sort.Strings(deps) r.SetAttr("deps", deps) } } @@ -74,11 +79,16 @@ var ( notFoundError = errors.New("not found") ) -func resolveProto(pc *ProtoConfig, ix *resolve.RuleIndex, r *rule.Rule, imp string, from label.Label) (label.Label, error) { +func resolveProto(c *config.Config, ix *resolve.RuleIndex, r *rule.Rule, imp string, from label.Label) (label.Label, error) { + pc := GetProtoConfig(c) if !strings.HasSuffix(imp, ".proto") { return label.NoLabel, fmt.Errorf("can't import non-proto: %q", imp) } + if l, ok := resolve.FindRuleWithOverride(c, resolve.ImportSpec{Imp: imp, Lang: "proto"}, "proto"); ok { + return l, nil + } + if l, ok := knownImports[imp]; ok && pc.Mode.ShouldUseKnownImports() { if l.Equal(from) { return label.NoLabel, skipImportError diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/BUILD b/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/BUILD index aa8395f08fa63..d4c641df89dd0 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/BUILD +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/BUILD @@ -4,6 +4,7 @@ go_library( name = "go_default_library", srcs = [ "dep.go", + "modules.go", "remote.go", "repo.go", ], diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/modules.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/modules.go new file mode 100644 index 0000000000000..f70c7c90ee2c1 --- /dev/null +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/modules.go @@ -0,0 +1,145 @@ +/* Copyright 2018 The Bazel Authors. All rights reserved. + +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 repos + +import ( + "bytes" + "encoding/json" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "regexp" + "runtime" + "strings" + + "github.com/bazelbuild/bazel-gazelle/internal/label" +) + +type module struct { + Path, Version string + Main bool +} + +var regexMixedVersioning = regexp.MustCompile(`^(.*?)-([0-9]{14})-([a-fA-F0-9]{12})$`) + +func toRepoRule(mod module) Repo { + var tag, commit string + + if gr := regexMixedVersioning.FindStringSubmatch(mod.Version); gr != nil { + commit = gr[3] + } else { + tag = strings.TrimSuffix(mod.Version, "+incompatible") + } + + return Repo{ + Name: label.ImportPathToBazelRepoName(mod.Path), + GoPrefix: mod.Path, + Commit: commit, + Tag: tag, + } +} + +func importRepoRulesModules(filename string) (repos []Repo, err error) { + tempDir, err := copyGoModToTemp(filename) + if err != nil { + return nil, err + } + defer os.RemoveAll(tempDir) + + data, err := goListModulesFn(tempDir) + if err != nil { + return nil, err + } + + dec := json.NewDecoder(bytes.NewReader(data)) + for dec.More() { + var mod module + if err := dec.Decode(&mod); err != nil { + return nil, err + } + if mod.Main { + continue + } + + repos = append(repos, toRepoRule(mod)) + } + + return repos, nil +} + +// goListModulesFn may be overridden by tests. +var goListModulesFn = goListModules + +// goListModules invokes "go list" in a directory containing a go.mod file. +func goListModules(dir string) ([]byte, error) { + goTool := findGoTool() + cmd := exec.Command(goTool, "list", "-m", "-json", "all") + cmd.Stderr = os.Stderr + cmd.Dir = dir + data, err := cmd.Output() + return data, err +} + +// copyGoModToTemp copies to given go.mod file to a temporary directory. +// go list tends to mutate go.mod files, but gazelle shouldn't do that. +func copyGoModToTemp(filename string) (tempDir string, err error) { + goModOrig, err := os.Open(filename) + if err != nil { + return "", err + } + defer goModOrig.Close() + + tempDir, err = ioutil.TempDir("", "gazelle-temp-gomod") + if err != nil { + return "", err + } + + goModCopy, err := os.Create(filepath.Join(tempDir, "go.mod")) + if err != nil { + os.Remove(tempDir) + return "", err + } + defer func() { + if cerr := goModCopy.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + _, err = io.Copy(goModCopy, goModOrig) + if err != nil { + os.RemoveAll(tempDir) + return "", err + } + return tempDir, err +} + +// findGoTool attempts to locate the go executable. If GOROOT is set, we'll +// prefer the one in there; otherwise, we'll rely on PATH. If the wrapper +// script generated by the gazelle rule is invoked by Bazel, it will set +// GOROOT to the configured SDK. We don't want to rely on the host SDK in +// that situation. +func findGoTool() string { + path := "go" // rely on PATH by default + if goroot, ok := os.LookupEnv("GOROOT"); ok { + path = filepath.Join(goroot, "bin", "go") + } + if runtime.GOOS == "windows" { + path += ".exe" + } + return path +} diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/repo.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/repo.go index ba5e91a1a6769..262595e19d795 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/repo.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos/repo.go @@ -61,10 +61,12 @@ type lockFileFormat int const ( unknownFormat lockFileFormat = iota depFormat + moduleFormat ) var lockFileParsers = map[lockFileFormat]func(string) ([]Repo, error){ - depFormat: importRepoRulesDep, + depFormat: importRepoRulesDep, + moduleFormat: importRepoRulesModules, } // ImportRepoRules reads the lock file of a vendoring tool and returns @@ -94,6 +96,8 @@ func getLockFileFormat(filename string) lockFileFormat { switch filepath.Base(filename) { case "Gopkg.lock": return depFormat + case "go.mod": + return moduleFormat default: return unknownFormat } @@ -103,7 +107,12 @@ func getLockFileFormat(filename string) lockFileFormat { // be written in a WORKSPACE file. func GenerateRule(repo Repo) *rule.Rule { r := rule.NewRule("go_repository", repo.Name) - r.SetAttr("commit", repo.Commit) + if repo.Commit != "" { + r.SetAttr("commit", repo.Commit) + } + if repo.Tag != "" { + r.SetAttr("tag", repo.Tag) + } r.SetAttr("importpath", repo.GoPrefix) if repo.Remote != "" { r.SetAttr("remote", repo.Remote) diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/BUILD b/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/BUILD index 30ddf5b40b3f8..7aae6f7a1e035 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/BUILD +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/BUILD @@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", - srcs = ["index.go"], + srcs = [ + "config.go", + "index.go", + ], importmap = "k8s.io/kubernetes/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve", importpath = "github.com/bazelbuild/bazel-gazelle/internal/resolve", visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"], diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/config.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/config.go new file mode 100644 index 0000000000000..339f4c9e529aa --- /dev/null +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/config.go @@ -0,0 +1,115 @@ +/* Copyright 2018 The Bazel Authors. All rights reserved. + +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 resolve + +import ( + "flag" + "log" + "strings" + + "github.com/bazelbuild/bazel-gazelle/internal/config" + "github.com/bazelbuild/bazel-gazelle/internal/label" + "github.com/bazelbuild/bazel-gazelle/internal/rule" +) + +// FindRuleWithOverride searches the current configuration for user-specified +// dependency resolution overrides. Overrides specified later (in configuration +// files in deeper directories, or closer to the end of the file) are +// returned first. If no override is found, label.NoLabel is returned. +func FindRuleWithOverride(c *config.Config, imp ImportSpec, lang string) (label.Label, bool) { + rc := getResolveConfig(c) + for i := len(rc.overrides) - 1; i >= 0; i-- { + o := rc.overrides[i] + if o.matches(imp, lang) { + return o.dep, true + } + } + return label.NoLabel, false +} + +type overrideSpec struct { + imp ImportSpec + lang string + dep label.Label +} + +func (o overrideSpec) matches(imp ImportSpec, lang string) bool { + return imp.Lang == o.imp.Lang && + imp.Imp == o.imp.Imp && + (o.lang == "" || o.lang == lang) +} + +type resolveConfig struct { + overrides []overrideSpec +} + +const resolveName = "_resolve" + +func getResolveConfig(c *config.Config) *resolveConfig { + return c.Exts[resolveName].(*resolveConfig) +} + +type Configurer struct{} + +func (_ *Configurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) { + c.Exts[resolveName] = &resolveConfig{} +} + +func (_ *Configurer) CheckFlags(fs *flag.FlagSet, c *config.Config) error { return nil } + +func (_ *Configurer) KnownDirectives() []string { + return []string{"resolve"} +} + +func (_ *Configurer) Configure(c *config.Config, rel string, f *rule.File) { + rc := getResolveConfig(c) + rcCopy := &resolveConfig{ + overrides: rc.overrides[:], + } + + if f != nil { + for _, d := range f.Directives { + if d.Key == "resolve" { + parts := strings.Fields(d.Value) + o := overrideSpec{} + var lbl string + if len(parts) == 3 { + o.imp.Lang = parts[0] + o.imp.Imp = parts[1] + lbl = parts[2] + } else if len(parts) == 4 { + o.imp.Lang = parts[0] + o.lang = parts[1] + o.imp.Imp = parts[2] + lbl = parts[3] + } else { + log.Printf("could not parse directive: %s\n\texpected gazelle:resolve source-language [import-language] import-string label", d.Value) + continue + } + var err error + o.dep, err = label.Parse(lbl) + if err != nil { + log.Printf("gazelle:resolve %s: %v", d.Value, err) + continue + } + o.dep = o.dep.Abs("", rel) + rcCopy.overrides = append(rcCopy.overrides, o) + } + } + } + + c.Exts[resolveName] = rcCopy +} diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/index.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/index.go index 211eba6b0c407..dba4eeac9c89f 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/index.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve/index.go @@ -195,8 +195,6 @@ type FindResult struct { // a matched rule. Label label.Label - Rule *rule.Rule - // Embeds is the transitive closure of labels for rules that the matched // rule embeds. It may contains duplicates and does not include the label // for the rule itself. @@ -222,7 +220,6 @@ func (ix *RuleIndex) FindRulesByImport(imp ImportSpec, lang string) []FindResult } results = append(results, FindResult{ Label: m.label, - Rule: m.rule, Embeds: m.embeds, }) } diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools/BUILD b/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools/BUILD new file mode 100644 index 0000000000000..5848a6a99b545 --- /dev/null +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools/BUILD @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "config.go", + "files.go", + ], + importmap = "k8s.io/kubernetes/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools", + importpath = "github.com/bazelbuild/bazel-gazelle/internal/testtools", + visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"], + deps = [ + "//vendor/github.com/bazelbuild/bazel-gazelle/internal/config:go_default_library", + "//vendor/github.com/bazelbuild/bazel-gazelle/internal/language: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/github.com/bazelbuild/bazel-gazelle/internal/testtools/config.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools/config.go new file mode 100644 index 0000000000000..15be3bdc52cb4 --- /dev/null +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools/config.go @@ -0,0 +1,53 @@ +/* Copyright 2018 The Bazel Authors. All rights reserved. + +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 testtools + +import ( + "flag" + "testing" + + "github.com/bazelbuild/bazel-gazelle/internal/config" + "github.com/bazelbuild/bazel-gazelle/internal/language" +) + +// NewTestConfig returns a Config used for tests in any language extension. +// cexts is a list of configuration extensions to use. langs is a list of +// language extensions to use (languages are also configuration extensions, +// but it may be convenient to keep them separate). args is a list of +// command line arguments to apply. NewTestConfig calls t.Fatal if any +// error is encountered while processing flags. +func NewTestConfig(t *testing.T, cexts []config.Configurer, langs []language.Language, args []string) *config.Config { + c := config.New() + fs := flag.NewFlagSet("test", flag.ContinueOnError) + + for _, lang := range langs { + cexts = append(cexts, lang) + } + for _, cext := range cexts { + cext.RegisterFlags(fs, "update", c) + } + + if err := fs.Parse(args); err != nil { + t.Fatal(err) + } + for _, cext := range cexts { + if err := cext.CheckFlags(fs, c); err != nil { + t.Fatal(err) + } + } + + return c +} diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools/files.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools/files.go new file mode 100644 index 0000000000000..ca6fcda428c03 --- /dev/null +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/testtools/files.go @@ -0,0 +1,109 @@ +/* Copyright 2018 The Bazel Authors. All rights reserved. + +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 testtools + +import ( + "io/ioutil" + "os" + "path/filepath" + "strings" + "testing" +) + +// FileSpec specifies the content of a test file. +type FileSpec struct { + // Path is a slash-separated path relative to the test directory. If Path + // ends with a slash, it indicates a directory should be created + // instead of a file. + Path string + + // Symlink is a slash-separated path relative to the test directory. If set, + // it indicates a symbolic link should be created with this path instead of a + // file. + Symlink string + + // Content is the content of the test file. + Content string +} + +// CreateFiles creates a directory of test files. This is a more compact +// alternative to testdata directories. CreateFiles returns a canonical path +// to the directory and a function to call to clean up the directory +// after the test. +func CreateFiles(t *testing.T, files []FileSpec) (dir string, cleanup func()) { + dir, err := ioutil.TempDir(os.Getenv("TEST_TEMPDIR"), "gazelle_test") + if err != nil { + t.Fatal(err) + } + dir, err = filepath.EvalSymlinks(dir) + if err != nil { + t.Fatal(err) + } + + for _, f := range files { + path := filepath.Join(dir, filepath.FromSlash(f.Path)) + if strings.HasSuffix(f.Path, "/") { + if err := os.MkdirAll(path, 0700); err != nil { + os.RemoveAll(dir) + t.Fatal(err) + } + continue + } + if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { + os.RemoveAll(dir) + t.Fatal(err) + } + if f.Symlink != "" { + if err := os.Symlink(f.Symlink, path); err != nil { + t.Fatal(err) + } + continue + } + if err := ioutil.WriteFile(path, []byte(f.Content), 0600); err != nil { + os.RemoveAll(dir) + t.Fatal(err) + } + } + + return dir, func() { os.RemoveAll(dir) } +} + +// CheckFiles checks that files in "dir" exist and have the content specified +// in "files". Files not listed in "files" are not tested, so extra files +// are allowed. +func CheckFiles(t *testing.T, dir string, files []FileSpec) { + for _, f := range files { + path := filepath.Join(dir, f.Path) + if strings.HasSuffix(f.Path, "/") { + if st, err := os.Stat(path); err != nil { + t.Errorf("could not stat %s: %v", f.Path, err) + } else if !st.IsDir() { + t.Errorf("not a directory: %s", f.Path) + } + } else { + want := strings.TrimSpace(f.Content) + gotBytes, err := ioutil.ReadFile(filepath.Join(dir, f.Path)) + if err != nil { + t.Errorf("could not read %s: %v", f.Path, err) + continue + } + got := strings.TrimSpace(string(gotBytes)) + if got != want { + t.Errorf("%s: got:\n%s\nwant:\n %s", f.Path, gotBytes, f.Content) + } + } + } +} diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/walk/config.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/walk/config.go index fd38828e19daa..f5da70bbb9f10 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/walk/config.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/walk/config.go @@ -18,7 +18,6 @@ package walk import ( "flag" "path" - "strings" "github.com/bazelbuild/bazel-gazelle/internal/config" "github.com/bazelbuild/bazel-gazelle/internal/rule" @@ -27,60 +26,55 @@ import ( type walkConfig struct { excludes []string ignore bool + follow []string } const walkName = "_walk" -func getWalkConfig(c *config.Config) walkConfig { - return c.Exts[walkName].(walkConfig) +func getWalkConfig(c *config.Config) *walkConfig { + return c.Exts[walkName].(*walkConfig) } -func (wc *walkConfig) isExcluded(base string) bool { +func (wc *walkConfig) isExcluded(rel, base string) bool { + f := path.Join(rel, base) for _, x := range wc.excludes { - if base == x { + if f == x { return true } } return false } -type walkConfigurer struct{} +type Configurer struct{} -func (_ *walkConfigurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {} +func (_ *Configurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) { + c.Exts[walkName] = &walkConfig{} +} -func (_ *walkConfigurer) CheckFlags(fs *flag.FlagSet, c *config.Config) error { return nil } +func (_ *Configurer) CheckFlags(fs *flag.FlagSet, c *config.Config) error { return nil } -func (_ *walkConfigurer) KnownDirectives() []string { - return []string{"exclude", "ignore"} +func (_ *Configurer) KnownDirectives() []string { + return []string{"exclude", "follow", "ignore"} } -func (_ *walkConfigurer) Configure(c *config.Config, rel string, f *rule.File) { - var wc walkConfig - if raw, ok := c.Exts[walkName]; ok { - wc = raw.(walkConfig) - wc.ignore = false - if rel != "" { - prefix := path.Base(rel) + "/" - excludes := make([]string, 0, len(wc.excludes)) - for _, x := range wc.excludes { - if strings.HasPrefix(x, prefix) { - excludes = append(excludes, x[len(prefix):]) - } - } - wc.excludes = excludes - } - } +func (_ *Configurer) Configure(c *config.Config, rel string, f *rule.File) { + wc := getWalkConfig(c) + wcCopy := &walkConfig{} + *wcCopy = *wc + wcCopy.ignore = false if f != nil { for _, d := range f.Directives { switch d.Key { case "exclude": - wc.excludes = append(wc.excludes, d.Value) + wcCopy.excludes = append(wcCopy.excludes, path.Join(rel, d.Value)) + case "follow": + wcCopy.follow = append(wcCopy.follow, path.Join(rel, d.Value)) case "ignore": - wc.ignore = true + wcCopy.ignore = true } } } - c.Exts[walkName] = wc + c.Exts[walkName] = wcCopy } diff --git a/vendor/github.com/bazelbuild/bazel-gazelle/internal/walk/walk.go b/vendor/github.com/bazelbuild/bazel-gazelle/internal/walk/walk.go index 896a7935d54b7..d93bc1e289f73 100644 --- a/vendor/github.com/bazelbuild/bazel-gazelle/internal/walk/walk.go +++ b/vendor/github.com/bazelbuild/bazel-gazelle/internal/walk/walk.go @@ -28,6 +28,26 @@ import ( "github.com/bazelbuild/bazel-gazelle/internal/rule" ) +// Mode determines which directories Walk visits and which directories +// should be updated. +type Mode int + +const ( + // In VisitAllUpdateSubdirsMode, Walk visits every directory in the + // repository. The directories given to Walk and their subdirectories are + // updated. + VisitAllUpdateSubdirsMode Mode = iota + + // In VisitAllUpdateDirsMode, Walk visits every directory in the repository. + // Only the directories given to Walk are updated (not their subdirectories). + VisitAllUpdateDirsMode + + // In UpdateDirsMode, Walk only visits and updates directories given to Walk. + // Build files in parent directories are read in order to produce a complete + // configuration, but the callback is not called for parent directories. + UpdateDirsMode +) + // WalkFunc is a callback called by Walk in each visited directory. // // dir is the absolute file system path to the directory being visited. @@ -57,11 +77,10 @@ type WalkFunc func(dir, rel string, c *config.Config, update bool, f *rule.File, // // Walk calls the Configure method on each configuration extension in cexts // in each directory in pre-order, whether a build file is present in the -// directory or not. +// directory or not. cexts must contain a walk.Configurer. // // Walk calls the callback wf in post-order. -func Walk(c *config.Config, cexts []config.Configurer, wf WalkFunc) { - cexts = append(cexts, &walkConfigurer{}) +func Walk(c *config.Config, cexts []config.Configurer, dirs []string, mode Mode, wf WalkFunc) { knownDirectives := make(map[string]bool) for _, cext := range cexts { for _, d := range cext.KnownDirectives() { @@ -69,17 +88,14 @@ func Walk(c *config.Config, cexts []config.Configurer, wf WalkFunc) { } } - updateRels := buildUpdateRels(c.RepoRoot, c.Dirs) - symlinks := symlinkResolver{root: c.RepoRoot, visited: []string{c.RepoRoot}} + symlinks := symlinkResolver{visited: []string{c.RepoRoot}} + + updateRels := buildUpdateRelMap(c.RepoRoot, dirs) var visit func(*config.Config, string, string, bool) - visit = func(c *config.Config, dir, rel string, isUpdateDir bool) { + visit = func(c *config.Config, dir, rel string, updateParent bool) { haveError := false - if !isUpdateDir { - isUpdateDir = shouldUpdateDir(rel, updateRels) - } - // TODO: OPT: ReadDir stats all the files, which is slow. We just care about // names and modes, so we should use something like // golang.org/x/tools/internal/fastwalk to speed this up. @@ -102,10 +118,10 @@ func Walk(c *config.Config, cexts []config.Configurer, wf WalkFunc) { for _, fi := range files { base := fi.Name() switch { - case base == "" || base[0] == '.' || base[0] == '_' || wc.isExcluded(base): + case base == "" || base[0] == '.' || base[0] == '_' || wc.isExcluded(rel, base): continue - case fi.IsDir() || fi.Mode()&os.ModeSymlink != 0 && symlinks.follow(dir, base): + case fi.IsDir() || fi.Mode()&os.ModeSymlink != 0 && symlinks.follow(c, dir, rel, base): subdirs = append(subdirs, base) default: @@ -113,45 +129,75 @@ func Walk(c *config.Config, cexts []config.Configurer, wf WalkFunc) { } } + shouldUpdate := shouldUpdate(rel, mode, updateParent, updateRels) for _, sub := range subdirs { - visit(c, filepath.Join(dir, sub), path.Join(rel, sub), isUpdateDir) + if subRel := path.Join(rel, sub); shouldVisit(subRel, mode, updateRels) { + visit(c, filepath.Join(dir, sub), subRel, shouldUpdate) + } } - genFiles := findGenFiles(wc, f) - update := !haveError && isUpdateDir && !wc.ignore - wf(dir, rel, c, update, f, subdirs, regularFiles, genFiles) + update := !haveError && !wc.ignore && shouldUpdate + if shouldCall(rel, mode, updateRels) { + genFiles := findGenFiles(wc, f) + wf(dir, rel, c, update, f, subdirs, regularFiles, genFiles) + } } visit(c, c.RepoRoot, "", false) } -// buildUpdateRels builds a list of relative paths from the repository root -// directory (passed as an absolute file path) to directories that Gazelle -// may update. The relative paths are slash-separated. "" represents the -// root directory itself. -func buildUpdateRels(root string, dirs []string) []string { - var updateRels []string +// buildUpdateRelMap builds a table of prefixes, used to determine which +// directories to update and visit. +// +// root and dirs must be absolute, canonical file paths. Each entry in dirs +// must be a subdirectory of root. The caller is responsible for checking this. +// +// buildUpdateRelMap returns a map from slash-separated paths relative to the +// root directory ("" for the root itself) to a boolean indicating whether +// the directory should be updated. +func buildUpdateRelMap(root string, dirs []string) map[string]bool { + relMap := make(map[string]bool) for _, dir := range dirs { - rel, err := filepath.Rel(root, dir) - if err != nil { - // This should have been verified when c was built. - log.Panicf("%s: not a subdirectory of repository root %q", dir, root) - } + rel, _ := filepath.Rel(root, dir) rel = filepath.ToSlash(rel) - if rel == "." || rel == "/" { + if rel == "." { rel = "" } - updateRels = append(updateRels, rel) + + i := 0 + for { + next := strings.IndexByte(rel[i:], '/') + i + if next-i < 0 { + relMap[rel] = true + break + } + prefix := rel[:next] + relMap[prefix] = relMap[prefix] // set to false if not present + i = next + 1 + } } - return updateRels + return relMap } -func shouldUpdateDir(rel string, updateRels []string) bool { - for _, r := range updateRels { - if pathtools.HasPrefix(rel, r) { - return true - } +// shouldCall returns true if Walk should call the callback in the +// directory rel. +func shouldCall(rel string, mode Mode, updateRels map[string]bool) bool { + return mode != UpdateDirsMode || updateRels[rel] +} + +// shouldUpdate returns true if Walk should pass true to the callback's update +// parameter in the directory rel. This indicates the build file should be +// updated. +func shouldUpdate(rel string, mode Mode, updateParent bool, updateRels map[string]bool) bool { + return mode == VisitAllUpdateSubdirsMode && updateParent || updateRels[rel] +} + +// shouldVisit returns true if Walk should visit the subdirectory rel. +func shouldVisit(rel string, mode Mode, updateRels map[string]bool) bool { + if mode != UpdateDirsMode { + return true } - return false + _, ok := updateRels[rel] + return ok } func loadBuildFile(c *config.Config, pkg, dir string, files []os.FileInfo) (*rule.File, error) { @@ -189,7 +235,7 @@ func configure(cexts []config.Configurer, knownDirectives map[string]bool, c *co return c } -func findGenFiles(wc walkConfig, f *rule.File) []string { +func findGenFiles(wc *walkConfig, f *rule.File) []string { if f == nil { return nil } @@ -206,7 +252,7 @@ func findGenFiles(wc walkConfig, f *rule.File) []string { var genFiles []string for _, s := range strs { - if !wc.isExcluded(s) { + if !wc.isExcluded(f.Pkg, s) { genFiles = append(genFiles, s) } } @@ -214,17 +260,26 @@ func findGenFiles(wc walkConfig, f *rule.File) []string { } type symlinkResolver struct { - root string visited []string } // Decide if symlink dir/base should be followed. -func (r *symlinkResolver) follow(dir, base string) bool { - if dir == r.root && strings.HasPrefix(base, "bazel-") { +func (r *symlinkResolver) follow(c *config.Config, dir, rel, base string) bool { + if dir == c.RepoRoot && strings.HasPrefix(base, "bazel-") { // Links such as bazel-, bazel-out, bazel-genfiles are created by // Bazel to point to internal build directories. return false } + + // See if the user has explicitly directed us to follow the link. + wc := getWalkConfig(c) + linkRel := path.Join(rel, base) + for _, follow := range wc.follow { + if linkRel == follow { + return true + } + } + // See if the symlink points to a tree that has been already visited. fullpath := filepath.Join(dir, base) dest, err := filepath.EvalSymlinks(fullpath) diff --git a/vendor/github.com/coreos/etcd/clientv3/concurrency/mutex.go b/vendor/github.com/coreos/etcd/clientv3/concurrency/mutex.go index dac9ba5a2a31b..77b3582cde52b 100644 --- a/vendor/github.com/coreos/etcd/clientv3/concurrency/mutex.go +++ b/vendor/github.com/coreos/etcd/clientv3/concurrency/mutex.go @@ -68,11 +68,10 @@ func (m *Mutex) Lock(ctx context.Context) error { // wait for deletion revisions prior to myKey hdr, werr := waitDeletes(ctx, client, m.pfx, m.myRev-1) - // release lock key if cancelled - select { - case <-ctx.Done(): + // release lock key if wait failed + if werr != nil { m.Unlock(client.Ctx()) - default: + } else { m.hdr = hdr } return werr diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/BUILD b/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/BUILD index e0c1fedbb4fc7..e4bff8d399d5b 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/BUILD +++ b/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/BUILD @@ -23,6 +23,7 @@ go_library( "//vendor/github.com/coreos/etcd/rafthttp:go_default_library", "//vendor/github.com/coreos/etcd/version:go_default_library", "//vendor/github.com/coreos/pkg/capnslog:go_default_library", + "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", "//vendor/github.com/prometheus/client_golang/prometheus/promhttp:go_default_library", ], ) diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/metrics.go index f374adcaa6bb5..aeaf350ef4158 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/metrics.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/metrics.go @@ -24,6 +24,7 @@ import ( "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/raft" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -43,11 +44,6 @@ func HandlePrometheus(mux *http.ServeMux) { mux.Handle(pathMetrics, promhttp.Handler()) } -// HandleHealth registers health handler on '/health'. -func HandleHealth(mux *http.ServeMux, srv etcdserver.ServerV2) { - mux.Handle(PathHealth, NewHealthHandler(func() Health { return checkHealth(srv) })) -} - // NewHealthHandler handles '/health' requests. func NewHealthHandler(hfunc func() Health) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -67,6 +63,26 @@ func NewHealthHandler(hfunc func() Health) http.HandlerFunc { } } +var ( + healthSuccess = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "server", + Name: "health_success", + Help: "The total number of successful health checks", + }) + healthFailed = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "server", + Name: "health_failures", + Help: "The total number of failed health checks", + }) +) + +func init() { + prometheus.MustRegister(healthSuccess) + prometheus.MustRegister(healthFailed) +} + // Health defines etcd server health status. // TODO: remove manual parsing in etcdctl cluster-health type Health struct { @@ -97,5 +113,11 @@ func checkHealth(srv etcdserver.ServerV2) Health { h.Health = "false" } } + + if h.Health == "true" { + healthSuccess.Inc() + } else { + healthFailed.Inc() + } return h } diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/BUILD b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/BUILD index 6ef688720bf4c..8f703423fc9ae 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/BUILD +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/BUILD @@ -37,15 +37,17 @@ go_library( "//vendor/github.com/coreos/etcd/version:go_default_library", "//vendor/github.com/coreos/pkg/capnslog:go_default_library", "//vendor/github.com/gogo/protobuf/proto:go_default_library", + "//vendor/github.com/grpc-ecosystem/go-grpc-middleware:go_default_library", "//vendor/github.com/grpc-ecosystem/go-grpc-prometheus:go_default_library", "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", + "//vendor/go.uber.org/zap:go_default_library", "//vendor/google.golang.org/grpc:go_default_library", "//vendor/google.golang.org/grpc/codes:go_default_library", "//vendor/google.golang.org/grpc/credentials:go_default_library", - "//vendor/google.golang.org/grpc/grpclog:go_default_library", "//vendor/google.golang.org/grpc/health:go_default_library", "//vendor/google.golang.org/grpc/health/grpc_health_v1:go_default_library", "//vendor/google.golang.org/grpc/metadata:go_default_library", + "//vendor/google.golang.org/grpc/peer:go_default_library", "//vendor/google.golang.org/grpc/status:go_default_library", ], ) diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go index 39776b444d174..c97e7466215a3 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go @@ -16,18 +16,15 @@ package v3rpc import ( "crypto/tls" - "io/ioutil" "math" - "os" - "sync" "github.com/coreos/etcd/etcdserver" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" "google.golang.org/grpc/credentials" - "google.golang.org/grpc/grpclog" "google.golang.org/grpc/health" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) @@ -38,17 +35,21 @@ const ( maxSendBytes = math.MaxInt32 ) -// integration tests call this multiple times, which is racey in gRPC side -var grpclogOnce sync.Once - func Server(s *etcdserver.EtcdServer, tls *tls.Config, gopts ...grpc.ServerOption) *grpc.Server { var opts []grpc.ServerOption opts = append(opts, grpc.CustomCodec(&codec{})) if tls != nil { opts = append(opts, grpc.Creds(credentials.NewTLS(tls))) } - opts = append(opts, grpc.UnaryInterceptor(newUnaryInterceptor(s))) - opts = append(opts, grpc.StreamInterceptor(newStreamInterceptor(s))) + opts = append(opts, grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( + newLogUnaryInterceptor(s), + newUnaryInterceptor(s), + grpc_prometheus.UnaryServerInterceptor, + ))) + opts = append(opts, grpc.StreamInterceptor(grpc_middleware.ChainStreamServer( + newStreamInterceptor(s), + grpc_prometheus.StreamServerInterceptor, + ))) opts = append(opts, grpc.MaxRecvMsgSize(int(s.Cfg.MaxRequestBytes+grpcOverheadBytes))) opts = append(opts, grpc.MaxSendMsgSize(maxSendBytes)) opts = append(opts, grpc.MaxConcurrentStreams(maxStreams)) @@ -71,16 +72,5 @@ func Server(s *etcdserver.EtcdServer, tls *tls.Config, gopts ...grpc.ServerOptio // set zero values for metrics registered for this grpc server grpc_prometheus.Register(grpcServer) - grpclogOnce.Do(func() { - if s.Cfg.Debug { - grpc.EnableTracing = true - // enable info, warning, error - grpclog.SetLoggerV2(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr)) - } else { - // only discard info - grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, os.Stderr, os.Stderr)) - } - }) - return grpcServer } diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go index f38dc4a99cf13..d594ae7f154c9 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go @@ -25,9 +25,11 @@ import ( "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/raft" - prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" ) const ( @@ -40,7 +42,7 @@ type streamsMap struct { } func newUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor { - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { if !api.IsCapabilityEnabled(api.V3rpcCapability) { return nil, rpctypes.ErrGRPCNotCapable } @@ -54,7 +56,124 @@ func newUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor { } } - return prometheus.UnaryServerInterceptor(ctx, req, info, handler) + return handler(ctx, req) + } +} + +func newLogUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + startTime := time.Now() + resp, err := handler(ctx, req) + defer logUnaryRequestStats(ctx, nil, info, startTime, req, resp) + return resp, err + } +} + +func logUnaryRequestStats(ctx context.Context, lg *zap.Logger, info *grpc.UnaryServerInfo, startTime time.Time, req interface{}, resp interface{}) { + duration := time.Since(startTime) + remote := "No remote client info." + peerInfo, ok := peer.FromContext(ctx) + if ok { + remote = peerInfo.Addr.String() + } + var responseType string = info.FullMethod + var reqCount, respCount int64 + var reqSize, respSize int + var reqContent string + switch _resp := resp.(type) { + case *pb.RangeResponse: + _req, ok := req.(*pb.RangeRequest) + if ok { + reqCount = 0 + reqSize = _req.Size() + reqContent = _req.String() + } + if _resp != nil { + respCount = _resp.GetCount() + respSize = _resp.Size() + } + case *pb.PutResponse: + _req, ok := req.(*pb.PutRequest) + if ok { + reqCount = 1 + reqSize = _req.Size() + reqContent = pb.NewLoggablePutRequest(_req).String() + // redact value field from request content, see PR #9821 + } + if _resp != nil { + respCount = 0 + respSize = _resp.Size() + } + case *pb.DeleteRangeResponse: + _req, ok := req.(*pb.DeleteRangeRequest) + if ok { + reqCount = 0 + reqSize = _req.Size() + reqContent = _req.String() + } + if _resp != nil { + respCount = _resp.GetDeleted() + respSize = _resp.Size() + } + case *pb.TxnResponse: + _req, ok := req.(*pb.TxnRequest) + if ok && _resp != nil { + if _resp.GetSucceeded() { // determine the 'actual' count and size of request based on success or failure + reqCount = int64(len(_req.GetSuccess())) + reqSize = 0 + for _, r := range _req.GetSuccess() { + reqSize += r.Size() + } + } else { + reqCount = int64(len(_req.GetFailure())) + reqSize = 0 + for _, r := range _req.GetFailure() { + reqSize += r.Size() + } + } + reqContent = pb.NewLoggableTxnRequest(_req).String() + // redact value field from request content, see PR #9821 + } + if _resp != nil { + respCount = 0 + respSize = _resp.Size() + } + default: + reqCount = -1 + reqSize = -1 + respCount = -1 + respSize = -1 + } + + logGenericRequestStats(lg, startTime, duration, remote, responseType, reqCount, reqSize, respCount, respSize, reqContent) +} + +func logGenericRequestStats(lg *zap.Logger, startTime time.Time, duration time.Duration, remote string, responseType string, + reqCount int64, reqSize int, respCount int64, respSize int, reqContent string) { + if lg == nil { + plog.Debugf("start time = %v, "+ + "time spent = %v, "+ + "remote = %s, "+ + "response type = %s, "+ + "request count = %d, "+ + "request size = %d, "+ + "response count = %d, "+ + "response size = %d, "+ + "request content = %s", + startTime, duration, remote, responseType, reqCount, reqSize, respCount, respSize, reqContent, + ) + } else { + lg.Debug("request stats", + zap.Time("start time", startTime), + zap.Duration("time spent", duration), + zap.String("remote", remote), + zap.String("response type", responseType), + zap.Int64("request count", reqCount), + zap.Int("request size", reqSize), + zap.Int64("response count", respCount), + zap.Int("response size", respSize), + zap.String("request content", reqContent), + ) } } @@ -90,7 +209,7 @@ func newStreamInterceptor(s *etcdserver.EtcdServer) grpc.StreamServerInterceptor } } - return prometheus.StreamServerInterceptor(srv, ss, info, handler) + return handler(srv, ss) } } diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go index ec6b6397b3998..3d3536a326dd0 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go @@ -59,7 +59,7 @@ func (as *InternalRaftStringer) String() string { case as.Request.Put != nil: return fmt.Sprintf("header:<%s> put:<%s>", as.Request.Header.String(), - newLoggablePutRequest(as.Request.Put).String(), + NewLoggablePutRequest(as.Request.Put).String(), ) case as.Request.Txn != nil: return fmt.Sprintf("header:<%s> txn:<%s>", @@ -121,7 +121,7 @@ func newLoggableRequestOp(op *RequestOp) *requestOpStringer { func (as *requestOpStringer) String() string { switch op := as.Op.Request.(type) { case *RequestOp_RequestPut: - return fmt.Sprintf("request_put:<%s>", newLoggablePutRequest(op.RequestPut).String()) + return fmt.Sprintf("request_put:<%s>", NewLoggablePutRequest(op.RequestPut).String()) case *RequestOp_RequestTxn: return fmt.Sprintf("request_txn:<%s>", NewLoggableTxnRequest(op.RequestTxn).String()) default: @@ -167,7 +167,7 @@ type loggablePutRequest struct { IgnoreLease bool `protobuf:"varint,6,opt,name=ignore_lease,proto3"` } -func newLoggablePutRequest(request *PutRequest) *loggablePutRequest { +func NewLoggablePutRequest(request *PutRequest) *loggablePutRequest { return &loggablePutRequest{ request.Key, len(request.Value), diff --git a/vendor/github.com/coreos/etcd/etcdserver/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/metrics.go index f6f2d7b62a853..10f8a475fca78 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/metrics.go +++ b/vendor/github.com/coreos/etcd/etcdserver/metrics.go @@ -90,6 +90,12 @@ var ( Name: "slow_read_indexes_total", Help: "The total number of pending read indexes not in sync with leader's or timed out read index requests.", }) + readIndexFailed = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "server", + Name: "read_indexes_failed_total", + Help: "The total number of failed read indexes seen.", + }) quotaBackendBytes = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "etcd", Subsystem: "server", @@ -110,6 +116,13 @@ var ( Help: "Which Go version server is running with. 1 for 'server_go_version' label with current version.", }, []string{"server_go_version"}) + serverID = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: "etcd", + Subsystem: "server", + Name: "id", + Help: "Server or member ID in hexadecimal format. 1 for 'server_id' label with current ID.", + }, + []string{"server_id"}) ) func init() { @@ -124,9 +137,11 @@ func init() { prometheus.MustRegister(proposalsFailed) prometheus.MustRegister(leaseExpired) prometheus.MustRegister(slowReadIndex) + prometheus.MustRegister(readIndexFailed) prometheus.MustRegister(quotaBackendBytes) prometheus.MustRegister(currentVersion) prometheus.MustRegister(currentGoVersion) + prometheus.MustRegister(serverID) currentVersion.With(prometheus.Labels{ "server_version": version.Version, diff --git a/vendor/github.com/coreos/etcd/etcdserver/server.go b/vendor/github.com/coreos/etcd/etcdserver/server.go index f891c862351e0..71e2bcf4bc73c 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/server.go @@ -59,6 +59,7 @@ import ( "github.com/coreos/go-semver/semver" "github.com/coreos/pkg/capnslog" + "github.com/prometheus/client_golang/prometheus" ) const ( @@ -435,6 +436,7 @@ func NewServer(cfg ServerConfig) (srv *EtcdServer, err error) { reqIDGen: idutil.NewGenerator(uint16(id), time.Now()), forceVersionC: make(chan struct{}), } + serverID.With(prometheus.Labels{"server_id": id.String()}).Set(1) srv.applyV2 = &applierV2store{store: srv.store, cluster: srv.cluster} diff --git a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go index 8d5961bb0c021..f214a1926bb9a 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go @@ -634,6 +634,7 @@ func (s *EtcdServer) linearizableReadLoop() { return } plog.Errorf("failed to get read index from raft: %v", err) + readIndexFailed.Inc() nr.notify(err) continue } @@ -659,7 +660,7 @@ func (s *EtcdServer) linearizableReadLoop() { } case <-time.After(s.Cfg.ReqTimeout()): - plog.Warningf("timed out waiting for read index response") + plog.Warningf("timed out waiting for read index response (local node might have slow network)") nr.notify(ErrTimeout) timeout = true slowReadIndex.Inc() diff --git a/vendor/github.com/coreos/etcd/rafthttp/http.go b/vendor/github.com/coreos/etcd/rafthttp/http.go index cc89e171ee27a..223a5deb9bdbe 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/http.go +++ b/vendor/github.com/coreos/etcd/rafthttp/http.go @@ -22,6 +22,7 @@ import ( "net/http" "path" "strings" + "time" pioutil "github.com/coreos/etcd/pkg/ioutil" "github.com/coreos/etcd/pkg/types" @@ -149,6 +150,8 @@ func newSnapshotHandler(tr Transporter, r Raft, snapshotter *snap.Snapshotter, c } } +const unknownSnapshotSender = "UNKNOWN_SNAPSHOT_SENDER" + // ServeHTTP serves HTTP request to receive and process snapshot message. // // If request sender dies without closing underlying TCP connection, @@ -159,9 +162,12 @@ func newSnapshotHandler(tr Transporter, r Raft, snapshotter *snap.Snapshotter, c // received and processed. // 2. this case should happen rarely, so no further optimization is done. func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + start := time.Now() + if r.Method != "POST" { w.Header().Set("Allow", "POST") http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) + snapshotReceiveFailures.WithLabelValues(unknownSnapshotSender).Inc() return } @@ -169,6 +175,7 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if err := checkClusterCompatibilityFromHeader(r.Header, h.cid); err != nil { http.Error(w, err.Error(), http.StatusPreconditionFailed) + snapshotReceiveFailures.WithLabelValues(unknownSnapshotSender).Inc() return } @@ -177,19 +184,22 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { dec := &messageDecoder{r: r.Body} // let snapshots be very large since they can exceed 512MB for large installations m, err := dec.decodeLimit(uint64(1 << 63)) + from := types.ID(m.From).String() if err != nil { msg := fmt.Sprintf("failed to decode raft message (%v)", err) plog.Errorf(msg) http.Error(w, msg, http.StatusBadRequest) recvFailures.WithLabelValues(r.RemoteAddr).Inc() + snapshotReceiveFailures.WithLabelValues(from).Inc() return } - receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(m.Size())) + receivedBytes.WithLabelValues(from).Add(float64(m.Size())) if m.Type != raftpb.MsgSnap { plog.Errorf("unexpected raft message type %s on snapshot path", m.Type) http.Error(w, "wrong raft message type", http.StatusBadRequest) + snapshotReceiveFailures.WithLabelValues(from).Inc() return } @@ -200,9 +210,10 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { msg := fmt.Sprintf("failed to save KV snapshot (%v)", err) plog.Error(msg) http.Error(w, msg, http.StatusInternalServerError) + snapshotReceiveFailures.WithLabelValues(from).Inc() return } - receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(n)) + receivedBytes.WithLabelValues(from).Add(float64(n)) plog.Infof("received and saved database snapshot [index: %d, from: %s] successfully", m.Snapshot.Metadata.Index, types.ID(m.From)) if err := h.r.Process(context.TODO(), m); err != nil { @@ -215,12 +226,16 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { msg := fmt.Sprintf("failed to process raft message (%v)", err) plog.Warningf(msg) http.Error(w, msg, http.StatusInternalServerError) + snapshotReceiveFailures.WithLabelValues(from).Inc() } return } // Write StatusNoContent header after the message has been processed by // raft, which facilitates the client to report MsgSnap status. w.WriteHeader(http.StatusNoContent) + + snapshotReceive.WithLabelValues(from).Inc() + snapshotReceiveSeconds.WithLabelValues(from).Observe(time.Since(start).Seconds()) } type streamHandler struct { diff --git a/vendor/github.com/coreos/etcd/rafthttp/metrics.go b/vendor/github.com/coreos/etcd/rafthttp/metrics.go index 320bfe72661d3..2066663c691d2 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/metrics.go +++ b/vendor/github.com/coreos/etcd/rafthttp/metrics.go @@ -53,6 +53,68 @@ var ( []string{"From"}, ) + snapshotSend = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "snapshot_send_success", + Help: "Total number of successful snapshot sends", + }, + []string{"To"}, + ) + + snapshotSendFailures = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "snapshot_send_failures", + Help: "Total number of snapshot send failures", + }, + []string{"To"}, + ) + + snapshotSendSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "snapshot_send_total_duration_seconds", + Help: "Total latency distributions of v3 snapshot sends", + + // lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2 + // highest bucket start of 0.1 sec * 2^9 == 51.2 sec + Buckets: prometheus.ExponentialBuckets(0.1, 2, 10), + }, + []string{"To"}, + ) + + snapshotReceive = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "snapshot_receive_success", + Help: "Total number of successful snapshot receives", + }, + []string{"From"}, + ) + + snapshotReceiveFailures = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "snapshot_receive_failures", + Help: "Total number of snapshot receive failures", + }, + []string{"From"}, + ) + + snapshotReceiveSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "snapshot_receive_total_duration_seconds", + Help: "Total latency distributions of v3 snapshot receives", + + // lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2 + // highest bucket start of 0.1 sec * 2^9 == 51.2 sec + Buckets: prometheus.ExponentialBuckets(0.1, 2, 10), + }, + []string{"From"}, + ) + rtts = prometheus.NewHistogramVec(prometheus.HistogramOpts{ Namespace: "etcd", Subsystem: "network", @@ -69,5 +131,13 @@ func init() { prometheus.MustRegister(receivedBytes) prometheus.MustRegister(sentFailures) prometheus.MustRegister(recvFailures) + + prometheus.MustRegister(snapshotSend) + prometheus.MustRegister(snapshotSendFailures) + prometheus.MustRegister(snapshotSendSeconds) + prometheus.MustRegister(snapshotReceive) + prometheus.MustRegister(snapshotReceiveFailures) + prometheus.MustRegister(snapshotReceiveSeconds) + prometheus.MustRegister(rtts) } diff --git a/vendor/github.com/coreos/etcd/rafthttp/peer_status.go b/vendor/github.com/coreos/etcd/rafthttp/peer_status.go index 706144f6466d7..69cbd384ca0ca 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/peer_status.go +++ b/vendor/github.com/coreos/etcd/rafthttp/peer_status.go @@ -56,7 +56,7 @@ func (s *peerStatus) deactivate(failure failureType, reason string) { msg := fmt.Sprintf("failed to %s %s on %s (%s)", failure.action, s.id, failure.source, reason) if s.active { plog.Errorf(msg) - plog.Infof("peer %s became inactive", s.id) + plog.Infof("peer %s became inactive (message send to peer failed)", s.id) s.active = false s.since = time.Time{} return diff --git a/vendor/github.com/coreos/etcd/rafthttp/probing_status.go b/vendor/github.com/coreos/etcd/rafthttp/probing_status.go index c7a3c7ab93181..109a0aea0f1a8 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/probing_status.go +++ b/vendor/github.com/coreos/etcd/rafthttp/probing_status.go @@ -17,6 +17,7 @@ package rafthttp import ( "time" + "github.com/prometheus/client_golang/prometheus" "github.com/xiang90/probing" ) @@ -28,7 +29,15 @@ var ( statusErrorInterval = 5 * time.Second ) -func addPeerToProber(p probing.Prober, id string, us []string) { +const ( + // RoundTripperNameRaftMessage is the name of round-tripper that sends + // all other Raft messages, other than "snap.Message". + RoundTripperNameRaftMessage = "ROUND_TRIPPER_RAFT_MESSAGE" + // RoundTripperNameSnapshot is the name of round-tripper that sends merged snapshot message. + RoundTripperNameSnapshot = "ROUND_TRIPPER_SNAPSHOT" +) + +func addPeerToProber(p probing.Prober, id string, us []string, roundTripperName string, rttSecProm *prometheus.HistogramVec) { hus := make([]string, len(us)) for i := range us { hus[i] = us[i] + ProbingPrefix @@ -40,26 +49,26 @@ func addPeerToProber(p probing.Prober, id string, us []string) { if err != nil { plog.Errorf("failed to add peer %s into prober", id) } else { - go monitorProbingStatus(s, id) + go monitorProbingStatus(s, id, roundTripperName, rttSecProm) } } -func monitorProbingStatus(s probing.Status, id string) { +func monitorProbingStatus(s probing.Status, id string, roundTripperName string, rttSecProm *prometheus.HistogramVec) { // set the first interval short to log error early. interval := statusErrorInterval for { select { case <-time.After(interval): if !s.Health() { - plog.Warningf("health check for peer %s could not connect: %v", id, s.Err()) + plog.Warningf("health check for peer %s could not connect: %v (prober %q)", id, s.Err(), roundTripperName) interval = statusErrorInterval } else { interval = statusMonitoringInterval } if s.ClockDiff() > time.Second { - plog.Warningf("the clock difference against peer %s is too high [%v > %v]", id, s.ClockDiff(), time.Second) + plog.Warningf("the clock difference against peer %s is too high [%v > %v] (prober %q)", id, s.ClockDiff(), time.Second, roundTripperName) } - rtts.WithLabelValues(id).Observe(s.SRTT().Seconds()) + rttSecProm.WithLabelValues(id).Observe(s.SRTT().Seconds()) case <-s.StopNotify(): return } diff --git a/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go b/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go index 52273c9d195e6..24eb53553f55e 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go +++ b/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go @@ -64,7 +64,10 @@ func newSnapshotSender(tr *Transport, picker *urlPicker, to types.ID, status *pe func (s *snapshotSender) stop() { close(s.stopc) } func (s *snapshotSender) send(merged snap.Message) { + start := time.Now() + m := merged.Message + to := types.ID(m.To).String() body := createSnapBody(merged) defer body.Close() @@ -92,14 +95,18 @@ func (s *snapshotSender) send(merged snap.Message) { // machine knows about it, it would pause a while and retry sending // new snapshot message. s.r.ReportSnapshot(m.To, raft.SnapshotFailure) - sentFailures.WithLabelValues(types.ID(m.To).String()).Inc() + sentFailures.WithLabelValues(to).Inc() + snapshotSendFailures.WithLabelValues(to).Inc() return } s.status.activate() s.r.ReportSnapshot(m.To, raft.SnapshotFinish) plog.Infof("database snapshot [index: %d, to: %s] sent out successfully", m.Snapshot.Metadata.Index, types.ID(m.To)) - sentBytes.WithLabelValues(types.ID(m.To).String()).Add(float64(merged.TotalSize)) + sentBytes.WithLabelValues(to).Add(float64(merged.TotalSize)) + + snapshotSend.WithLabelValues(to).Inc() + snapshotSendSeconds.WithLabelValues(to).Observe(time.Since(start).Seconds()) } // post posts the given request. diff --git a/vendor/github.com/coreos/etcd/rafthttp/transport.go b/vendor/github.com/coreos/etcd/rafthttp/transport.go index ce73433027b7f..16e854c8a3491 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/transport.go +++ b/vendor/github.com/coreos/etcd/rafthttp/transport.go @@ -127,7 +127,8 @@ type Transport struct { remotes map[types.ID]*remote // remotes map that helps newly joined member to catch up peers map[types.ID]Peer // peers map - prober probing.Prober + pipelineProber probing.Prober + streamProber probing.Prober } func (t *Transport) Start() error { @@ -142,7 +143,8 @@ func (t *Transport) Start() error { } t.remotes = make(map[types.ID]*remote) t.peers = make(map[types.ID]Peer) - t.prober = probing.NewProber(t.pipelineRt) + t.pipelineProber = probing.NewProber(t.pipelineRt) + t.streamProber = probing.NewProber(t.streamRt) // If client didn't provide dial retry frequency, use the default // (100ms backoff between attempts to create a new stream), @@ -210,7 +212,8 @@ func (t *Transport) Stop() { for _, p := range t.peers { p.stop() } - t.prober.RemoveAll() + t.pipelineProber.RemoveAll() + t.streamProber.RemoveAll() if tr, ok := t.streamRt.(*http.Transport); ok { tr.CloseIdleConnections() } @@ -289,8 +292,8 @@ func (t *Transport) AddPeer(id types.ID, us []string) { } fs := t.LeaderStats.Follower(id.String()) t.peers[id] = startPeer(t, urls, id, fs) - addPeerToProber(t.prober, id.String(), us) - + addPeerToProber(t.pipelineProber, id.String(), us, RoundTripperNameSnapshot, rtts) + addPeerToProber(t.streamProber, id.String(), us, RoundTripperNameRaftMessage, rtts) plog.Infof("added peer %s", id) } @@ -317,7 +320,8 @@ func (t *Transport) removePeer(id types.ID) { } delete(t.peers, id) delete(t.LeaderStats.Followers, id.String()) - t.prober.Remove(id.String()) + t.pipelineProber.Remove(id.String()) + t.streamProber.Remove(id.String()) plog.Infof("removed peer %s", id) } @@ -334,8 +338,10 @@ func (t *Transport) UpdatePeer(id types.ID, us []string) { } t.peers[id].update(urls) - t.prober.Remove(id.String()) - addPeerToProber(t.prober, id.String(), us) + t.pipelineProber.Remove(id.String()) + addPeerToProber(t.pipelineProber, id.String(), us, RoundTripperNameSnapshot, rtts) + t.streamProber.Remove(id.String()) + addPeerToProber(t.streamProber, id.String(), us, RoundTripperNameRaftMessage, rtts) plog.Infof("updated peer %s", id) } diff --git a/vendor/github.com/coreos/etcd/snap/db.go b/vendor/github.com/coreos/etcd/snap/db.go index 01d897ae86116..dcbd3bd6710ca 100644 --- a/vendor/github.com/coreos/etcd/snap/db.go +++ b/vendor/github.com/coreos/etcd/snap/db.go @@ -21,6 +21,7 @@ import ( "io/ioutil" "os" "path/filepath" + "time" "github.com/coreos/etcd/pkg/fileutil" ) @@ -30,6 +31,8 @@ var ErrNoDBSnapshot = errors.New("snap: snapshot file doesn't exist") // SaveDBFrom saves snapshot of the database from the given reader. It // guarantees the save operation is atomic. func (s *Snapshotter) SaveDBFrom(r io.Reader, id uint64) (int64, error) { + start := time.Now() + f, err := ioutil.TempFile(s.dir, "tmp") if err != nil { return 0, err @@ -37,7 +40,9 @@ func (s *Snapshotter) SaveDBFrom(r io.Reader, id uint64) (int64, error) { var n int64 n, err = io.Copy(f, r) if err == nil { + fsyncStart := time.Now() err = fileutil.Fsync(f) + snapDBFsyncSec.Observe(time.Since(fsyncStart).Seconds()) } f.Close() if err != nil { @@ -57,6 +62,7 @@ func (s *Snapshotter) SaveDBFrom(r io.Reader, id uint64) (int64, error) { plog.Infof("saved database snapshot to disk [total bytes: %d]", n) + snapDBSaveSec.Observe(time.Since(start).Seconds()) return n, nil } diff --git a/vendor/github.com/coreos/etcd/snap/metrics.go b/vendor/github.com/coreos/etcd/snap/metrics.go index 433ef09d4ba81..0d3b7e63e5e85 100644 --- a/vendor/github.com/coreos/etcd/snap/metrics.go +++ b/vendor/github.com/coreos/etcd/snap/metrics.go @@ -33,9 +33,33 @@ var ( Help: "The marshalling cost distributions of save called by snapshot.", Buckets: prometheus.ExponentialBuckets(0.001, 2, 14), }) + + snapDBSaveSec = prometheus.NewHistogram(prometheus.HistogramOpts{ + Namespace: "etcd", + Subsystem: "snap_db", + Name: "save_total_duration_seconds", + Help: "The total latency distributions of v3 snapshot save", + + // lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2 + // highest bucket start of 0.1 sec * 2^9 == 51.2 sec + Buckets: prometheus.ExponentialBuckets(0.1, 2, 10), + }) + + snapDBFsyncSec = prometheus.NewHistogram(prometheus.HistogramOpts{ + Namespace: "etcd", + Subsystem: "snap_db", + Name: "fsync_duration_seconds", + Help: "The latency distributions of fsyncing .snap.db file", + + // lowest bucket start of upper bound 0.001 sec (1 ms) with factor 2 + // highest bucket start of 0.001 sec * 2^13 == 8.192 sec + Buckets: prometheus.ExponentialBuckets(0.001, 2, 14), + }) ) func init() { prometheus.MustRegister(saveDurations) prometheus.MustRegister(marshallingDurations) + prometheus.MustRegister(snapDBSaveSec) + prometheus.MustRegister(snapDBFsyncSec) } diff --git a/vendor/github.com/coreos/etcd/version/version.go b/vendor/github.com/coreos/etcd/version/version.go index 156e0f11af95f..c68847dc34a09 100644 --- a/vendor/github.com/coreos/etcd/version/version.go +++ b/vendor/github.com/coreos/etcd/version/version.go @@ -26,7 +26,7 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. MinClusterVersion = "3.0.0" - Version = "3.3.9" + Version = "3.3.10" APIVersion = "unknown" // Git SHA Value will be set during build diff --git a/vendor/github.com/coreos/go-semver/NOTICE b/vendor/github.com/coreos/go-semver/NOTICE new file mode 100644 index 0000000000000..23a0ada2fbb56 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go index f1f8ab7973901..76cf4852c769e 100644 --- a/vendor/github.com/coreos/go-semver/semver/semver.go +++ b/vendor/github.com/coreos/go-semver/semver/semver.go @@ -1,9 +1,25 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// 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. + +// Semantic Versions http://semver.org package semver import ( "bytes" "errors" "fmt" + "regexp" "strconv" "strings" ) @@ -29,17 +45,45 @@ func splitOff(input *string, delim string) (val string) { return val } +func New(version string) *Version { + return Must(NewVersion(version)) +} + func NewVersion(version string) (*Version, error) { v := Version{} + if err := v.Set(version); err != nil { + return nil, err + } + + return &v, nil +} + +// Must is a helper for wrapping NewVersion and will panic if err is not nil. +func Must(v *Version, err error) *Version { + if err != nil { + panic(err) + } + return v +} + +// Set parses and updates v from the given version string. Implements flag.Value +func (v *Version) Set(version string) error { + metadata := splitOff(&version, "+") + preRelease := PreRelease(splitOff(&version, "-")) dotParts := strings.SplitN(version, ".", 3) if len(dotParts) != 3 { - return nil, errors.New(fmt.Sprintf("%s is not in dotted-tri format", version)) + return fmt.Errorf("%s is not in dotted-tri format", version) + } + + if err := validateIdentifier(string(preRelease)); err != nil { + return fmt.Errorf("failed to validate pre-release: %v", err) } - v.Metadata = splitOff(&dotParts[2], "+") - v.PreRelease = PreRelease(splitOff(&dotParts[2], "-")) + if err := validateIdentifier(metadata); err != nil { + return fmt.Errorf("failed to validate metadata: %v", err) + } parsed := make([]int64, 3, 3) @@ -47,63 +91,83 @@ func NewVersion(version string) (*Version, error) { val, err := strconv.ParseInt(v, 10, 64) parsed[i] = val if err != nil { - return nil, err + return err } } + v.Metadata = metadata + v.PreRelease = preRelease v.Major = parsed[0] v.Minor = parsed[1] v.Patch = parsed[2] - - return &v, nil + return nil } -func Must(v *Version, err error) *Version { - if err != nil { - panic(err) - } - return v -} - -func (v *Version) String() string { +func (v Version) String() string { var buffer bytes.Buffer - base := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch) - buffer.WriteString(base) + fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch) if v.PreRelease != "" { - buffer.WriteString(fmt.Sprintf("-%s", v.PreRelease)) + fmt.Fprintf(&buffer, "-%s", v.PreRelease) } if v.Metadata != "" { - buffer.WriteString(fmt.Sprintf("+%s", v.Metadata)) + fmt.Fprintf(&buffer, "+%s", v.Metadata) } return buffer.String() } -func (v *Version) LessThan(versionB Version) bool { - versionA := *v - cmp := recursiveCompare(versionA.Slice(), versionB.Slice()) +func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error { + var data string + if err := unmarshal(&data); err != nil { + return err + } + return v.Set(data) +} - if cmp == 0 { - cmp = preReleaseCompare(versionA, versionB) +func (v Version) MarshalJSON() ([]byte, error) { + return []byte(`"` + v.String() + `"`), nil +} + +func (v *Version) UnmarshalJSON(data []byte) error { + l := len(data) + if l == 0 || string(data) == `""` { + return nil + } + if l < 2 || data[0] != '"' || data[l-1] != '"' { + return errors.New("invalid semver string") } + return v.Set(string(data[1 : l-1])) +} - if cmp == -1 { - return true +// Compare tests if v is less than, equal to, or greater than versionB, +// returning -1, 0, or +1 respectively. +func (v Version) Compare(versionB Version) int { + if cmp := recursiveCompare(v.Slice(), versionB.Slice()); cmp != 0 { + return cmp } + return preReleaseCompare(v, versionB) +} + +// Equal tests if v is equal to versionB. +func (v Version) Equal(versionB Version) bool { + return v.Compare(versionB) == 0 +} - return false +// LessThan tests if v is less than versionB. +func (v Version) LessThan(versionB Version) bool { + return v.Compare(versionB) < 0 } -/* Slice converts the comparable parts of the semver into a slice of strings */ -func (v *Version) Slice() []int64 { +// Slice converts the comparable parts of the semver into a slice of integers. +func (v Version) Slice() []int64 { return []int64{v.Major, v.Minor, v.Patch} } -func (p *PreRelease) Slice() []string { - preRelease := string(*p) +func (p PreRelease) Slice() []string { + preRelease := string(p) return strings.Split(preRelease, ".") } @@ -119,7 +183,7 @@ func preReleaseCompare(versionA Version, versionB Version) int { return -1 } - // If there is a prelease, check and compare each part. + // If there is a prerelease, check and compare each part. return recursivePreReleaseCompare(a.Slice(), b.Slice()) } @@ -141,9 +205,12 @@ func recursiveCompare(versionA []int64, versionB []int64) int { } func recursivePreReleaseCompare(versionA []string, versionB []string) int { - // Handle slice length disparity. + // A larger set of pre-release fields has a higher precedence than a smaller set, + // if all of the preceding identifiers are equal. if len(versionA) == 0 { - // Nothing to compare too, so we return 0 + if len(versionB) > 0 { + return -1 + } return 0 } else if len(versionB) == 0 { // We're longer than versionB so return 1. @@ -153,7 +220,8 @@ func recursivePreReleaseCompare(versionA []string, versionB []string) int { a := versionA[0] b := versionB[0] - aInt := false; bInt := false + aInt := false + bInt := false aI, err := strconv.Atoi(versionA[0]) if err == nil { @@ -165,6 +233,13 @@ func recursivePreReleaseCompare(versionA []string, versionB []string) int { bInt = true } + // Numeric identifiers always have lower precedence than non-numeric identifiers. + if aInt && !bInt { + return -1 + } else if !aInt && bInt { + return 1 + } + // Handle Integer Comparison if aInt && bInt { if aI > bI { @@ -207,3 +282,15 @@ func (v *Version) BumpPatch() { v.PreRelease = PreRelease("") v.Metadata = "" } + +// validateIdentifier makes sure the provided identifier satisfies semver spec +func validateIdentifier(id string) error { + if id != "" && !reIdentifier.MatchString(id) { + return fmt.Errorf("%s is not a valid semver identifier", id) + } + return nil +} + +// reIdentifier is a regular expression used to check that pre-release and metadata +// identifiers satisfy the spec requirements +var reIdentifier = regexp.MustCompile(`^[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*$`) diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go index 86203007ae9f8..e256b41a5ddf5 100644 --- a/vendor/github.com/coreos/go-semver/semver/sort.go +++ b/vendor/github.com/coreos/go-semver/semver/sort.go @@ -1,3 +1,17 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// 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 semver import ( diff --git a/vendor/github.com/coreos/go-systemd/NOTICE b/vendor/github.com/coreos/go-systemd/NOTICE new file mode 100644 index 0000000000000..23a0ada2fbb56 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-systemd/daemon/sdnotify.go b/vendor/github.com/coreos/go-systemd/daemon/sdnotify.go index ba6d41d85baae..ba4ae31f19bae 100644 --- a/vendor/github.com/coreos/go-systemd/daemon/sdnotify.go +++ b/vendor/github.com/coreos/go-systemd/daemon/sdnotify.go @@ -1,4 +1,5 @@ // Copyright 2014 Docker, Inc. +// Copyright 2015-2018 CoreOS, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,7 +14,11 @@ // limitations under the License. // -// Code forked from Docker project +// Package daemon provides a Go implementation of the sd_notify protocol. +// It can be used to inform systemd of service start-up completion, watchdog +// events, and other status changes. +// +// https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description package daemon import ( @@ -21,6 +26,25 @@ import ( "os" ) +const ( + // SdNotifyReady tells the service manager that service startup is finished + // or the service finished loading its configuration. + SdNotifyReady = "READY=1" + + // SdNotifyStopping tells the service manager that the service is beginning + // its shutdown. + SdNotifyStopping = "STOPPING=1" + + // SdNotifyReloading tells the service manager that this service is + // reloading its configuration. Note that you must call SdNotifyReady when + // it completed reloading. + SdNotifyReloading = "RELOADING=1" + + // SdNotifyWatchdog tells the service manager to update the watchdog + // timestamp for the service. + SdNotifyWatchdog = "WATCHDOG=1" +) + // SdNotify sends a message to the init daemon. It is common to ignore the error. // If `unsetEnvironment` is true, the environment variable `NOTIFY_SOCKET` // will be unconditionally unset. @@ -29,7 +53,7 @@ import ( // (false, nil) - notification not supported (i.e. NOTIFY_SOCKET is unset) // (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data) // (true, nil) - notification supported, data has been sent -func SdNotify(unsetEnvironment bool, state string) (sent bool, err error) { +func SdNotify(unsetEnvironment bool, state string) (bool, error) { socketAddr := &net.UnixAddr{ Name: os.Getenv("NOTIFY_SOCKET"), Net: "unixgram", @@ -41,10 +65,9 @@ func SdNotify(unsetEnvironment bool, state string) (sent bool, err error) { } if unsetEnvironment { - err = os.Unsetenv("NOTIFY_SOCKET") - } - if err != nil { - return false, err + if err := os.Unsetenv("NOTIFY_SOCKET"); err != nil { + return false, err + } } conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr) @@ -54,9 +77,7 @@ func SdNotify(unsetEnvironment bool, state string) (sent bool, err error) { } defer conn.Close() - _, err = conn.Write([]byte(state)) - // Error sending the message - if err != nil { + if _, err = conn.Write([]byte(state)); err != nil { return false, err } return true, nil diff --git a/vendor/github.com/coreos/go-systemd/daemon/watchdog.go b/vendor/github.com/coreos/go-systemd/daemon/watchdog.go index 35a92e6e67dbf..7a0e0d3a51b14 100644 --- a/vendor/github.com/coreos/go-systemd/daemon/watchdog.go +++ b/vendor/github.com/coreos/go-systemd/daemon/watchdog.go @@ -21,10 +21,11 @@ import ( "time" ) -// SdWatchdogEnabled return watchdog information for a service. -// Process should send daemon.SdNotify("WATCHDOG=1") every time / 2. -// If `unsetEnvironment` is true, the environment variables `WATCHDOG_USEC` -// and `WATCHDOG_PID` will be unconditionally unset. +// SdWatchdogEnabled returns watchdog information for a service. +// Processes should call daemon.SdNotify(false, daemon.SdNotifyWatchdog) every +// time / 2. +// If `unsetEnvironment` is true, the environment variables `WATCHDOG_USEC` and +// `WATCHDOG_PID` will be unconditionally unset. // // It returns one of the following: // (0, nil) - watchdog isn't enabled or we aren't the watched PID. diff --git a/vendor/github.com/coreos/go-systemd/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/dbus/dbus.go index c1694fb522e71..1d54810aff4e9 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/dbus.go +++ b/vendor/github.com/coreos/go-systemd/dbus/dbus.go @@ -16,6 +16,7 @@ package dbus import ( + "encoding/hex" "fmt" "os" "strconv" @@ -60,6 +61,27 @@ func PathBusEscape(path string) string { return string(n) } +// pathBusUnescape is the inverse of PathBusEscape. +func pathBusUnescape(path string) string { + if path == "_" { + return "" + } + n := []byte{} + for i := 0; i < len(path); i++ { + c := path[i] + if c == '_' && i+2 < len(path) { + res, err := hex.DecodeString(path[i+1 : i+3]) + if err == nil { + n = append(n, res...) + } + i += 2 + } else { + n = append(n, c) + } + } + return string(n) +} + // Conn is a connection to systemd's dbus endpoint. type Conn struct { // sysconn/sysobj are only used to call dbus methods @@ -74,13 +96,18 @@ type Conn struct { jobs map[dbus.ObjectPath]chan<- string sync.Mutex } - subscriber struct { + subStateSubscriber struct { updateCh chan<- *SubStateUpdate errCh chan<- error sync.Mutex ignore map[dbus.ObjectPath]int64 cleanIgnore int64 } + propertiesSubscriber struct { + updateCh chan<- *PropertiesUpdate + errCh chan<- error + sync.Mutex + } } // New establishes a connection to any available bus and authenticates. @@ -152,7 +179,7 @@ func NewConnection(dialBus func() (*dbus.Conn, error)) (*Conn, error) { sigobj: systemdObject(sigconn), } - c.subscriber.ignore = make(map[dbus.ObjectPath]int64) + c.subStateSubscriber.ignore = make(map[dbus.ObjectPath]int64) c.jobListener.jobs = make(map[dbus.ObjectPath]chan<- string) // Setup the listeners on jobs so that we can get completions diff --git a/vendor/github.com/coreos/go-systemd/dbus/methods.go b/vendor/github.com/coreos/go-systemd/dbus/methods.go index ab17f7cc75a4b..0b4207229f775 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/methods.go +++ b/vendor/github.com/coreos/go-systemd/dbus/methods.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015, 2018 CoreOS, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package dbus import ( "errors" + "fmt" "path" "strconv" @@ -148,14 +149,27 @@ func (c *Conn) ResetFailedUnit(name string) error { return c.sysobj.Call("org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store() } -// getProperties takes the unit name and returns all of its dbus object properties, for the given dbus interface -func (c *Conn) getProperties(unit string, dbusInterface string) (map[string]interface{}, error) { +// SystemState returns the systemd state. Equivalent to `systemctl is-system-running`. +func (c *Conn) SystemState() (*Property, error) { + var err error + var prop dbus.Variant + + obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1") + err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop) + if err != nil { + return nil, err + } + + return &Property{Name: "SystemState", Value: prop}, nil +} + +// getProperties takes the unit path and returns all of its dbus object properties, for the given dbus interface +func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) { var err error var props map[string]dbus.Variant - path := unitPath(unit) if !path.IsValid() { - return nil, errors.New("invalid unit name: " + unit) + return nil, fmt.Errorf("invalid unit name: %v", path) } obj := c.sysconn.Object("org.freedesktop.systemd1", path) @@ -172,9 +186,15 @@ func (c *Conn) getProperties(unit string, dbusInterface string) (map[string]inte return out, nil } -// GetUnitProperties takes the unit name and returns all of its dbus object properties. +// GetUnitProperties takes the (unescaped) unit name and returns all of its dbus object properties. func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) { - return c.getProperties(unit, "org.freedesktop.systemd1.Unit") + path := unitPath(unit) + return c.getProperties(path, "org.freedesktop.systemd1.Unit") +} + +// GetUnitProperties takes the (escaped) unit path and returns all of its dbus object properties. +func (c *Conn) GetUnitPathProperties(path dbus.ObjectPath) (map[string]interface{}, error) { + return c.getProperties(path, "org.freedesktop.systemd1.Unit") } func (c *Conn) getProperty(unit string, dbusInterface string, propertyName string) (*Property, error) { @@ -208,7 +228,8 @@ func (c *Conn) GetServiceProperty(service string, propertyName string) (*Propert // Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope // return "dbus.Error: Unknown interface" if the unitType is not the correct type of the unit func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) { - return c.getProperties(unit, "org.freedesktop.systemd1."+unitType) + path := unitPath(unit) + return c.getProperties(path, "org.freedesktop.systemd1."+unitType) } // SetUnitProperties() may be used to modify certain unit properties at runtime. @@ -292,6 +313,7 @@ func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitSt // names and returns an UnitStatus array. Comparing to ListUnitsByPatterns // method, this method returns statuses even for inactive or non-existing // units. Input array should contain exact unit names, but not patterns. +// Note: Requires systemd v230 or higher func (c *Conn) ListUnitsByNames(units []string) ([]UnitStatus, error) { return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store) } @@ -563,3 +585,8 @@ func (c *Conn) Reload() error { func unitPath(name string) dbus.ObjectPath { return dbus.ObjectPath("/org/freedesktop/systemd1/unit/" + PathBusEscape(name)) } + +// unitName returns the unescaped base element of the supplied escaped path +func unitName(dpath dbus.ObjectPath) string { + return pathBusUnescape(path.Base(string(dpath))) +} diff --git a/vendor/github.com/coreos/go-systemd/dbus/set.go b/vendor/github.com/coreos/go-systemd/dbus/set.go index f92e6fbed1eaa..17c5d485657dc 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/set.go +++ b/vendor/github.com/coreos/go-systemd/dbus/set.go @@ -36,7 +36,7 @@ func (s *set) Length() int { } func (s *set) Values() (values []string) { - for val, _ := range s.data { + for val := range s.data { values = append(values, val) } return diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription.go b/vendor/github.com/coreos/go-systemd/dbus/subscription.go index 996451445c06e..70e63a6f16e15 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/subscription.go +++ b/vendor/github.com/coreos/go-systemd/dbus/subscription.go @@ -16,6 +16,7 @@ package dbus import ( "errors" + "log" "time" "github.com/godbus/dbus" @@ -36,22 +37,12 @@ func (c *Conn) Subscribe() error { c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'") - err := c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store() - if err != nil { - return err - } - - return nil + return c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store() } // Unsubscribe this connection from systemd dbus events. func (c *Conn) Unsubscribe() error { - err := c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store() - if err != nil { - return err - } - - return nil + return c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store() } func (c *Conn) dispatch() { @@ -70,7 +61,8 @@ func (c *Conn) dispatch() { c.jobComplete(signal) } - if c.subscriber.updateCh == nil { + if c.subStateSubscriber.updateCh == nil && + c.propertiesSubscriber.updateCh == nil { continue } @@ -84,6 +76,12 @@ func (c *Conn) dispatch() { case "org.freedesktop.DBus.Properties.PropertiesChanged": if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" { unitPath = signal.Path + + if len(signal.Body) >= 2 { + if changed, ok := signal.Body[1].(map[string]dbus.Variant); ok { + c.sendPropertiesUpdate(unitPath, changed) + } + } } } @@ -169,42 +167,80 @@ type SubStateUpdate struct { // is full, it attempts to write an error to errCh; if errCh is full, the error // passes silently. func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) { - c.subscriber.Lock() - defer c.subscriber.Unlock() - c.subscriber.updateCh = updateCh - c.subscriber.errCh = errCh + if c == nil { + msg := "nil receiver" + select { + case errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } + + c.subStateSubscriber.Lock() + defer c.subStateSubscriber.Unlock() + c.subStateSubscriber.updateCh = updateCh + c.subStateSubscriber.errCh = errCh } -func (c *Conn) sendSubStateUpdate(path dbus.ObjectPath) { - c.subscriber.Lock() - defer c.subscriber.Unlock() +func (c *Conn) sendSubStateUpdate(unitPath dbus.ObjectPath) { + c.subStateSubscriber.Lock() + defer c.subStateSubscriber.Unlock() + + if c.subStateSubscriber.updateCh == nil { + return + } - if c.shouldIgnore(path) { + isIgnored := c.shouldIgnore(unitPath) + defer c.cleanIgnore() + if isIgnored { return } - info, err := c.GetUnitProperties(string(path)) + info, err := c.GetUnitPathProperties(unitPath) if err != nil { select { - case c.subscriber.errCh <- err: + case c.subStateSubscriber.errCh <- err: default: + log.Printf("full error channel while reporting: %s\n", err) } + return } + defer c.updateIgnore(unitPath, info) - name := info["Id"].(string) - substate := info["SubState"].(string) + name, ok := info["Id"].(string) + if !ok { + msg := "failed to cast info.Id" + select { + case c.subStateSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", err) + } + return + } + substate, ok := info["SubState"].(string) + if !ok { + msg := "failed to cast info.SubState" + select { + case c.subStateSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } update := &SubStateUpdate{name, substate} select { - case c.subscriber.updateCh <- update: + case c.subStateSubscriber.updateCh <- update: default: + msg := "update channel is full" select { - case c.subscriber.errCh <- errors.New("update channel full!"): + case c.subStateSubscriber.errCh <- errors.New(msg): default: + log.Printf("full error channel while reporting: %s\n", msg) } + return } - - c.updateIgnore(path, info) } // The ignore functions work around a wart in the systemd dbus interface. @@ -222,29 +258,76 @@ func (c *Conn) sendSubStateUpdate(path dbus.ObjectPath) { // the properties). func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool { - t, ok := c.subscriber.ignore[path] + t, ok := c.subStateSubscriber.ignore[path] return ok && t >= time.Now().UnixNano() } func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) { - c.cleanIgnore() + loadState, ok := info["LoadState"].(string) + if !ok { + return + } // unit is unloaded - it will trigger bad systemd dbus behavior - if info["LoadState"].(string) == "not-found" { - c.subscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval + if loadState == "not-found" { + c.subStateSubscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval } } // without this, ignore would grow unboundedly over time func (c *Conn) cleanIgnore() { now := time.Now().UnixNano() - if c.subscriber.cleanIgnore < now { - c.subscriber.cleanIgnore = now + cleanIgnoreInterval + if c.subStateSubscriber.cleanIgnore < now { + c.subStateSubscriber.cleanIgnore = now + cleanIgnoreInterval - for p, t := range c.subscriber.ignore { + for p, t := range c.subStateSubscriber.ignore { if t < now { - delete(c.subscriber.ignore, p) + delete(c.subStateSubscriber.ignore, p) } } } } + +// PropertiesUpdate holds a map of a unit's changed properties +type PropertiesUpdate struct { + UnitName string + Changed map[string]dbus.Variant +} + +// SetPropertiesSubscriber writes to updateCh when any unit's properties +// change. Every property change reported by systemd will be sent; that is, no +// transitions will be "missed" (as they might be with SetSubStateSubscriber). +// However, state changes will only be written to the channel with non-blocking +// writes. If updateCh is full, it attempts to write an error to errCh; if +// errCh is full, the error passes silently. +func (c *Conn) SetPropertiesSubscriber(updateCh chan<- *PropertiesUpdate, errCh chan<- error) { + c.propertiesSubscriber.Lock() + defer c.propertiesSubscriber.Unlock() + c.propertiesSubscriber.updateCh = updateCh + c.propertiesSubscriber.errCh = errCh +} + +// we don't need to worry about shouldIgnore() here because +// sendPropertiesUpdate doesn't call GetProperties() +func (c *Conn) sendPropertiesUpdate(unitPath dbus.ObjectPath, changedProps map[string]dbus.Variant) { + c.propertiesSubscriber.Lock() + defer c.propertiesSubscriber.Unlock() + + if c.propertiesSubscriber.updateCh == nil { + return + } + + update := &PropertiesUpdate{unitName(unitPath), changedProps} + + select { + case c.propertiesSubscriber.updateCh <- update: + default: + msg := "update channel is full" + select { + case c.propertiesSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } +} diff --git a/vendor/github.com/coreos/go-systemd/journal/journal.go b/vendor/github.com/coreos/go-systemd/journal/journal.go index 7f434990d25b4..ef85a3ba2455e 100644 --- a/vendor/github.com/coreos/go-systemd/journal/journal.go +++ b/vendor/github.com/coreos/go-systemd/journal/journal.go @@ -103,7 +103,10 @@ func Send(message string, priority Priority, vars map[string]string) error { if !ok { return journalError("can't send file through non-Unix connection") } - unixConn.WriteMsgUnix([]byte{}, rights, nil) + _, _, err = unixConn.WriteMsgUnix([]byte{}, rights, nil) + if err != nil { + return journalError(err.Error()) + } } else if err != nil { return journalError(err.Error()) } @@ -165,7 +168,7 @@ func tempFd() (*os.File, error) { if err != nil { return nil, err } - syscall.Unlink(file.Name()) + err = syscall.Unlink(file.Name()) if err != nil { return nil, err } diff --git a/vendor/github.com/coreos/go-systemd/util/util_cgo.go b/vendor/github.com/coreos/go-systemd/util/util_cgo.go index 22c0d6099df5b..6269bc73236e1 100644 --- a/vendor/github.com/coreos/go-systemd/util/util_cgo.go +++ b/vendor/github.com/coreos/go-systemd/util/util_cgo.go @@ -122,11 +122,12 @@ func runningFromSystemService() (ret bool, err error) { errno := C.my_sd_pid_get_owner_uid(sd_pid_get_owner_uid, 0, &uid) serrno := syscall.Errno(-errno) // when we're running from a unit file, sd_pid_get_owner_uid returns - // ENOENT (systemd <220) or ENXIO (systemd >=220) + // ENOENT (systemd <220), ENXIO (systemd 220-223), or ENODATA + // (systemd >=234) switch { case errno >= 0: ret = false - case serrno == syscall.ENOENT, serrno == syscall.ENXIO: + case serrno == syscall.ENOENT, serrno == syscall.ENXIO, serrno == syscall.ENODATA: // Since the implementation of sessions in systemd relies on // the `pam_systemd` module, using the sd_pid_get_owner_uid // heuristic alone can result in false positives if that module diff --git a/vendor/github.com/coreos/pkg/capnslog/README.md b/vendor/github.com/coreos/pkg/capnslog/README.md index 81efb1fb6a7bd..f79dbfca5cbe5 100644 --- a/vendor/github.com/coreos/pkg/capnslog/README.md +++ b/vendor/github.com/coreos/pkg/capnslog/README.md @@ -21,7 +21,7 @@ Still the job of `main` to expose these configurations. `main` may delegate this Splitting streams is probably not the job of your program, but rather, your log aggregation framework. If you must split output streams, again, `main` configures this and you can write a very simple two-output struct that satisfies io.Writer. -Fancy colorful formatting and JSON output are beyond the scope of a basic logging framework -- they're application/log-collector dependant. These are, at best, provided as options, but more likely, provided by your application. +Fancy colorful formatting and JSON output are beyond the scope of a basic logging framework -- they're application/log-collector dependent. These are, at best, provided as options, but more likely, provided by your application. ##### Log objects are an interface diff --git a/vendor/github.com/coreos/pkg/capnslog/logmap.go b/vendor/github.com/coreos/pkg/capnslog/logmap.go index 84954488308db..226b60c22534e 100644 --- a/vendor/github.com/coreos/pkg/capnslog/logmap.go +++ b/vendor/github.com/coreos/pkg/capnslog/logmap.go @@ -95,6 +95,11 @@ func (l *LogLevel) Set(s string) error { return nil } +// Returns an empty string, only here to fulfill the pflag.Value interface. +func (l *LogLevel) Type() string { + return "" +} + // ParseLevel translates some potential loglevel strings into their corresponding levels. func ParseLevel(s string) (LogLevel, error) { switch s { diff --git a/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go b/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go index 612d55c66c802..00ff37149aeb5 100644 --- a/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go +++ b/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go @@ -37,6 +37,14 @@ func (p *PackageLogger) internalLog(depth int, inLevel LogLevel, entries ...inte } } +// SetLevel allows users to change the current logging level. +func (p *PackageLogger) SetLevel(l LogLevel) { + logger.Lock() + defer logger.Unlock() + p.level = l +} + +// LevelAt checks if the given log level will be outputted under current setting. func (p *PackageLogger) LevelAt(l LogLevel) bool { logger.Lock() defer logger.Unlock() @@ -81,6 +89,12 @@ func (p *PackageLogger) Panic(args ...interface{}) { panic(s) } +func (p *PackageLogger) Panicln(args ...interface{}) { + s := fmt.Sprintln(args...) + p.internalLog(calldepth, CRITICAL, s) + panic(s) +} + func (p *PackageLogger) Fatalf(format string, args ...interface{}) { p.Logf(CRITICAL, format, args...) os.Exit(1) diff --git a/vendor/github.com/globalsign/mgo/LICENSE b/vendor/github.com/globalsign/mgo/LICENSE new file mode 100644 index 0000000000000..770c7672b45d6 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/LICENSE @@ -0,0 +1,25 @@ +mgo - MongoDB driver for Go + +Copyright (c) 2010-2013 - Gustavo Niemeyer + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/globalsign/mgo/bson/BUILD b/vendor/github.com/globalsign/mgo/bson/BUILD new file mode 100644 index 0000000000000..6e50a6d65fb83 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/BUILD @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "bson.go", + "compatibility.go", + "decimal.go", + "decode.go", + "encode.go", + "json.go", + "stream.go", + ], + importmap = "k8s.io/kubernetes/vendor/github.com/globalsign/mgo/bson", + importpath = "github.com/globalsign/mgo/bson", + visibility = ["//visibility:public"], + deps = ["//vendor/github.com/globalsign/mgo/internal/json: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/github.com/globalsign/mgo/bson/LICENSE b/vendor/github.com/globalsign/mgo/bson/LICENSE new file mode 100644 index 0000000000000..890326017b85c --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/LICENSE @@ -0,0 +1,25 @@ +BSON library for Go + +Copyright (c) 2010-2012 - Gustavo Niemeyer + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/globalsign/mgo/bson/README.md b/vendor/github.com/globalsign/mgo/bson/README.md new file mode 100644 index 0000000000000..5c5819e612b70 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/README.md @@ -0,0 +1,12 @@ +[![GoDoc](https://godoc.org/github.com/globalsign/mgo/bson?status.svg)](https://godoc.org/github.com/globalsign/mgo/bson) + +An Implementation of BSON for Go +-------------------------------- + +Package bson is an implementation of the [BSON specification](http://bsonspec.org) for Go. + +While the BSON package implements the BSON spec as faithfully as possible, there +is some MongoDB specific behaviour (such as map keys `$in`, `$all`, etc) in the +`bson` package. The priority is for backwards compatibility for the `mgo` +driver, though fixes for obviously buggy behaviour is welcome (and features, etc +behind feature flags). diff --git a/vendor/github.com/globalsign/mgo/bson/bson.go b/vendor/github.com/globalsign/mgo/bson/bson.go new file mode 100644 index 0000000000000..eb87ef6208a2b --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/bson.go @@ -0,0 +1,836 @@ +// BSON library for Go +// +// Copyright (c) 2010-2012 - Gustavo Niemeyer +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Package bson is an implementation of the BSON specification for Go: +// +// http://bsonspec.org +// +// It was created as part of the mgo MongoDB driver for Go, but is standalone +// and may be used on its own without the driver. +package bson + +import ( + "bytes" + "crypto/md5" + "crypto/rand" + "encoding/binary" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "math" + "os" + "reflect" + "runtime" + "strings" + "sync" + "sync/atomic" + "time" +) + +//go:generate go run bson_corpus_spec_test_generator.go + +// -------------------------------------------------------------------------- +// The public API. + +// Element types constants from BSON specification. +const ( + ElementFloat64 byte = 0x01 + ElementString byte = 0x02 + ElementDocument byte = 0x03 + ElementArray byte = 0x04 + ElementBinary byte = 0x05 + Element06 byte = 0x06 + ElementObjectId byte = 0x07 + ElementBool byte = 0x08 + ElementDatetime byte = 0x09 + ElementNil byte = 0x0A + ElementRegEx byte = 0x0B + ElementDBPointer byte = 0x0C + ElementJavaScriptWithoutScope byte = 0x0D + ElementSymbol byte = 0x0E + ElementJavaScriptWithScope byte = 0x0F + ElementInt32 byte = 0x10 + ElementTimestamp byte = 0x11 + ElementInt64 byte = 0x12 + ElementDecimal128 byte = 0x13 + ElementMinKey byte = 0xFF + ElementMaxKey byte = 0x7F + + BinaryGeneric byte = 0x00 + BinaryFunction byte = 0x01 + BinaryBinaryOld byte = 0x02 + BinaryUUIDOld byte = 0x03 + BinaryUUID byte = 0x04 + BinaryMD5 byte = 0x05 + BinaryUserDefined byte = 0x80 +) + +// Getter interface: a value implementing the bson.Getter interface will have its GetBSON +// method called when the given value has to be marshalled, and the result +// of this method will be marshaled in place of the actual object. +// +// If GetBSON returns return a non-nil error, the marshalling procedure +// will stop and error out with the provided value. +type Getter interface { + GetBSON() (interface{}, error) +} + +// Setter interface: a value implementing the bson.Setter interface will receive the BSON +// value via the SetBSON method during unmarshaling, and the object +// itself will not be changed as usual. +// +// If setting the value works, the method should return nil or alternatively +// bson.ErrSetZero to set the respective field to its zero value (nil for +// pointer types). If SetBSON returns a value of type bson.TypeError, the +// BSON value will be omitted from a map or slice being decoded and the +// unmarshalling will continue. If it returns any other non-nil error, the +// unmarshalling procedure will stop and error out with the provided value. +// +// This interface is generally useful in pointer receivers, since the method +// will want to change the receiver. A type field that implements the Setter +// interface doesn't have to be a pointer, though. +// +// Unlike the usual behavior, unmarshalling onto a value that implements a +// Setter interface will NOT reset the value to its zero state. This allows +// the value to decide by itself how to be unmarshalled. +// +// For example: +// +// type MyString string +// +// func (s *MyString) SetBSON(raw bson.Raw) error { +// return raw.Unmarshal(s) +// } +// +type Setter interface { + SetBSON(raw Raw) error +} + +// ErrSetZero may be returned from a SetBSON method to have the value set to +// its respective zero value. When used in pointer values, this will set the +// field to nil rather than to the pre-allocated value. +var ErrSetZero = errors.New("set to zero") + +// M is a convenient alias for a map[string]interface{} map, useful for +// dealing with BSON in a native way. For instance: +// +// bson.M{"a": 1, "b": true} +// +// There's no special handling for this type in addition to what's done anyway +// for an equivalent map type. Elements in the map will be dumped in an +// undefined ordered. See also the bson.D type for an ordered alternative. +type M map[string]interface{} + +// D represents a BSON document containing ordered elements. For example: +// +// bson.D{{"a", 1}, {"b", true}} +// +// In some situations, such as when creating indexes for MongoDB, the order in +// which the elements are defined is important. If the order is not important, +// using a map is generally more comfortable. See bson.M and bson.RawD. +type D []DocElem + +// DocElem is an element of the bson.D document representation. +type DocElem struct { + Name string + Value interface{} +} + +// Map returns a map out of the ordered element name/value pairs in d. +func (d D) Map() (m M) { + m = make(M, len(d)) + for _, item := range d { + m[item.Name] = item.Value + } + return m +} + +// The Raw type represents raw unprocessed BSON documents and elements. +// Kind is the kind of element as defined per the BSON specification, and +// Data is the raw unprocessed data for the respective element. +// Using this type it is possible to unmarshal or marshal values partially. +// +// Relevant documentation: +// +// http://bsonspec.org/#/specification +// +type Raw struct { + Kind byte + Data []byte +} + +// RawD represents a BSON document containing raw unprocessed elements. +// This low-level representation may be useful when lazily processing +// documents of uncertain content, or when manipulating the raw content +// documents in general. +type RawD []RawDocElem + +// RawDocElem elements of RawD type. +type RawDocElem struct { + Name string + Value Raw +} + +// ObjectId is a unique ID identifying a BSON value. It must be exactly 12 bytes +// long. MongoDB objects by default have such a property set in their "_id" +// property. +// +// http://www.mongodb.org/display/DOCS/Object+Ids +type ObjectId string + +// ObjectIdHex returns an ObjectId from the provided hex representation. +// Calling this function with an invalid hex representation will +// cause a runtime panic. See the IsObjectIdHex function. +func ObjectIdHex(s string) ObjectId { + d, err := hex.DecodeString(s) + if err != nil || len(d) != 12 { + panic(fmt.Sprintf("invalid input to ObjectIdHex: %q", s)) + } + return ObjectId(d) +} + +// IsObjectIdHex returns whether s is a valid hex representation of +// an ObjectId. See the ObjectIdHex function. +func IsObjectIdHex(s string) bool { + if len(s) != 24 { + return false + } + _, err := hex.DecodeString(s) + return err == nil +} + +// objectIdCounter is atomically incremented when generating a new ObjectId +// using NewObjectId() function. It's used as a counter part of an id. +var objectIdCounter = readRandomUint32() + +// readRandomUint32 returns a random objectIdCounter. +func readRandomUint32() uint32 { + var b [4]byte + _, err := io.ReadFull(rand.Reader, b[:]) + if err != nil { + panic(fmt.Errorf("cannot read random object id: %v", err)) + } + return uint32((uint32(b[0]) << 0) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)) +} + +// machineId stores machine id generated once and used in subsequent calls +// to NewObjectId function. +var machineId = readMachineId() +var processId = os.Getpid() + +// readMachineId generates and returns a machine id. +// If this function fails to get the hostname it will cause a runtime error. +func readMachineId() []byte { + var sum [3]byte + id := sum[:] + hostname, err1 := os.Hostname() + if err1 != nil { + _, err2 := io.ReadFull(rand.Reader, id) + if err2 != nil { + panic(fmt.Errorf("cannot get hostname: %v; %v", err1, err2)) + } + return id + } + hw := md5.New() + hw.Write([]byte(hostname)) + copy(id, hw.Sum(nil)) + return id +} + +// NewObjectId returns a new unique ObjectId. +func NewObjectId() ObjectId { + var b [12]byte + // Timestamp, 4 bytes, big endian + binary.BigEndian.PutUint32(b[:], uint32(time.Now().Unix())) + // Machine, first 3 bytes of md5(hostname) + b[4] = machineId[0] + b[5] = machineId[1] + b[6] = machineId[2] + // Pid, 2 bytes, specs don't specify endianness, but we use big endian. + b[7] = byte(processId >> 8) + b[8] = byte(processId) + // Increment, 3 bytes, big endian + i := atomic.AddUint32(&objectIdCounter, 1) + b[9] = byte(i >> 16) + b[10] = byte(i >> 8) + b[11] = byte(i) + return ObjectId(b[:]) +} + +// NewObjectIdWithTime returns a dummy ObjectId with the timestamp part filled +// with the provided number of seconds from epoch UTC, and all other parts +// filled with zeroes. It's not safe to insert a document with an id generated +// by this method, it is useful only for queries to find documents with ids +// generated before or after the specified timestamp. +func NewObjectIdWithTime(t time.Time) ObjectId { + var b [12]byte + binary.BigEndian.PutUint32(b[:4], uint32(t.Unix())) + return ObjectId(string(b[:])) +} + +// String returns a hex string representation of the id. +// Example: ObjectIdHex("4d88e15b60f486e428412dc9"). +func (id ObjectId) String() string { + return fmt.Sprintf(`ObjectIdHex("%x")`, string(id)) +} + +// Hex returns a hex representation of the ObjectId. +func (id ObjectId) Hex() string { + return hex.EncodeToString([]byte(id)) +} + +// MarshalJSON turns a bson.ObjectId into a json.Marshaller. +func (id ObjectId) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%x"`, string(id))), nil +} + +var nullBytes = []byte("null") + +// UnmarshalJSON turns *bson.ObjectId into a json.Unmarshaller. +func (id *ObjectId) UnmarshalJSON(data []byte) error { + if len(data) > 0 && (data[0] == '{' || data[0] == 'O') { + var v struct { + Id json.RawMessage `json:"$oid"` + Func struct { + Id json.RawMessage + } `json:"$oidFunc"` + } + err := jdec(data, &v) + if err == nil { + if len(v.Id) > 0 { + data = []byte(v.Id) + } else { + data = []byte(v.Func.Id) + } + } + } + if len(data) == 2 && data[0] == '"' && data[1] == '"' || bytes.Equal(data, nullBytes) { + *id = "" + return nil + } + if len(data) != 26 || data[0] != '"' || data[25] != '"' { + return fmt.Errorf("invalid ObjectId in JSON: %s", string(data)) + } + var buf [12]byte + _, err := hex.Decode(buf[:], data[1:25]) + if err != nil { + return fmt.Errorf("invalid ObjectId in JSON: %s (%s)", string(data), err) + } + *id = ObjectId(string(buf[:])) + return nil +} + +// MarshalText turns bson.ObjectId into an encoding.TextMarshaler. +func (id ObjectId) MarshalText() ([]byte, error) { + return []byte(fmt.Sprintf("%x", string(id))), nil +} + +// UnmarshalText turns *bson.ObjectId into an encoding.TextUnmarshaler. +func (id *ObjectId) UnmarshalText(data []byte) error { + if len(data) == 1 && data[0] == ' ' || len(data) == 0 { + *id = "" + return nil + } + if len(data) != 24 { + return fmt.Errorf("invalid ObjectId: %s", data) + } + var buf [12]byte + _, err := hex.Decode(buf[:], data[:]) + if err != nil { + return fmt.Errorf("invalid ObjectId: %s (%s)", data, err) + } + *id = ObjectId(string(buf[:])) + return nil +} + +// Valid returns true if id is valid. A valid id must contain exactly 12 bytes. +func (id ObjectId) Valid() bool { + return len(id) == 12 +} + +// byteSlice returns byte slice of id from start to end. +// Calling this function with an invalid id will cause a runtime panic. +func (id ObjectId) byteSlice(start, end int) []byte { + if len(id) != 12 { + panic(fmt.Sprintf("invalid ObjectId: %q", string(id))) + } + return []byte(string(id)[start:end]) +} + +// Time returns the timestamp part of the id. +// It's a runtime error to call this method with an invalid id. +func (id ObjectId) Time() time.Time { + // First 4 bytes of ObjectId is 32-bit big-endian seconds from epoch. + secs := int64(binary.BigEndian.Uint32(id.byteSlice(0, 4))) + return time.Unix(secs, 0) +} + +// Machine returns the 3-byte machine id part of the id. +// It's a runtime error to call this method with an invalid id. +func (id ObjectId) Machine() []byte { + return id.byteSlice(4, 7) +} + +// Pid returns the process id part of the id. +// It's a runtime error to call this method with an invalid id. +func (id ObjectId) Pid() uint16 { + return binary.BigEndian.Uint16(id.byteSlice(7, 9)) +} + +// Counter returns the incrementing value part of the id. +// It's a runtime error to call this method with an invalid id. +func (id ObjectId) Counter() int32 { + b := id.byteSlice(9, 12) + // Counter is stored as big-endian 3-byte value + return int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2])) +} + +// The Symbol type is similar to a string and is used in languages with a +// distinct symbol type. +type Symbol string + +// Now returns the current time with millisecond precision. MongoDB stores +// timestamps with the same precision, so a Time returned from this method +// will not change after a roundtrip to the database. That's the only reason +// why this function exists. Using the time.Now function also works fine +// otherwise. +func Now() time.Time { + return time.Unix(0, time.Now().UnixNano()/1e6*1e6) +} + +// MongoTimestamp is a special internal type used by MongoDB that for some +// strange reason has its own datatype defined in BSON. +type MongoTimestamp int64 + +// Time returns the time part of ts which is stored with second precision. +func (ts MongoTimestamp) Time() time.Time { + return time.Unix(int64(uint64(ts)>>32), 0) +} + +// Counter returns the counter part of ts. +func (ts MongoTimestamp) Counter() uint32 { + return uint32(ts) +} + +// NewMongoTimestamp creates a timestamp using the given +// date `t` (with second precision) and counter `c` (unique for `t`). +// +// Returns an error if time `t` is not between 1970-01-01T00:00:00Z +// and 2106-02-07T06:28:15Z (inclusive). +// +// Note that two MongoTimestamps should never have the same (time, counter) combination: +// the caller must ensure the counter `c` is increased if creating multiple MongoTimestamp +// values for the same time `t` (ignoring fractions of seconds). +func NewMongoTimestamp(t time.Time, c uint32) (MongoTimestamp, error) { + u := t.Unix() + if u < 0 || u > math.MaxUint32 { + return -1, errors.New("invalid value for time") + } + + i := int64(u<<32 | int64(c)) + + return MongoTimestamp(i), nil +} + +type orderKey int64 + +// MaxKey is a special value that compares higher than all other possible BSON +// values in a MongoDB database. +var MaxKey = orderKey(1<<63 - 1) + +// MinKey is a special value that compares lower than all other possible BSON +// values in a MongoDB database. +var MinKey = orderKey(-1 << 63) + +type undefined struct{} + +// Undefined represents the undefined BSON value. +var Undefined undefined + +// Binary is a representation for non-standard binary values. Any kind should +// work, but the following are known as of this writing: +// +// 0x00 - Generic. This is decoded as []byte(data), not Binary{0x00, data}. +// 0x01 - Function (!?) +// 0x02 - Obsolete generic. +// 0x03 - UUID +// 0x05 - MD5 +// 0x80 - User defined. +// +type Binary struct { + Kind byte + Data []byte +} + +// RegEx represents a regular expression. The Options field may contain +// individual characters defining the way in which the pattern should be +// applied, and must be sorted. Valid options as of this writing are 'i' for +// case insensitive matching, 'm' for multi-line matching, 'x' for verbose +// mode, 'l' to make \w, \W, and similar be locale-dependent, 's' for dot-all +// mode (a '.' matches everything), and 'u' to make \w, \W, and similar match +// unicode. The value of the Options parameter is not verified before being +// marshaled into the BSON format. +type RegEx struct { + Pattern string + Options string +} + +// JavaScript is a type that holds JavaScript code. If Scope is non-nil, it +// will be marshaled as a mapping from identifiers to values that may be +// used when evaluating the provided Code. +type JavaScript struct { + Code string + Scope interface{} +} + +// DBPointer refers to a document id in a namespace. +// +// This type is deprecated in the BSON specification and should not be used +// except for backwards compatibility with ancient applications. +type DBPointer struct { + Namespace string + Id ObjectId +} + +const initialBufferSize = 64 + +func handleErr(err *error) { + if r := recover(); r != nil { + if _, ok := r.(runtime.Error); ok { + panic(r) + } else if _, ok := r.(externalPanic); ok { + panic(r) + } else if s, ok := r.(string); ok { + *err = errors.New(s) + } else if e, ok := r.(error); ok { + *err = e + } else { + panic(r) + } + } +} + +// Marshal serializes the in value, which may be a map or a struct value. +// In the case of struct values, only exported fields will be serialized, +// and the order of serialized fields will match that of the struct itself. +// The lowercased field name is used as the key for each exported field, +// but this behavior may be changed using the respective field tag. +// The tag may also contain flags to tweak the marshalling behavior for +// the field. The tag formats accepted are: +// +// "[][,[,]]" +// +// `(...) bson:"[][,[,]]" (...)` +// +// The following flags are currently supported: +// +// omitempty Only include the field if it's not set to the zero +// value for the type or to empty slices or maps. +// +// minsize Marshal an int64 value as an int32, if that's feasible +// while preserving the numeric value. +// +// inline Inline the field, which must be a struct or a map, +// causing all of its fields or keys to be processed as if +// they were part of the outer struct. For maps, keys must +// not conflict with the bson keys of other struct fields. +// +// Some examples: +// +// type T struct { +// A bool +// B int "myb" +// C string "myc,omitempty" +// D string `bson:",omitempty" json:"jsonkey"` +// E int64 ",minsize" +// F int64 "myf,omitempty,minsize" +// } +// +func Marshal(in interface{}) (out []byte, err error) { + return MarshalBuffer(in, make([]byte, 0, initialBufferSize)) +} + +// MarshalBuffer behaves the same way as Marshal, except that instead of +// allocating a new byte slice it tries to use the received byte slice and +// only allocates more memory if necessary to fit the marshaled value. +func MarshalBuffer(in interface{}, buf []byte) (out []byte, err error) { + defer handleErr(&err) + e := &encoder{buf} + e.addDoc(reflect.ValueOf(in)) + return e.out, nil +} + +// Unmarshal deserializes data from in into the out value. The out value +// must be a map, a pointer to a struct, or a pointer to a bson.D value. +// In the case of struct values, only exported fields will be deserialized. +// The lowercased field name is used as the key for each exported field, +// but this behavior may be changed using the respective field tag. +// The tag may also contain flags to tweak the marshalling behavior for +// the field. The tag formats accepted are: +// +// "[][,[,]]" +// +// `(...) bson:"[][,[,]]" (...)` +// +// The following flags are currently supported during unmarshal (see the +// Marshal method for other flags): +// +// inline Inline the field, which must be a struct or a map. +// Inlined structs are handled as if its fields were part +// of the outer struct. An inlined map causes keys that do +// not match any other struct field to be inserted in the +// map rather than being discarded as usual. +// +// The target field or element types of out may not necessarily match +// the BSON values of the provided data. The following conversions are +// made automatically: +// +// - Numeric types are converted if at least the integer part of the +// value would be preserved correctly +// - Bools are converted to numeric types as 1 or 0 +// - Numeric types are converted to bools as true if not 0 or false otherwise +// - Binary and string BSON data is converted to a string, array or byte slice +// +// If the value would not fit the type and cannot be converted, it's +// silently skipped. +// +// Pointer values are initialized when necessary. +func Unmarshal(in []byte, out interface{}) (err error) { + if raw, ok := out.(*Raw); ok { + raw.Kind = 3 + raw.Data = in + return nil + } + defer handleErr(&err) + v := reflect.ValueOf(out) + switch v.Kind() { + case reflect.Ptr: + fallthrough + case reflect.Map: + d := newDecoder(in) + d.readDocTo(v) + if d.i < len(d.in) { + return errors.New("document is corrupted") + } + case reflect.Struct: + return errors.New("unmarshal can't deal with struct values. Use a pointer") + default: + return errors.New("unmarshal needs a map or a pointer to a struct") + } + return nil +} + +// Unmarshal deserializes raw into the out value. If the out value type +// is not compatible with raw, a *bson.TypeError is returned. +// +// See the Unmarshal function documentation for more details on the +// unmarshalling process. +func (raw Raw) Unmarshal(out interface{}) (err error) { + defer handleErr(&err) + v := reflect.ValueOf(out) + switch v.Kind() { + case reflect.Ptr: + v = v.Elem() + fallthrough + case reflect.Map: + d := newDecoder(raw.Data) + good := d.readElemTo(v, raw.Kind) + if !good { + return &TypeError{v.Type(), raw.Kind} + } + case reflect.Struct: + return errors.New("raw Unmarshal can't deal with struct values. Use a pointer") + default: + return errors.New("raw Unmarshal needs a map or a valid pointer") + } + return nil +} + +// TypeError store details for type error occuring +// during unmarshaling +type TypeError struct { + Type reflect.Type + Kind byte +} + +func (e *TypeError) Error() string { + return fmt.Sprintf("BSON kind 0x%02x isn't compatible with type %s", e.Kind, e.Type.String()) +} + +// -------------------------------------------------------------------------- +// Maintain a mapping of keys to structure field indexes + +type structInfo struct { + FieldsMap map[string]fieldInfo + FieldsList []fieldInfo + InlineMap int + Zero reflect.Value +} + +type fieldInfo struct { + Key string + Num int + OmitEmpty bool + MinSize bool + Inline []int +} + +var structMap = make(map[reflect.Type]*structInfo) +var structMapMutex sync.RWMutex + +type externalPanic string + +func (e externalPanic) String() string { + return string(e) +} + +func getStructInfo(st reflect.Type) (*structInfo, error) { + structMapMutex.RLock() + sinfo, found := structMap[st] + structMapMutex.RUnlock() + if found { + return sinfo, nil + } + n := st.NumField() + fieldsMap := make(map[string]fieldInfo) + fieldsList := make([]fieldInfo, 0, n) + inlineMap := -1 + for i := 0; i != n; i++ { + field := st.Field(i) + if field.PkgPath != "" && !field.Anonymous { + continue // Private field + } + + info := fieldInfo{Num: i} + + tag := field.Tag.Get("bson") + + // Fall-back to JSON struct tag, if feature flag is set. + if tag == "" && useJSONTagFallback { + tag = field.Tag.Get("json") + } + + // If there's no bson/json tag available. + if tag == "" { + // If there's no tag, and also no tag: value splits (i.e. no colon) + // then assume the entire tag is the value + if strings.Index(string(field.Tag), ":") < 0 { + tag = string(field.Tag) + } + } + + if tag == "-" { + continue + } + + inline := false + fields := strings.Split(tag, ",") + if len(fields) > 1 { + for _, flag := range fields[1:] { + switch flag { + case "omitempty": + info.OmitEmpty = true + case "minsize": + info.MinSize = true + case "inline": + inline = true + default: + msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st) + panic(externalPanic(msg)) + } + } + tag = fields[0] + } + + if inline { + switch field.Type.Kind() { + case reflect.Map: + if inlineMap >= 0 { + return nil, errors.New("Multiple ,inline maps in struct " + st.String()) + } + if field.Type.Key() != reflect.TypeOf("") { + return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String()) + } + inlineMap = info.Num + case reflect.Ptr: + // allow only pointer to struct + if kind := field.Type.Elem().Kind(); kind != reflect.Struct { + return nil, errors.New("Option ,inline allows a pointer only to a struct, was given pointer to " + kind.String()) + } + + field.Type = field.Type.Elem() + fallthrough + case reflect.Struct: + sinfo, err := getStructInfo(field.Type) + if err != nil { + return nil, err + } + for _, finfo := range sinfo.FieldsList { + if _, found := fieldsMap[finfo.Key]; found { + msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String() + return nil, errors.New(msg) + } + if finfo.Inline == nil { + finfo.Inline = []int{i, finfo.Num} + } else { + finfo.Inline = append([]int{i}, finfo.Inline...) + } + fieldsMap[finfo.Key] = finfo + fieldsList = append(fieldsList, finfo) + } + default: + panic("Option ,inline needs a struct value or a pointer to a struct or map field") + } + continue + } + + if tag != "" { + info.Key = tag + } else { + info.Key = strings.ToLower(field.Name) + } + + if _, found = fieldsMap[info.Key]; found { + msg := "Duplicated key '" + info.Key + "' in struct " + st.String() + return nil, errors.New(msg) + } + + fieldsList = append(fieldsList, info) + fieldsMap[info.Key] = info + } + sinfo = &structInfo{ + fieldsMap, + fieldsList, + inlineMap, + reflect.New(st).Elem(), + } + structMapMutex.Lock() + structMap[st] = sinfo + structMapMutex.Unlock() + return sinfo, nil +} diff --git a/vendor/github.com/globalsign/mgo/bson/bson_corpus_spec_test_generator.go b/vendor/github.com/globalsign/mgo/bson/bson_corpus_spec_test_generator.go new file mode 100644 index 0000000000000..3525a004b6c8d --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/bson_corpus_spec_test_generator.go @@ -0,0 +1,294 @@ +// +build ignore + +package main + +import ( + "bytes" + "fmt" + "go/format" + "html/template" + "io/ioutil" + "log" + "path/filepath" + "strings" + + "github.com/globalsign/mgo/internal/json" +) + +func main() { + log.SetFlags(0) + log.SetPrefix(name + ": ") + + var g Generator + + fmt.Fprintf(&g, "// Code generated by \"%s.go\"; DO NOT EDIT\n\n", name) + + src := g.generate() + + err := ioutil.WriteFile(fmt.Sprintf("%s.go", strings.TrimSuffix(name, "_generator")), src, 0644) + if err != nil { + log.Fatalf("writing output: %s", err) + } +} + +// Generator holds the state of the analysis. Primarily used to buffer +// the output for format.Source. +type Generator struct { + bytes.Buffer // Accumulated output. +} + +// format returns the gofmt-ed contents of the Generator's buffer. +func (g *Generator) format() []byte { + src, err := format.Source(g.Bytes()) + if err != nil { + // Should never happen, but can arise when developing this code. + // The user can compile the output to see the error. + log.Printf("warning: internal error: invalid Go generated: %s", err) + log.Printf("warning: compile the package to analyze the error") + return g.Bytes() + } + return src +} + +// EVERYTHING ABOVE IS CONSTANT BETWEEN THE GENERATORS + +const name = "bson_corpus_spec_test_generator" + +func (g *Generator) generate() []byte { + + testFiles, err := filepath.Glob("./specdata/specifications/source/bson-corpus/tests/*.json") + if err != nil { + log.Fatalf("error reading bson-corpus files: %s", err) + } + + tests, err := g.loadTests(testFiles) + if err != nil { + log.Fatalf("error loading tests: %s", err) + } + + tmpl, err := g.getTemplate() + if err != nil { + log.Fatalf("error loading template: %s", err) + } + + tmpl.Execute(&g.Buffer, tests) + + return g.format() +} + +func (g *Generator) loadTests(filenames []string) ([]*testDef, error) { + var tests []*testDef + for _, filename := range filenames { + test, err := g.loadTest(filename) + if err != nil { + return nil, err + } + + tests = append(tests, test) + } + + return tests, nil +} + +func (g *Generator) loadTest(filename string) (*testDef, error) { + content, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + + var testDef testDef + err = json.Unmarshal(content, &testDef) + if err != nil { + return nil, err + } + + names := make(map[string]struct{}) + + for i := len(testDef.Valid) - 1; i >= 0; i-- { + if testDef.BsonType == "0x05" && testDef.Valid[i].Description == "subtype 0x02" { + testDef.Valid = append(testDef.Valid[:i], testDef.Valid[i+1:]...) + continue + } + + name := cleanupFuncName(testDef.Description + "_" + testDef.Valid[i].Description) + nameIdx := name + j := 1 + for { + if _, ok := names[nameIdx]; !ok { + break + } + + nameIdx = fmt.Sprintf("%s_%d", name, j) + } + + names[nameIdx] = struct{}{} + + testDef.Valid[i].TestDef = &testDef + testDef.Valid[i].Name = nameIdx + testDef.Valid[i].StructTest = testDef.TestKey != "" && + (testDef.BsonType != "0x05" || strings.Contains(testDef.Valid[i].Description, "0x00")) && + !testDef.Deprecated + } + + for i := len(testDef.DecodeErrors) - 1; i >= 0; i-- { + if strings.Contains(testDef.DecodeErrors[i].Description, "UTF-8") { + testDef.DecodeErrors = append(testDef.DecodeErrors[:i], testDef.DecodeErrors[i+1:]...) + continue + } + + name := cleanupFuncName(testDef.Description + "_" + testDef.DecodeErrors[i].Description) + nameIdx := name + j := 1 + for { + if _, ok := names[nameIdx]; !ok { + break + } + + nameIdx = fmt.Sprintf("%s_%d", name, j) + } + names[nameIdx] = struct{}{} + + testDef.DecodeErrors[i].Name = nameIdx + } + + return &testDef, nil +} + +func (g *Generator) getTemplate() (*template.Template, error) { + content := `package bson_test + +import ( + "encoding/hex" + "time" + + . "gopkg.in/check.v1" + "github.com/globalsign/mgo/bson" +) + +func testValid(c *C, in []byte, expected []byte, result interface{}) { + err := bson.Unmarshal(in, result) + c.Assert(err, IsNil) + + out, err := bson.Marshal(result) + c.Assert(err, IsNil) + + c.Assert(string(expected), Equals, string(out), Commentf("roundtrip failed for %T, expected '%x' but got '%x'", result, expected, out)) +} + +func testDecodeSkip(c *C, in []byte) { + err := bson.Unmarshal(in, &struct{}{}) + c.Assert(err, IsNil) +} + +func testDecodeError(c *C, in []byte, result interface{}) { + err := bson.Unmarshal(in, result) + c.Assert(err, Not(IsNil)) +} + +{{range .}} +{{range .Valid}} +func (s *S) Test{{.Name}}(c *C) { + b, err := hex.DecodeString("{{.Bson}}") + c.Assert(err, IsNil) + + {{if .CanonicalBson}} + cb, err := hex.DecodeString("{{.CanonicalBson}}") + c.Assert(err, IsNil) + {{else}} + cb := b + {{end}} + + var resultD bson.D + testValid(c, b, cb, &resultD) + {{if .StructTest}}var resultS struct { + Element {{.TestDef.GoType}} ` + "`bson:\"{{.TestDef.TestKey}}\"`" + ` + } + testValid(c, b, cb, &resultS){{end}} + + testDecodeSkip(c, b) +} +{{end}} + +{{range .DecodeErrors}} +func (s *S) Test{{.Name}}(c *C) { + b, err := hex.DecodeString("{{.Bson}}") + c.Assert(err, IsNil) + + var resultD bson.D + testDecodeError(c, b, &resultD) +} +{{end}} +{{end}} +` + tmpl, err := template.New("").Parse(content) + if err != nil { + return nil, err + } + return tmpl, nil +} + +func cleanupFuncName(name string) string { + return strings.Map(func(r rune) rune { + if (r >= 48 && r <= 57) || (r >= 65 && r <= 90) || (r >= 97 && r <= 122) { + return r + } + return '_' + }, name) +} + +type testDef struct { + Description string `json:"description"` + BsonType string `json:"bson_type"` + TestKey string `json:"test_key"` + Valid []*valid `json:"valid"` + DecodeErrors []*decodeError `json:"decodeErrors"` + Deprecated bool `json:"deprecated"` +} + +func (t *testDef) GoType() string { + switch t.BsonType { + case "0x01": + return "float64" + case "0x02": + return "string" + case "0x03": + return "bson.D" + case "0x04": + return "[]interface{}" + case "0x05": + return "[]byte" + case "0x07": + return "bson.ObjectId" + case "0x08": + return "bool" + case "0x09": + return "time.Time" + case "0x0E": + return "string" + case "0x10": + return "int32" + case "0x12": + return "int64" + case "0x13": + return "bson.Decimal" + default: + return "interface{}" + } +} + +type valid struct { + Description string `json:"description"` + Bson string `json:"bson"` + CanonicalBson string `json:"canonical_bson"` + + Name string + StructTest bool + TestDef *testDef +} + +type decodeError struct { + Description string `json:"description"` + Bson string `json:"bson"` + + Name string +} diff --git a/vendor/github.com/globalsign/mgo/bson/compatibility.go b/vendor/github.com/globalsign/mgo/bson/compatibility.go new file mode 100644 index 0000000000000..66efd465faccd --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/compatibility.go @@ -0,0 +1,29 @@ +package bson + +// Current state of the JSON tag fallback option. +var useJSONTagFallback = false +var useRespectNilValues = false + +// SetJSONTagFallback enables or disables the JSON-tag fallback for structure tagging. When this is enabled, structures +// without BSON tags on a field will fall-back to using the JSON tag (if present). +func SetJSONTagFallback(state bool) { + useJSONTagFallback = state +} + +// JSONTagFallbackState returns the current status of the JSON tag fallback compatability option. See SetJSONTagFallback +// for more information. +func JSONTagFallbackState() bool { + return useJSONTagFallback +} + +// SetRespectNilValues enables or disables serializing nil slices or maps to `null` values. +// In other words it enables `encoding/json` compatible behaviour. +func SetRespectNilValues(state bool) { + useRespectNilValues = state +} + +// RespectNilValuesState returns the current status of the JSON nil slices and maps fallback compatibility option. +// See SetRespectNilValues for more information. +func RespectNilValuesState() bool { + return useRespectNilValues +} diff --git a/vendor/github.com/globalsign/mgo/bson/decimal.go b/vendor/github.com/globalsign/mgo/bson/decimal.go new file mode 100644 index 0000000000000..672ba1825940b --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/decimal.go @@ -0,0 +1,312 @@ +// BSON library for Go +// +// Copyright (c) 2010-2012 - Gustavo Niemeyer +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package bson + +import ( + "fmt" + "strconv" + "strings" +) + +// Decimal128 holds decimal128 BSON values. +type Decimal128 struct { + h, l uint64 +} + +func (d Decimal128) String() string { + var pos int // positive sign + var e int // exponent + var h, l uint64 // significand high/low + + if d.h>>63&1 == 0 { + pos = 1 + } + + switch d.h >> 58 & (1<<5 - 1) { + case 0x1F: + return "NaN" + case 0x1E: + return "-Inf"[pos:] + } + + l = d.l + if d.h>>61&3 == 3 { + // Bits: 1*sign 2*ignored 14*exponent 111*significand. + // Implicit 0b100 prefix in significand. + e = int(d.h>>47&(1<<14-1)) - 6176 + //h = 4<<47 | d.h&(1<<47-1) + // Spec says all of these values are out of range. + h, l = 0, 0 + } else { + // Bits: 1*sign 14*exponent 113*significand + e = int(d.h>>49&(1<<14-1)) - 6176 + h = d.h & (1<<49 - 1) + } + + // Would be handled by the logic below, but that's trivial and common. + if h == 0 && l == 0 && e == 0 { + return "-0"[pos:] + } + + var repr [48]byte // Loop 5 times over 9 digits plus dot, negative sign, and leading zero. + var last = len(repr) + var i = len(repr) + var dot = len(repr) + e + var rem uint32 +Loop: + for d9 := 0; d9 < 5; d9++ { + h, l, rem = divmod(h, l, 1e9) + for d1 := 0; d1 < 9; d1++ { + // Handle "-0.0", "0.00123400", "-1.00E-6", "1.050E+3", etc. + if i < len(repr) && (dot == i || l == 0 && h == 0 && rem > 0 && rem < 10 && (dot < i-6 || e > 0)) { + e += len(repr) - i + i-- + repr[i] = '.' + last = i - 1 + dot = len(repr) // Unmark. + } + c := '0' + byte(rem%10) + rem /= 10 + i-- + repr[i] = c + // Handle "0E+3", "1E+3", etc. + if l == 0 && h == 0 && rem == 0 && i == len(repr)-1 && (dot < i-5 || e > 0) { + last = i + break Loop + } + if c != '0' { + last = i + } + // Break early. Works without it, but why. + if dot > i && l == 0 && h == 0 && rem == 0 { + break Loop + } + } + } + repr[last-1] = '-' + last-- + + if e > 0 { + return string(repr[last+pos:]) + "E+" + strconv.Itoa(e) + } + if e < 0 { + return string(repr[last+pos:]) + "E" + strconv.Itoa(e) + } + return string(repr[last+pos:]) +} + +func divmod(h, l uint64, div uint32) (qh, ql uint64, rem uint32) { + div64 := uint64(div) + a := h >> 32 + aq := a / div64 + ar := a % div64 + b := ar<<32 + h&(1<<32-1) + bq := b / div64 + br := b % div64 + c := br<<32 + l>>32 + cq := c / div64 + cr := c % div64 + d := cr<<32 + l&(1<<32-1) + dq := d / div64 + dr := d % div64 + return (aq<<32 | bq), (cq<<32 | dq), uint32(dr) +} + +var dNaN = Decimal128{0x1F << 58, 0} +var dPosInf = Decimal128{0x1E << 58, 0} +var dNegInf = Decimal128{0x3E << 58, 0} + +func dErr(s string) (Decimal128, error) { + return dNaN, fmt.Errorf("cannot parse %q as a decimal128", s) +} + +// ParseDecimal128 parse a string and return the corresponding value as +// a decimal128 +func ParseDecimal128(s string) (Decimal128, error) { + orig := s + if s == "" { + return dErr(orig) + } + neg := s[0] == '-' + if neg || s[0] == '+' { + s = s[1:] + } + + if (len(s) == 3 || len(s) == 8) && (s[0] == 'N' || s[0] == 'n' || s[0] == 'I' || s[0] == 'i') { + if s == "NaN" || s == "nan" || strings.EqualFold(s, "nan") { + return dNaN, nil + } + if s == "Inf" || s == "inf" || strings.EqualFold(s, "inf") || strings.EqualFold(s, "infinity") { + if neg { + return dNegInf, nil + } + return dPosInf, nil + } + return dErr(orig) + } + + var h, l uint64 + var e int + + var add, ovr uint32 + var mul uint32 = 1 + var dot = -1 + var digits = 0 + var i = 0 + for i < len(s) { + c := s[i] + if mul == 1e9 { + h, l, ovr = muladd(h, l, mul, add) + mul, add = 1, 0 + if ovr > 0 || h&((1<<15-1)<<49) > 0 { + return dErr(orig) + } + } + if c >= '0' && c <= '9' { + i++ + if c > '0' || digits > 0 { + digits++ + } + if digits > 34 { + if c == '0' { + // Exact rounding. + e++ + continue + } + return dErr(orig) + } + mul *= 10 + add *= 10 + add += uint32(c - '0') + continue + } + if c == '.' { + i++ + if dot >= 0 || i == 1 && len(s) == 1 { + return dErr(orig) + } + if i == len(s) { + break + } + if s[i] < '0' || s[i] > '9' || e > 0 { + return dErr(orig) + } + dot = i + continue + } + break + } + if i == 0 { + return dErr(orig) + } + if mul > 1 { + h, l, ovr = muladd(h, l, mul, add) + if ovr > 0 || h&((1<<15-1)<<49) > 0 { + return dErr(orig) + } + } + if dot >= 0 { + e += dot - i + } + if i+1 < len(s) && (s[i] == 'E' || s[i] == 'e') { + i++ + eneg := s[i] == '-' + if eneg || s[i] == '+' { + i++ + if i == len(s) { + return dErr(orig) + } + } + n := 0 + for i < len(s) && n < 1e4 { + c := s[i] + i++ + if c < '0' || c > '9' { + return dErr(orig) + } + n *= 10 + n += int(c - '0') + } + if eneg { + n = -n + } + e += n + for e < -6176 { + // Subnormal. + var div uint32 = 1 + for div < 1e9 && e < -6176 { + div *= 10 + e++ + } + var rem uint32 + h, l, rem = divmod(h, l, div) + if rem > 0 { + return dErr(orig) + } + } + for e > 6111 { + // Clamped. + var mul uint32 = 1 + for mul < 1e9 && e > 6111 { + mul *= 10 + e-- + } + h, l, ovr = muladd(h, l, mul, 0) + if ovr > 0 || h&((1<<15-1)<<49) > 0 { + return dErr(orig) + } + } + if e < -6176 || e > 6111 { + return dErr(orig) + } + } + + if i < len(s) { + return dErr(orig) + } + + h |= uint64(e+6176) & uint64(1<<14-1) << 49 + if neg { + h |= 1 << 63 + } + return Decimal128{h, l}, nil +} + +func muladd(h, l uint64, mul uint32, add uint32) (resh, resl uint64, overflow uint32) { + mul64 := uint64(mul) + a := mul64 * (l & (1<<32 - 1)) + b := a>>32 + mul64*(l>>32) + c := b>>32 + mul64*(h&(1<<32-1)) + d := c>>32 + mul64*(h>>32) + + a = a&(1<<32-1) + uint64(add) + b = b&(1<<32-1) + a>>32 + c = c&(1<<32-1) + b>>32 + d = d&(1<<32-1) + c>>32 + + return (d<<32 | c&(1<<32-1)), (b<<32 | a&(1<<32-1)), uint32(d >> 32) +} diff --git a/vendor/github.com/globalsign/mgo/bson/decode.go b/vendor/github.com/globalsign/mgo/bson/decode.go new file mode 100644 index 0000000000000..658856add04b2 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/decode.go @@ -0,0 +1,1055 @@ +// BSON library for Go +// +// Copyright (c) 2010-2012 - Gustavo Niemeyer +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// gobson - BSON library for Go. + +package bson + +import ( + "errors" + "fmt" + "io" + "math" + "net/url" + "reflect" + "strconv" + "sync" + "time" +) + +type decoder struct { + in []byte + i int + docType reflect.Type +} + +var typeM = reflect.TypeOf(M{}) + +func newDecoder(in []byte) *decoder { + return &decoder{in, 0, typeM} +} + +// -------------------------------------------------------------------------- +// Some helper functions. + +func corrupted() { + panic("Document is corrupted") +} + +// -------------------------------------------------------------------------- +// Unmarshaling of documents. + +const ( + setterUnknown = iota + setterNone + setterType + setterAddr +) + +var setterStyles map[reflect.Type]int +var setterIface reflect.Type +var setterMutex sync.RWMutex + +func init() { + var iface Setter + setterIface = reflect.TypeOf(&iface).Elem() + setterStyles = make(map[reflect.Type]int) +} + +func setterStyle(outt reflect.Type) int { + setterMutex.RLock() + style := setterStyles[outt] + setterMutex.RUnlock() + if style != setterUnknown { + return style + } + + setterMutex.Lock() + defer setterMutex.Unlock() + if outt.Implements(setterIface) { + style = setterType + } else if reflect.PtrTo(outt).Implements(setterIface) { + style = setterAddr + } else { + style = setterNone + } + setterStyles[outt] = style + return style +} + +func getSetter(outt reflect.Type, out reflect.Value) Setter { + style := setterStyle(outt) + if style == setterNone { + return nil + } + if style == setterAddr { + if !out.CanAddr() { + return nil + } + out = out.Addr() + } else if outt.Kind() == reflect.Ptr && out.IsNil() { + out.Set(reflect.New(outt.Elem())) + } + return out.Interface().(Setter) +} + +func clearMap(m reflect.Value) { + var none reflect.Value + for _, k := range m.MapKeys() { + m.SetMapIndex(k, none) + } +} + +func (d *decoder) readDocTo(out reflect.Value) { + var elemType reflect.Type + outt := out.Type() + outk := outt.Kind() + + for { + if outk == reflect.Ptr && out.IsNil() { + out.Set(reflect.New(outt.Elem())) + } + if setter := getSetter(outt, out); setter != nil { + raw := d.readRaw(ElementDocument) + err := setter.SetBSON(raw) + if _, ok := err.(*TypeError); err != nil && !ok { + panic(err) + } + return + } + if outk == reflect.Ptr { + out = out.Elem() + outt = out.Type() + outk = out.Kind() + continue + } + break + } + + var fieldsMap map[string]fieldInfo + var inlineMap reflect.Value + if outt == typeRaw { + out.Set(reflect.ValueOf(d.readRaw(ElementDocument))) + return + } + + origout := out + if outk == reflect.Interface { + if d.docType.Kind() == reflect.Map { + mv := reflect.MakeMap(d.docType) + out.Set(mv) + out = mv + } else { + dv := reflect.New(d.docType).Elem() + out.Set(dv) + out = dv + } + outt = out.Type() + outk = outt.Kind() + } + + docType := d.docType + keyType := typeString + convertKey := false + switch outk { + case reflect.Map: + keyType = outt.Key() + if keyType != typeString { + convertKey = true + } + elemType = outt.Elem() + if elemType == typeIface { + d.docType = outt + } + if out.IsNil() { + out.Set(reflect.MakeMap(out.Type())) + } else if out.Len() > 0 { + clearMap(out) + } + case reflect.Struct: + sinfo, err := getStructInfo(out.Type()) + if err != nil { + panic(err) + } + fieldsMap = sinfo.FieldsMap + out.Set(sinfo.Zero) + if sinfo.InlineMap != -1 { + inlineMap = out.Field(sinfo.InlineMap) + if !inlineMap.IsNil() && inlineMap.Len() > 0 { + clearMap(inlineMap) + } + elemType = inlineMap.Type().Elem() + if elemType == typeIface { + d.docType = inlineMap.Type() + } + } + case reflect.Slice: + switch outt.Elem() { + case typeDocElem: + origout.Set(d.readDocElems(outt)) + return + case typeRawDocElem: + origout.Set(d.readRawDocElems(outt)) + return + } + fallthrough + default: + panic("Unsupported document type for unmarshalling: " + out.Type().String()) + } + + end := int(d.readInt32()) + end += d.i - 4 + if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { + corrupted() + } + for d.in[d.i] != '\x00' { + kind := d.readByte() + name := d.readCStr() + if d.i >= end { + corrupted() + } + + switch outk { + case reflect.Map: + e := reflect.New(elemType).Elem() + if d.readElemTo(e, kind) { + k := reflect.ValueOf(name) + if convertKey { + mapKeyType := out.Type().Key() + mapKeyKind := mapKeyType.Kind() + + switch mapKeyKind { + case reflect.Int: + fallthrough + case reflect.Int8: + fallthrough + case reflect.Int16: + fallthrough + case reflect.Int32: + fallthrough + case reflect.Int64: + fallthrough + case reflect.Uint: + fallthrough + case reflect.Uint8: + fallthrough + case reflect.Uint16: + fallthrough + case reflect.Uint32: + fallthrough + case reflect.Uint64: + fallthrough + case reflect.Float32: + fallthrough + case reflect.Float64: + parsed := d.parseMapKeyAsFloat(k, mapKeyKind) + k = reflect.ValueOf(parsed) + case reflect.String: + mapKeyType = keyType + default: + panic("BSON map must have string or decimal keys. Got: " + outt.String()) + } + + k = k.Convert(mapKeyType) + } + out.SetMapIndex(k, e) + } + case reflect.Struct: + if info, ok := fieldsMap[name]; ok { + if info.Inline == nil { + d.readElemTo(out.Field(info.Num), kind) + } else { + d.readElemTo(out.FieldByIndex(info.Inline), kind) + } + } else if inlineMap.IsValid() { + if inlineMap.IsNil() { + inlineMap.Set(reflect.MakeMap(inlineMap.Type())) + } + e := reflect.New(elemType).Elem() + if d.readElemTo(e, kind) { + inlineMap.SetMapIndex(reflect.ValueOf(name), e) + } + } else { + d.dropElem(kind) + } + case reflect.Slice: + } + + if d.i >= end { + corrupted() + } + } + d.i++ // '\x00' + if d.i != end { + corrupted() + } + d.docType = docType +} + +func (decoder) parseMapKeyAsFloat(k reflect.Value, mapKeyKind reflect.Kind) float64 { + parsed, err := strconv.ParseFloat(k.String(), 64) + if err != nil { + panic("Map key is defined to be a decimal type (" + mapKeyKind.String() + ") but got error " + + err.Error()) + } + + return parsed +} + +func (d *decoder) readArrayDocTo(out reflect.Value) { + end := int(d.readInt32()) + end += d.i - 4 + if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { + corrupted() + } + i := 0 + l := out.Len() + for d.in[d.i] != '\x00' { + if i >= l { + panic("Length mismatch on array field") + } + kind := d.readByte() + for d.i < end && d.in[d.i] != '\x00' { + d.i++ + } + if d.i >= end { + corrupted() + } + d.i++ + d.readElemTo(out.Index(i), kind) + if d.i >= end { + corrupted() + } + i++ + } + if i != l { + panic("Length mismatch on array field") + } + d.i++ // '\x00' + if d.i != end { + corrupted() + } +} + +func (d *decoder) readSliceDoc(t reflect.Type) interface{} { + tmp := make([]reflect.Value, 0, 8) + elemType := t.Elem() + if elemType == typeRawDocElem { + d.dropElem(ElementArray) + return reflect.Zero(t).Interface() + } + if elemType == typeRaw { + return d.readSliceOfRaw() + } + + end := int(d.readInt32()) + end += d.i - 4 + if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { + corrupted() + } + for d.in[d.i] != '\x00' { + kind := d.readByte() + for d.i < end && d.in[d.i] != '\x00' { + d.i++ + } + if d.i >= end { + corrupted() + } + d.i++ + e := reflect.New(elemType).Elem() + if d.readElemTo(e, kind) { + tmp = append(tmp, e) + } + if d.i >= end { + corrupted() + } + } + d.i++ // '\x00' + if d.i != end { + corrupted() + } + + n := len(tmp) + slice := reflect.MakeSlice(t, n, n) + for i := 0; i != n; i++ { + slice.Index(i).Set(tmp[i]) + } + return slice.Interface() +} + +func BSONElementSize(kind byte, offset int, buffer []byte) (int, error) { + switch kind { + case ElementFloat64: // Float64 + return 8, nil + case ElementJavaScriptWithoutScope: // JavaScript without scope + fallthrough + case ElementSymbol: // Symbol + fallthrough + case ElementString: // UTF-8 string + size, err := getSize(offset, buffer) + if err != nil { + return 0, err + } + if size < 1 { + return 0, errors.New("String size can't be less then one byte") + } + size += 4 + if offset+size > len(buffer) { + return 0, io.ErrUnexpectedEOF + } + if buffer[offset+size-1] != 0 { + return 0, errors.New("Invalid string: non zero-terminated") + } + return size, nil + case ElementArray: // Array + fallthrough + case ElementDocument: // Document + size, err := getSize(offset, buffer) + if err != nil { + return 0, err + } + if size < 5 { + return 0, errors.New("Declared document size is too small") + } + return size, nil + case ElementBinary: // Binary + size, err := getSize(offset, buffer) + if err != nil { + return 0, err + } + if size < 0 { + return 0, errors.New("Binary data size can't be negative") + } + return size + 5, nil + case Element06: // Undefined (obsolete, but still seen in the wild) + return 0, nil + case ElementObjectId: // ObjectId + return 12, nil + case ElementBool: // Bool + return 1, nil + case ElementDatetime: // Timestamp + return 8, nil + case ElementNil: // Nil + return 0, nil + case ElementRegEx: // RegEx + end := offset + for i := 0; i < 2; i++ { + for end < len(buffer) && buffer[end] != '\x00' { + end++ + } + end++ + } + if end > len(buffer) { + return 0, io.ErrUnexpectedEOF + } + return end - offset, nil + case ElementDBPointer: // DBPointer + size, err := getSize(offset, buffer) + if err != nil { + return 0, err + } + if size < 1 { + return 0, errors.New("String size can't be less then one byte") + } + return size + 12 + 4, nil + case ElementJavaScriptWithScope: // JavaScript with scope + size, err := getSize(offset, buffer) + if err != nil { + return 0, err + } + if size < 4+5+5 { + return 0, errors.New("Declared document element is too small") + } + return size, nil + case ElementInt32: // Int32 + return 4, nil + case ElementTimestamp: // Mongo-specific timestamp + return 8, nil + case ElementInt64: // Int64 + return 8, nil + case ElementDecimal128: // Decimal128 + return 16, nil + case ElementMaxKey: // Max key + return 0, nil + case ElementMinKey: // Min key + return 0, nil + default: + return 0, errors.New(fmt.Sprintf("Unknown element kind (0x%02X)", kind)) + } +} + +func (d *decoder) readRaw(kind byte) Raw { + size, err := BSONElementSize(kind, d.i, d.in) + if err != nil { + corrupted() + } + if d.i+size > len(d.in) { + corrupted() + } + d.i += size + return Raw{ + Kind: kind, + Data: d.in[d.i-size : d.i], + } +} + +func (d *decoder) readSliceOfRaw() interface{} { + tmp := make([]Raw, 0, 8) + end := int(d.readInt32()) + end += d.i - 4 + if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { + corrupted() + } + for d.in[d.i] != '\x00' { + kind := d.readByte() + for d.i < end && d.in[d.i] != '\x00' { + d.i++ + } + if d.i >= end { + corrupted() + } + d.i++ + e := d.readRaw(kind) + tmp = append(tmp, e) + if d.i >= end { + corrupted() + } + } + d.i++ // '\x00' + if d.i != end { + corrupted() + } + return tmp +} + +var typeSlice = reflect.TypeOf([]interface{}{}) +var typeIface = typeSlice.Elem() + +func (d *decoder) readDocElems(typ reflect.Type) reflect.Value { + docType := d.docType + d.docType = typ + slice := make([]DocElem, 0, 8) + d.readDocWith(func(kind byte, name string) { + e := DocElem{Name: name} + v := reflect.ValueOf(&e.Value) + if d.readElemTo(v.Elem(), kind) { + slice = append(slice, e) + } + }) + slicev := reflect.New(typ).Elem() + slicev.Set(reflect.ValueOf(slice)) + d.docType = docType + return slicev +} + +func (d *decoder) readRawDocElems(typ reflect.Type) reflect.Value { + docType := d.docType + d.docType = typ + slice := make([]RawDocElem, 0, 8) + d.readDocWith(func(kind byte, name string) { + e := RawDocElem{Name: name, Value: d.readRaw(kind)} + slice = append(slice, e) + }) + slicev := reflect.New(typ).Elem() + slicev.Set(reflect.ValueOf(slice)) + d.docType = docType + return slicev +} + +func (d *decoder) readDocWith(f func(kind byte, name string)) { + end := int(d.readInt32()) + end += d.i - 4 + if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { + corrupted() + } + for d.in[d.i] != '\x00' { + kind := d.readByte() + name := d.readCStr() + if d.i >= end { + corrupted() + } + f(kind, name) + if d.i >= end { + corrupted() + } + } + d.i++ // '\x00' + if d.i != end { + corrupted() + } +} + +// -------------------------------------------------------------------------- +// Unmarshaling of individual elements within a document. +func (d *decoder) dropElem(kind byte) { + size, err := BSONElementSize(kind, d.i, d.in) + if err != nil { + corrupted() + } + if d.i+size > len(d.in) { + corrupted() + } + d.i += size +} + +// Attempt to decode an element from the document and put it into out. +// If the types are not compatible, the returned ok value will be +// false and out will be unchanged. +func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) { + outt := out.Type() + + if outt == typeRaw { + out.Set(reflect.ValueOf(d.readRaw(kind))) + return true + } + + if outt == typeRawPtr { + raw := d.readRaw(kind) + out.Set(reflect.ValueOf(&raw)) + return true + } + + if kind == ElementDocument { + // Delegate unmarshaling of documents. + outt := out.Type() + outk := out.Kind() + switch outk { + case reflect.Interface, reflect.Ptr, reflect.Struct, reflect.Map: + d.readDocTo(out) + return true + } + if setterStyle(outt) != setterNone { + d.readDocTo(out) + return true + } + if outk == reflect.Slice { + switch outt.Elem() { + case typeDocElem: + out.Set(d.readDocElems(outt)) + case typeRawDocElem: + out.Set(d.readRawDocElems(outt)) + default: + d.dropElem(kind) + } + return true + } + d.dropElem(kind) + return true + } + + if setter := getSetter(outt, out); setter != nil { + err := setter.SetBSON(d.readRaw(kind)) + if err == ErrSetZero { + out.Set(reflect.Zero(outt)) + return true + } + if err == nil { + return true + } + if _, ok := err.(*TypeError); !ok { + panic(err) + } + return false + } + + var in interface{} + + switch kind { + case ElementFloat64: + in = d.readFloat64() + case ElementString: + in = d.readStr() + case ElementDocument: + panic("Can't happen. Handled above.") + case ElementArray: + outt := out.Type() + if setterStyle(outt) != setterNone { + // Skip the value so its data is handed to the setter below. + d.dropElem(kind) + break + } + for outt.Kind() == reflect.Ptr { + outt = outt.Elem() + } + switch outt.Kind() { + case reflect.Array: + d.readArrayDocTo(out) + return true + case reflect.Slice: + in = d.readSliceDoc(outt) + default: + in = d.readSliceDoc(typeSlice) + } + case ElementBinary: + b := d.readBinary() + if b.Kind == BinaryGeneric || b.Kind == BinaryBinaryOld { + in = b.Data + } else { + in = b + } + case Element06: // Undefined (obsolete, but still seen in the wild) + in = Undefined + case ElementObjectId: + in = ObjectId(d.readBytes(12)) + case ElementBool: + in = d.readBool() + case ElementDatetime: // Timestamp + // MongoDB handles timestamps as milliseconds. + i := d.readInt64() + if i == -62135596800000 { + in = time.Time{} // In UTC for convenience. + } else { + in = time.Unix(i/1e3, i%1e3*1e6).UTC() + } + case ElementNil: + in = nil + case ElementRegEx: + in = d.readRegEx() + case ElementDBPointer: + in = DBPointer{Namespace: d.readStr(), Id: ObjectId(d.readBytes(12))} + case ElementJavaScriptWithoutScope: + in = JavaScript{Code: d.readStr()} + case ElementSymbol: + in = Symbol(d.readStr()) + case ElementJavaScriptWithScope: + start := d.i + l := int(d.readInt32()) + js := JavaScript{d.readStr(), make(M)} + d.readDocTo(reflect.ValueOf(js.Scope)) + if d.i != start+l { + corrupted() + } + in = js + case ElementInt32: + in = int(d.readInt32()) + case ElementTimestamp: // Mongo-specific timestamp + in = MongoTimestamp(d.readInt64()) + case ElementInt64: + switch out.Type() { + case typeTimeDuration: + in = time.Duration(time.Duration(d.readInt64()) * time.Millisecond) + default: + in = d.readInt64() + } + case ElementDecimal128: + in = Decimal128{ + l: uint64(d.readInt64()), + h: uint64(d.readInt64()), + } + case ElementMaxKey: + in = MaxKey + case ElementMinKey: + in = MinKey + default: + panic(fmt.Sprintf("Unknown element kind (0x%02X)", kind)) + } + + if in == nil { + out.Set(reflect.Zero(outt)) + return true + } + + outk := outt.Kind() + + // Dereference and initialize pointer if necessary. + first := true + for outk == reflect.Ptr { + if !out.IsNil() { + out = out.Elem() + } else { + elem := reflect.New(outt.Elem()) + if first { + // Only set if value is compatible. + first = false + defer func(out, elem reflect.Value) { + if good { + out.Set(elem) + } + }(out, elem) + } else { + out.Set(elem) + } + out = elem + } + outt = out.Type() + outk = outt.Kind() + } + + inv := reflect.ValueOf(in) + if outt == inv.Type() { + out.Set(inv) + return true + } + + switch outk { + case reflect.Interface: + out.Set(inv) + return true + case reflect.String: + switch inv.Kind() { + case reflect.String: + out.SetString(inv.String()) + return true + case reflect.Slice: + if b, ok := in.([]byte); ok { + out.SetString(string(b)) + return true + } + case reflect.Int, reflect.Int64: + if outt == typeJSONNumber { + out.SetString(strconv.FormatInt(inv.Int(), 10)) + return true + } + case reflect.Float64: + if outt == typeJSONNumber { + out.SetString(strconv.FormatFloat(inv.Float(), 'f', -1, 64)) + return true + } + } + case reflect.Slice, reflect.Array: + // Remember, array (0x04) slices are built with the correct + // element type. If we are here, must be a cross BSON kind + // conversion (e.g. 0x05 unmarshalling on string). + if outt.Elem().Kind() != reflect.Uint8 { + break + } + switch inv.Kind() { + case reflect.String: + slice := []byte(inv.String()) + out.Set(reflect.ValueOf(slice)) + return true + case reflect.Slice: + switch outt.Kind() { + case reflect.Array: + reflect.Copy(out, inv) + case reflect.Slice: + out.SetBytes(inv.Bytes()) + } + return true + } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + switch inv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + out.SetInt(inv.Int()) + return true + case reflect.Float32, reflect.Float64: + out.SetInt(int64(inv.Float())) + return true + case reflect.Bool: + if inv.Bool() { + out.SetInt(1) + } else { + out.SetInt(0) + } + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + panic("can't happen: no uint types in BSON (!?)") + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + switch inv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + out.SetUint(uint64(inv.Int())) + return true + case reflect.Float32, reflect.Float64: + out.SetUint(uint64(inv.Float())) + return true + case reflect.Bool: + if inv.Bool() { + out.SetUint(1) + } else { + out.SetUint(0) + } + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + panic("Can't happen. No uint types in BSON.") + } + case reflect.Float32, reflect.Float64: + switch inv.Kind() { + case reflect.Float32, reflect.Float64: + out.SetFloat(inv.Float()) + return true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + out.SetFloat(float64(inv.Int())) + return true + case reflect.Bool: + if inv.Bool() { + out.SetFloat(1) + } else { + out.SetFloat(0) + } + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + panic("Can't happen. No uint types in BSON?") + } + case reflect.Bool: + switch inv.Kind() { + case reflect.Bool: + out.SetBool(inv.Bool()) + return true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + out.SetBool(inv.Int() != 0) + return true + case reflect.Float32, reflect.Float64: + out.SetBool(inv.Float() != 0) + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + panic("Can't happen. No uint types in BSON?") + } + case reflect.Struct: + if outt == typeURL && inv.Kind() == reflect.String { + u, err := url.Parse(inv.String()) + if err != nil { + panic(err) + } + out.Set(reflect.ValueOf(u).Elem()) + return true + } + if outt == typeBinary { + if b, ok := in.([]byte); ok { + out.Set(reflect.ValueOf(Binary{Data: b})) + return true + } + } + } + + return false +} + +// -------------------------------------------------------------------------- +// Parsers of basic types. + +func (d *decoder) readRegEx() RegEx { + re := RegEx{} + re.Pattern = d.readCStr() + re.Options = d.readCStr() + return re +} + +func (d *decoder) readBinary() Binary { + l := d.readInt32() + b := Binary{} + b.Kind = d.readByte() + if b.Kind == BinaryBinaryOld && l > 4 { + // Weird obsolete format with redundant length. + rl := d.readInt32() + if rl != l-4 { + corrupted() + } + l = rl + } + b.Data = d.readBytes(l) + return b +} + +func (d *decoder) readStr() string { + l := d.readInt32() + b := d.readBytes(l - 1) + if d.readByte() != '\x00' { + corrupted() + } + return string(b) +} + +func (d *decoder) readCStr() string { + start := d.i + end := start + l := len(d.in) + for ; end != l; end++ { + if d.in[end] == '\x00' { + break + } + } + d.i = end + 1 + if d.i > l { + corrupted() + } + return string(d.in[start:end]) +} + +func (d *decoder) readBool() bool { + b := d.readByte() + if b == 0 { + return false + } + if b == 1 { + return true + } + panic(fmt.Sprintf("encoded boolean must be 1 or 0, found %d", b)) +} + +func (d *decoder) readFloat64() float64 { + return math.Float64frombits(uint64(d.readInt64())) +} + +func (d *decoder) readInt32() int32 { + b := d.readBytes(4) + return int32((uint32(b[0]) << 0) | + (uint32(b[1]) << 8) | + (uint32(b[2]) << 16) | + (uint32(b[3]) << 24)) +} + +func getSize(offset int, b []byte) (int, error) { + if offset+4 > len(b) { + return 0, io.ErrUnexpectedEOF + } + return int((uint32(b[offset]) << 0) | + (uint32(b[offset+1]) << 8) | + (uint32(b[offset+2]) << 16) | + (uint32(b[offset+3]) << 24)), nil +} + +func (d *decoder) readInt64() int64 { + b := d.readBytes(8) + return int64((uint64(b[0]) << 0) | + (uint64(b[1]) << 8) | + (uint64(b[2]) << 16) | + (uint64(b[3]) << 24) | + (uint64(b[4]) << 32) | + (uint64(b[5]) << 40) | + (uint64(b[6]) << 48) | + (uint64(b[7]) << 56)) +} + +func (d *decoder) readByte() byte { + i := d.i + d.i++ + if d.i > len(d.in) { + corrupted() + } + return d.in[i] +} + +func (d *decoder) readBytes(length int32) []byte { + if length < 0 { + corrupted() + } + start := d.i + d.i += int(length) + if d.i < start || d.i > len(d.in) { + corrupted() + } + return d.in[start : start+int(length)] +} diff --git a/vendor/github.com/globalsign/mgo/bson/encode.go b/vendor/github.com/globalsign/mgo/bson/encode.go new file mode 100644 index 0000000000000..d0c6b2a855f85 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/encode.go @@ -0,0 +1,645 @@ +// BSON library for Go +// +// Copyright (c) 2010-2012 - Gustavo Niemeyer +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// gobson - BSON library for Go. + +package bson + +import ( + "encoding/json" + "fmt" + "math" + "net/url" + "reflect" + "sort" + "strconv" + "sync" + "time" +) + +// -------------------------------------------------------------------------- +// Some internal infrastructure. + +var ( + typeBinary = reflect.TypeOf(Binary{}) + typeObjectId = reflect.TypeOf(ObjectId("")) + typeDBPointer = reflect.TypeOf(DBPointer{"", ObjectId("")}) + typeSymbol = reflect.TypeOf(Symbol("")) + typeMongoTimestamp = reflect.TypeOf(MongoTimestamp(0)) + typeOrderKey = reflect.TypeOf(MinKey) + typeDocElem = reflect.TypeOf(DocElem{}) + typeRawDocElem = reflect.TypeOf(RawDocElem{}) + typeRaw = reflect.TypeOf(Raw{}) + typeRawPtr = reflect.PtrTo(reflect.TypeOf(Raw{})) + typeURL = reflect.TypeOf(url.URL{}) + typeTime = reflect.TypeOf(time.Time{}) + typeString = reflect.TypeOf("") + typeJSONNumber = reflect.TypeOf(json.Number("")) + typeTimeDuration = reflect.TypeOf(time.Duration(0)) +) + +var ( + // spec for []uint8 or []byte encoding + arrayOps = map[string]bool{ + "$in": true, + "$nin": true, + "$all": true, + } +) + +const itoaCacheSize = 32 + +const ( + getterUnknown = iota + getterNone + getterTypeVal + getterTypePtr + getterAddr +) + +var itoaCache []string + +var getterStyles map[reflect.Type]int +var getterIface reflect.Type +var getterMutex sync.RWMutex + +func init() { + itoaCache = make([]string, itoaCacheSize) + for i := 0; i != itoaCacheSize; i++ { + itoaCache[i] = strconv.Itoa(i) + } + var iface Getter + getterIface = reflect.TypeOf(&iface).Elem() + getterStyles = make(map[reflect.Type]int) +} + +func itoa(i int) string { + if i < itoaCacheSize { + return itoaCache[i] + } + return strconv.Itoa(i) +} + +func getterStyle(outt reflect.Type) int { + getterMutex.RLock() + style := getterStyles[outt] + getterMutex.RUnlock() + if style != getterUnknown { + return style + } + + getterMutex.Lock() + defer getterMutex.Unlock() + if outt.Implements(getterIface) { + vt := outt + for vt.Kind() == reflect.Ptr { + vt = vt.Elem() + } + if vt.Implements(getterIface) { + style = getterTypeVal + } else { + style = getterTypePtr + } + } else if reflect.PtrTo(outt).Implements(getterIface) { + style = getterAddr + } else { + style = getterNone + } + getterStyles[outt] = style + return style +} + +func getGetter(outt reflect.Type, out reflect.Value) Getter { + style := getterStyle(outt) + if style == getterNone { + return nil + } + if style == getterAddr { + if !out.CanAddr() { + return nil + } + return out.Addr().Interface().(Getter) + } + if style == getterTypeVal && out.Kind() == reflect.Ptr && out.IsNil() { + return nil + } + return out.Interface().(Getter) +} + +// -------------------------------------------------------------------------- +// Marshaling of the document value itself. + +type encoder struct { + out []byte +} + +func (e *encoder) addDoc(v reflect.Value) { + for { + if vi, ok := v.Interface().(Getter); ok { + getv, err := vi.GetBSON() + if err != nil { + panic(err) + } + v = reflect.ValueOf(getv) + continue + } + if v.Kind() == reflect.Ptr { + v = v.Elem() + continue + } + break + } + + if v.Type() == typeRaw { + raw := v.Interface().(Raw) + if raw.Kind != 0x03 && raw.Kind != 0x00 { + panic("Attempted to marshal Raw kind " + strconv.Itoa(int(raw.Kind)) + " as a document") + } + if len(raw.Data) == 0 { + panic("Attempted to marshal empty Raw document") + } + e.addBytes(raw.Data...) + return + } + + start := e.reserveInt32() + + switch v.Kind() { + case reflect.Map: + e.addMap(v) + case reflect.Struct: + e.addStruct(v) + case reflect.Array, reflect.Slice: + e.addSlice(v) + default: + panic("Can't marshal " + v.Type().String() + " as a BSON document") + } + + e.addBytes(0) + e.setInt32(start, int32(len(e.out)-start)) +} + +func (e *encoder) addMap(v reflect.Value) { + for _, k := range v.MapKeys() { + e.addElem(fmt.Sprint(k), v.MapIndex(k), false) + } +} + +func (e *encoder) addStruct(v reflect.Value) { + sinfo, err := getStructInfo(v.Type()) + if err != nil { + panic(err) + } + var value reflect.Value + if sinfo.InlineMap >= 0 { + m := v.Field(sinfo.InlineMap) + if m.Len() > 0 { + for _, k := range m.MapKeys() { + ks := k.String() + if _, found := sinfo.FieldsMap[ks]; found { + panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", ks)) + } + e.addElem(ks, m.MapIndex(k), false) + } + } + } + for _, info := range sinfo.FieldsList { + if info.Inline == nil { + value = v.Field(info.Num) + } else { + // as pointers to struct are allowed here, + // there is no guarantee that pointer won't be nil. + // + // It is expected allowed behaviour + // so info.Inline MAY consist index to a nil pointer + // and that is why we safely call v.FieldByIndex and just continue on panic + field, errField := safeFieldByIndex(v, info.Inline) + if errField != nil { + continue + } + + value = field + } + if info.OmitEmpty && isZero(value) { + continue + } + if useRespectNilValues && + (value.Kind() == reflect.Slice || value.Kind() == reflect.Map) && + value.IsNil() { + e.addElem(info.Key, reflect.ValueOf(nil), info.MinSize) + continue + } + e.addElem(info.Key, value, info.MinSize) + } +} + +func safeFieldByIndex(v reflect.Value, index []int) (result reflect.Value, err error) { + defer func() { + if recovered := recover(); recovered != nil { + switch r := recovered.(type) { + case string: + err = fmt.Errorf("%s", r) + case error: + err = r + } + } + }() + + result = v.FieldByIndex(index) + return +} + +func isZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.String: + return len(v.String()) == 0 + case reflect.Ptr, reflect.Interface: + return v.IsNil() + case reflect.Slice: + return v.Len() == 0 + case reflect.Map: + return v.Len() == 0 + 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.Bool: + return !v.Bool() + case reflect.Struct: + vt := v.Type() + if vt == typeTime { + return v.Interface().(time.Time).IsZero() + } + for i := 0; i < v.NumField(); i++ { + if vt.Field(i).PkgPath != "" && !vt.Field(i).Anonymous { + continue // Private field + } + if !isZero(v.Field(i)) { + return false + } + } + return true + } + return false +} + +func (e *encoder) addSlice(v reflect.Value) { + vi := v.Interface() + if d, ok := vi.(D); ok { + for _, elem := range d { + e.addElem(elem.Name, reflect.ValueOf(elem.Value), false) + } + return + } + if d, ok := vi.(RawD); ok { + for _, elem := range d { + e.addElem(elem.Name, reflect.ValueOf(elem.Value), false) + } + return + } + l := v.Len() + et := v.Type().Elem() + if et == typeDocElem { + for i := 0; i < l; i++ { + elem := v.Index(i).Interface().(DocElem) + e.addElem(elem.Name, reflect.ValueOf(elem.Value), false) + } + return + } + if et == typeRawDocElem { + for i := 0; i < l; i++ { + elem := v.Index(i).Interface().(RawDocElem) + e.addElem(elem.Name, reflect.ValueOf(elem.Value), false) + } + return + } + for i := 0; i < l; i++ { + e.addElem(itoa(i), v.Index(i), false) + } +} + +// -------------------------------------------------------------------------- +// Marshaling of elements in a document. + +func (e *encoder) addElemName(kind byte, name string) { + e.addBytes(kind) + e.addBytes([]byte(name)...) + e.addBytes(0) +} + +func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { + + if !v.IsValid() { + e.addElemName(0x0A, name) + return + } + + if getter := getGetter(v.Type(), v); getter != nil { + getv, err := getter.GetBSON() + if err != nil { + panic(err) + } + e.addElem(name, reflect.ValueOf(getv), minSize) + return + } + + switch v.Kind() { + + case reflect.Interface: + e.addElem(name, v.Elem(), minSize) + + case reflect.Ptr: + e.addElem(name, v.Elem(), minSize) + + case reflect.String: + s := v.String() + switch v.Type() { + case typeObjectId: + if len(s) != 12 { + panic("ObjectIDs must be exactly 12 bytes long (got " + + strconv.Itoa(len(s)) + ")") + } + e.addElemName(0x07, name) + e.addBytes([]byte(s)...) + case typeSymbol: + e.addElemName(0x0E, name) + e.addStr(s) + case typeJSONNumber: + n := v.Interface().(json.Number) + if i, err := n.Int64(); err == nil { + e.addElemName(0x12, name) + e.addInt64(i) + } else if f, err := n.Float64(); err == nil { + e.addElemName(0x01, name) + e.addFloat64(f) + } else { + panic("failed to convert json.Number to a number: " + s) + } + default: + e.addElemName(0x02, name) + e.addStr(s) + } + + case reflect.Float32, reflect.Float64: + e.addElemName(0x01, name) + e.addFloat64(v.Float()) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + u := v.Uint() + if int64(u) < 0 { + panic("BSON has no uint64 type, and value is too large to fit correctly in an int64") + } else if u <= math.MaxInt32 && (minSize || v.Kind() <= reflect.Uint32) { + e.addElemName(0x10, name) + e.addInt32(int32(u)) + } else { + e.addElemName(0x12, name) + e.addInt64(int64(u)) + } + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + switch v.Type() { + case typeMongoTimestamp: + e.addElemName(0x11, name) + e.addInt64(v.Int()) + + case typeOrderKey: + if v.Int() == int64(MaxKey) { + e.addElemName(0x7F, name) + } else { + e.addElemName(0xFF, name) + } + case typeTimeDuration: + // Stored as int64 + e.addElemName(0x12, name) + + e.addInt64(int64(v.Int() / 1e6)) + default: + i := v.Int() + if (minSize || v.Type().Kind() != reflect.Int64) && i >= math.MinInt32 && i <= math.MaxInt32 { + // It fits into an int32, encode as such. + e.addElemName(0x10, name) + e.addInt32(int32(i)) + } else { + e.addElemName(0x12, name) + e.addInt64(i) + } + } + + case reflect.Bool: + e.addElemName(0x08, name) + if v.Bool() { + e.addBytes(1) + } else { + e.addBytes(0) + } + + case reflect.Map: + e.addElemName(0x03, name) + e.addDoc(v) + + case reflect.Slice: + vt := v.Type() + et := vt.Elem() + if et.Kind() == reflect.Uint8 { + if arrayOps[name] { + e.addElemName(0x04, name) + e.addDoc(v) + } else { + e.addElemName(0x05, name) + e.addBinary(0x00, v.Bytes()) + } + } else if et == typeDocElem || et == typeRawDocElem { + e.addElemName(0x03, name) + e.addDoc(v) + } else { + e.addElemName(0x04, name) + e.addDoc(v) + } + + case reflect.Array: + et := v.Type().Elem() + if et.Kind() == reflect.Uint8 { + if arrayOps[name] { + e.addElemName(0x04, name) + e.addDoc(v) + } else { + e.addElemName(0x05, name) + if v.CanAddr() { + e.addBinary(0x00, v.Slice(0, v.Len()).Interface().([]byte)) + } else { + n := v.Len() + e.addInt32(int32(n)) + e.addBytes(0x00) + for i := 0; i < n; i++ { + el := v.Index(i) + e.addBytes(byte(el.Uint())) + } + } + } + } else { + e.addElemName(0x04, name) + e.addDoc(v) + } + + case reflect.Struct: + switch s := v.Interface().(type) { + + case Raw: + kind := s.Kind + if kind == 0x00 { + kind = 0x03 + } + if len(s.Data) == 0 && kind != 0x06 && kind != 0x0A && kind != 0xFF && kind != 0x7F { + panic("Attempted to marshal empty Raw document") + } + e.addElemName(kind, name) + e.addBytes(s.Data...) + + case Binary: + e.addElemName(0x05, name) + e.addBinary(s.Kind, s.Data) + + case Decimal128: + e.addElemName(0x13, name) + e.addInt64(int64(s.l)) + e.addInt64(int64(s.h)) + + case DBPointer: + e.addElemName(0x0C, name) + e.addStr(s.Namespace) + if len(s.Id) != 12 { + panic("ObjectIDs must be exactly 12 bytes long (got " + + strconv.Itoa(len(s.Id)) + ")") + } + e.addBytes([]byte(s.Id)...) + + case RegEx: + e.addElemName(0x0B, name) + e.addCStr(s.Pattern) + options := runes(s.Options) + sort.Sort(options) + e.addCStr(string(options)) + + case JavaScript: + if s.Scope == nil { + e.addElemName(0x0D, name) + e.addStr(s.Code) + } else { + e.addElemName(0x0F, name) + start := e.reserveInt32() + e.addStr(s.Code) + e.addDoc(reflect.ValueOf(s.Scope)) + e.setInt32(start, int32(len(e.out)-start)) + } + + case time.Time: + // MongoDB handles timestamps as milliseconds. + e.addElemName(0x09, name) + e.addInt64(s.Unix()*1000 + int64(s.Nanosecond()/1e6)) + + case url.URL: + e.addElemName(0x02, name) + e.addStr(s.String()) + + case undefined: + e.addElemName(0x06, name) + + default: + e.addElemName(0x03, name) + e.addDoc(v) + } + + default: + panic("Can't marshal " + v.Type().String() + " in a BSON document") + } +} + +// ------------- +// Helper method for sorting regex options +type runes []rune + +func (a runes) Len() int { return len(a) } +func (a runes) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a runes) Less(i, j int) bool { return a[i] < a[j] } + +// -------------------------------------------------------------------------- +// Marshaling of base types. + +func (e *encoder) addBinary(subtype byte, v []byte) { + if subtype == 0x02 { + // Wonder how that brilliant idea came to life. Obsolete, luckily. + e.addInt32(int32(len(v) + 4)) + e.addBytes(subtype) + e.addInt32(int32(len(v))) + } else { + e.addInt32(int32(len(v))) + e.addBytes(subtype) + } + e.addBytes(v...) +} + +func (e *encoder) addStr(v string) { + e.addInt32(int32(len(v) + 1)) + e.addCStr(v) +} + +func (e *encoder) addCStr(v string) { + e.addBytes([]byte(v)...) + e.addBytes(0) +} + +func (e *encoder) reserveInt32() (pos int) { + pos = len(e.out) + e.addBytes(0, 0, 0, 0) + return pos +} + +func (e *encoder) setInt32(pos int, v int32) { + e.out[pos+0] = byte(v) + e.out[pos+1] = byte(v >> 8) + e.out[pos+2] = byte(v >> 16) + e.out[pos+3] = byte(v >> 24) +} + +func (e *encoder) addInt32(v int32) { + u := uint32(v) + e.addBytes(byte(u), byte(u>>8), byte(u>>16), byte(u>>24)) +} + +func (e *encoder) addInt64(v int64) { + u := uint64(v) + e.addBytes(byte(u), byte(u>>8), byte(u>>16), byte(u>>24), + byte(u>>32), byte(u>>40), byte(u>>48), byte(u>>56)) +} + +func (e *encoder) addFloat64(v float64) { + e.addInt64(int64(math.Float64bits(v))) +} + +func (e *encoder) addBytes(v ...byte) { + e.out = append(e.out, v...) +} diff --git a/vendor/github.com/globalsign/mgo/bson/json.go b/vendor/github.com/globalsign/mgo/bson/json.go new file mode 100644 index 0000000000000..045c713012b90 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/json.go @@ -0,0 +1,384 @@ +package bson + +import ( + "bytes" + "encoding/base64" + "fmt" + "strconv" + "strings" + "time" + + "github.com/globalsign/mgo/internal/json" +) + +// UnmarshalJSON unmarshals a JSON value that may hold non-standard +// syntax as defined in BSON's extended JSON specification. +func UnmarshalJSON(data []byte, value interface{}) error { + d := json.NewDecoder(bytes.NewBuffer(data)) + d.Extend(&jsonExt) + return d.Decode(value) +} + +// MarshalJSON marshals a JSON value that may hold non-standard +// syntax as defined in BSON's extended JSON specification. +func MarshalJSON(value interface{}) ([]byte, error) { + var buf bytes.Buffer + e := json.NewEncoder(&buf) + e.Extend(&jsonExt) + err := e.Encode(value) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// jdec is used internally by the JSON decoding functions +// so they may unmarshal functions without getting into endless +// recursion due to keyed objects. +func jdec(data []byte, value interface{}) error { + d := json.NewDecoder(bytes.NewBuffer(data)) + d.Extend(&funcExt) + return d.Decode(value) +} + +var jsonExt json.Extension +var funcExt json.Extension + +// TODO +// - Shell regular expressions ("/regexp/opts") + +func init() { + jsonExt.DecodeUnquotedKeys(true) + jsonExt.DecodeTrailingCommas(true) + + funcExt.DecodeFunc("BinData", "$binaryFunc", "$type", "$binary") + jsonExt.DecodeKeyed("$binary", jdecBinary) + jsonExt.DecodeKeyed("$binaryFunc", jdecBinary) + jsonExt.EncodeType([]byte(nil), jencBinarySlice) + jsonExt.EncodeType(Binary{}, jencBinaryType) + + funcExt.DecodeFunc("ISODate", "$dateFunc", "S") + funcExt.DecodeFunc("new Date", "$dateFunc", "S") + jsonExt.DecodeKeyed("$date", jdecDate) + jsonExt.DecodeKeyed("$dateFunc", jdecDate) + jsonExt.EncodeType(time.Time{}, jencDate) + + funcExt.DecodeFunc("Timestamp", "$timestamp", "t", "i") + jsonExt.DecodeKeyed("$timestamp", jdecTimestamp) + jsonExt.EncodeType(MongoTimestamp(0), jencTimestamp) + + funcExt.DecodeConst("undefined", Undefined) + + jsonExt.DecodeKeyed("$regex", jdecRegEx) + jsonExt.EncodeType(RegEx{}, jencRegEx) + + funcExt.DecodeFunc("ObjectId", "$oidFunc", "Id") + jsonExt.DecodeKeyed("$oid", jdecObjectId) + jsonExt.DecodeKeyed("$oidFunc", jdecObjectId) + jsonExt.EncodeType(ObjectId(""), jencObjectId) + + funcExt.DecodeFunc("DBRef", "$dbrefFunc", "$ref", "$id") + jsonExt.DecodeKeyed("$dbrefFunc", jdecDBRef) + + funcExt.DecodeFunc("NumberLong", "$numberLongFunc", "N") + jsonExt.DecodeKeyed("$numberLong", jdecNumberLong) + jsonExt.DecodeKeyed("$numberLongFunc", jdecNumberLong) + jsonExt.EncodeType(int64(0), jencNumberLong) + jsonExt.EncodeType(int(0), jencInt) + + funcExt.DecodeConst("MinKey", MinKey) + funcExt.DecodeConst("MaxKey", MaxKey) + jsonExt.DecodeKeyed("$minKey", jdecMinKey) + jsonExt.DecodeKeyed("$maxKey", jdecMaxKey) + jsonExt.EncodeType(orderKey(0), jencMinMaxKey) + + jsonExt.DecodeKeyed("$undefined", jdecUndefined) + jsonExt.EncodeType(Undefined, jencUndefined) + + jsonExt.Extend(&funcExt) +} + +func fbytes(format string, args ...interface{}) []byte { + var buf bytes.Buffer + fmt.Fprintf(&buf, format, args...) + return buf.Bytes() +} + +func jdecBinary(data []byte) (interface{}, error) { + var v struct { + Binary []byte `json:"$binary"` + Type string `json:"$type"` + Func struct { + Binary []byte `json:"$binary"` + Type int64 `json:"$type"` + } `json:"$binaryFunc"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + + var binData []byte + var binKind int64 + if v.Type == "" && v.Binary == nil { + binData = v.Func.Binary + binKind = v.Func.Type + } else if v.Type == "" { + return v.Binary, nil + } else { + binData = v.Binary + binKind, err = strconv.ParseInt(v.Type, 0, 64) + if err != nil { + binKind = -1 + } + } + + if binKind == 0 { + return binData, nil + } + if binKind < 0 || binKind > 255 { + return nil, fmt.Errorf("invalid type in binary object: %s", data) + } + + return Binary{Kind: byte(binKind), Data: binData}, nil +} + +func jencBinarySlice(v interface{}) ([]byte, error) { + in := v.([]byte) + out := make([]byte, base64.StdEncoding.EncodedLen(len(in))) + base64.StdEncoding.Encode(out, in) + return fbytes(`{"$binary":"%s","$type":"0x0"}`, out), nil +} + +func jencBinaryType(v interface{}) ([]byte, error) { + in := v.(Binary) + out := make([]byte, base64.StdEncoding.EncodedLen(len(in.Data))) + base64.StdEncoding.Encode(out, in.Data) + return fbytes(`{"$binary":"%s","$type":"0x%x"}`, out, in.Kind), nil +} + +const jdateFormat = "2006-01-02T15:04:05.999Z07:00" + +func jdecDate(data []byte) (interface{}, error) { + var v struct { + S string `json:"$date"` + Func struct { + S string + } `json:"$dateFunc"` + } + _ = jdec(data, &v) + if v.S == "" { + v.S = v.Func.S + } + if v.S != "" { + var errs []string + for _, format := range []string{jdateFormat, "2006-01-02"} { + t, err := time.Parse(format, v.S) + if err == nil { + return t, nil + } + errs = append(errs, err.Error()) + } + return nil, fmt.Errorf("cannot parse date: %q [%s]", v.S, strings.Join(errs, ", ")) + } + + var vn struct { + Date struct { + N int64 `json:"$numberLong,string"` + } `json:"$date"` + Func struct { + S int64 + } `json:"$dateFunc"` + } + err := jdec(data, &vn) + if err != nil { + return nil, fmt.Errorf("cannot parse date: %q", data) + } + n := vn.Date.N + if n == 0 { + n = vn.Func.S + } + return time.Unix(n/1000, n%1000*1e6).UTC(), nil +} + +func jencDate(v interface{}) ([]byte, error) { + t := v.(time.Time) + return fbytes(`{"$date":%q}`, t.Format(jdateFormat)), nil +} + +func jdecTimestamp(data []byte) (interface{}, error) { + var v struct { + Func struct { + T int32 `json:"t"` + I int32 `json:"i"` + } `json:"$timestamp"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + return MongoTimestamp(uint64(v.Func.T)<<32 | uint64(uint32(v.Func.I))), nil +} + +func jencTimestamp(v interface{}) ([]byte, error) { + ts := uint64(v.(MongoTimestamp)) + return fbytes(`{"$timestamp":{"t":%d,"i":%d}}`, ts>>32, uint32(ts)), nil +} + +func jdecRegEx(data []byte) (interface{}, error) { + var v struct { + Regex string `json:"$regex"` + Options string `json:"$options"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + return RegEx{v.Regex, v.Options}, nil +} + +func jencRegEx(v interface{}) ([]byte, error) { + re := v.(RegEx) + type regex struct { + Regex string `json:"$regex"` + Options string `json:"$options"` + } + return json.Marshal(regex{re.Pattern, re.Options}) +} + +func jdecObjectId(data []byte) (interface{}, error) { + var v struct { + Id string `json:"$oid"` + Func struct { + Id string + } `json:"$oidFunc"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + if v.Id == "" { + v.Id = v.Func.Id + } + return ObjectIdHex(v.Id), nil +} + +func jencObjectId(v interface{}) ([]byte, error) { + return fbytes(`{"$oid":"%s"}`, v.(ObjectId).Hex()), nil +} + +func jdecDBRef(data []byte) (interface{}, error) { + // TODO Support unmarshaling $ref and $id into the input value. + var v struct { + Obj map[string]interface{} `json:"$dbrefFunc"` + } + // TODO Fix this. Must not be required. + v.Obj = make(map[string]interface{}) + err := jdec(data, &v) + if err != nil { + return nil, err + } + return v.Obj, nil +} + +func jdecNumberLong(data []byte) (interface{}, error) { + var v struct { + N int64 `json:"$numberLong,string"` + Func struct { + N int64 `json:",string"` + } `json:"$numberLongFunc"` + } + var vn struct { + N int64 `json:"$numberLong"` + Func struct { + N int64 + } `json:"$numberLongFunc"` + } + err := jdec(data, &v) + if err != nil { + err = jdec(data, &vn) + v.N = vn.N + v.Func.N = vn.Func.N + } + if err != nil { + return nil, err + } + if v.N != 0 { + return v.N, nil + } + return v.Func.N, nil +} + +func jencNumberLong(v interface{}) ([]byte, error) { + n := v.(int64) + f := `{"$numberLong":"%d"}` + if n <= 1<<53 { + f = `{"$numberLong":%d}` + } + return fbytes(f, n), nil +} + +func jencInt(v interface{}) ([]byte, error) { + n := v.(int) + f := `{"$numberLong":"%d"}` + if int64(n) <= 1<<53 { + f = `%d` + } + return fbytes(f, n), nil +} + +func jdecMinKey(data []byte) (interface{}, error) { + var v struct { + N int64 `json:"$minKey"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + if v.N != 1 { + return nil, fmt.Errorf("invalid $minKey object: %s", data) + } + return MinKey, nil +} + +func jdecMaxKey(data []byte) (interface{}, error) { + var v struct { + N int64 `json:"$maxKey"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + if v.N != 1 { + return nil, fmt.Errorf("invalid $maxKey object: %s", data) + } + return MaxKey, nil +} + +func jencMinMaxKey(v interface{}) ([]byte, error) { + switch v.(orderKey) { + case MinKey: + return []byte(`{"$minKey":1}`), nil + case MaxKey: + return []byte(`{"$maxKey":1}`), nil + } + panic(fmt.Sprintf("invalid $minKey/$maxKey value: %d", v)) +} + +func jdecUndefined(data []byte) (interface{}, error) { + var v struct { + B bool `json:"$undefined"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + if !v.B { + return nil, fmt.Errorf("invalid $undefined object: %s", data) + } + return Undefined, nil +} + +func jencUndefined(v interface{}) ([]byte, error) { + return []byte(`{"$undefined":true}`), nil +} diff --git a/vendor/github.com/globalsign/mgo/bson/stream.go b/vendor/github.com/globalsign/mgo/bson/stream.go new file mode 100644 index 0000000000000..466528457b5fd --- /dev/null +++ b/vendor/github.com/globalsign/mgo/bson/stream.go @@ -0,0 +1,90 @@ +package bson + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" +) + +const ( + // MinDocumentSize is the size of the smallest possible valid BSON document: + // an int32 size header + 0x00 (end of document). + MinDocumentSize = 5 + + // MaxDocumentSize is the largest possible size for a BSON document allowed by MongoDB, + // that is, 16 MiB (see https://docs.mongodb.com/manual/reference/limits/). + MaxDocumentSize = 16777216 +) + +// ErrInvalidDocumentSize is an error returned when a BSON document's header +// contains a size smaller than MinDocumentSize or greater than MaxDocumentSize. +type ErrInvalidDocumentSize struct { + DocumentSize int32 +} + +func (e ErrInvalidDocumentSize) Error() string { + return fmt.Sprintf("invalid document size %d", e.DocumentSize) +} + +// A Decoder reads and decodes BSON values from an input stream. +type Decoder struct { + source io.Reader +} + +// NewDecoder returns a new Decoder that reads from source. +// It does not add any extra buffering, and may not read data from source beyond the BSON values requested. +func NewDecoder(source io.Reader) *Decoder { + return &Decoder{source: source} +} + +// Decode reads the next BSON-encoded value from its input and stores it in the value pointed to by v. +// See the documentation for Unmarshal for details about the conversion of BSON into a Go value. +func (dec *Decoder) Decode(v interface{}) (err error) { + // BSON documents start with their size as a *signed* int32. + var docSize int32 + if err = binary.Read(dec.source, binary.LittleEndian, &docSize); err != nil { + return + } + + if docSize < MinDocumentSize || docSize > MaxDocumentSize { + return ErrInvalidDocumentSize{DocumentSize: docSize} + } + + docBuffer := bytes.NewBuffer(make([]byte, 0, docSize)) + if err = binary.Write(docBuffer, binary.LittleEndian, docSize); err != nil { + return + } + + // docSize is the *full* document's size (including the 4-byte size header, + // which has already been read). + if _, err = io.CopyN(docBuffer, dec.source, int64(docSize-4)); err != nil { + return + } + + // Let Unmarshal handle the rest. + defer handleErr(&err) + return Unmarshal(docBuffer.Bytes(), v) +} + +// An Encoder encodes and writes BSON values to an output stream. +type Encoder struct { + target io.Writer +} + +// NewEncoder returns a new Encoder that writes to target. +func NewEncoder(target io.Writer) *Encoder { + return &Encoder{target: target} +} + +// Encode encodes v to BSON, and if successful writes it to the Encoder's output stream. +// See the documentation for Marshal for details about the conversion of Go values to BSON. +func (enc *Encoder) Encode(v interface{}) error { + data, err := Marshal(v) + if err != nil { + return err + } + + _, err = enc.target.Write(data) + return err +} diff --git a/vendor/github.com/globalsign/mgo/internal/json/BUILD b/vendor/github.com/globalsign/mgo/internal/json/BUILD new file mode 100644 index 0000000000000..89f9d09ce9365 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/internal/json/BUILD @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "decode.go", + "encode.go", + "extension.go", + "fold.go", + "indent.go", + "scanner.go", + "stream.go", + "tags.go", + ], + importmap = "k8s.io/kubernetes/vendor/github.com/globalsign/mgo/internal/json", + importpath = "github.com/globalsign/mgo/internal/json", + visibility = ["//vendor/github.com/globalsign/mgo:__subpackages__"], +) + +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/github.com/globalsign/mgo/internal/json/LICENSE b/vendor/github.com/globalsign/mgo/internal/json/LICENSE new file mode 100644 index 0000000000000..74487567632c8 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/internal/json/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/globalsign/mgo/internal/json/decode.go b/vendor/github.com/globalsign/mgo/internal/json/decode.go new file mode 100644 index 0000000000000..d5ca1f9a851c1 --- /dev/null +++ b/vendor/github.com/globalsign/mgo/internal/json/decode.go @@ -0,0 +1,1685 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Represents JSON data structure using native Go types: booleans, floats, +// strings, arrays, and maps. + +package json + +import ( + "bytes" + "encoding" + "encoding/base64" + "errors" + "fmt" + "reflect" + "runtime" + "strconv" + "unicode" + "unicode/utf16" + "unicode/utf8" +) + +// Unmarshal parses the JSON-encoded data and stores the result +// in the value pointed to by v. +// +// Unmarshal uses the inverse of the encodings that +// Marshal uses, allocating maps, slices, and pointers as necessary, +// with the following additional rules: +// +// To unmarshal JSON into a pointer, Unmarshal first handles the case of +// the JSON being the JSON literal null. In that case, Unmarshal sets +// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into +// the value pointed at by the pointer. If the pointer is nil, Unmarshal +// allocates a new value for it to point to. +// +// To unmarshal JSON into a struct, Unmarshal matches incoming object +// keys to the keys used by Marshal (either the struct field name or its tag), +// preferring an exact match but also accepting a case-insensitive match. +// Unmarshal will only set exported fields of the struct. +// +// To unmarshal JSON into an interface value, +// Unmarshal stores one of these in the interface value: +// +// bool, for JSON booleans +// float64, for JSON numbers +// string, for JSON strings +// []interface{}, for JSON arrays +// map[string]interface{}, for JSON objects +// nil for JSON null +// +// To unmarshal a JSON array into a slice, Unmarshal resets the slice length +// to zero and then appends each element to the slice. +// As a special case, to unmarshal an empty JSON array into a slice, +// Unmarshal replaces the slice with a new empty slice. +// +// To unmarshal a JSON array into a Go array, Unmarshal decodes +// JSON array elements into corresponding Go array elements. +// If the Go array is smaller than the JSON array, +// the additional JSON array elements are discarded. +// If the JSON array is smaller than the Go array, +// the additional Go array elements are set to zero values. +// +// To unmarshal a JSON object into a map, Unmarshal first establishes a map to +// use, If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal +// reuses the existing map, keeping existing entries. Unmarshal then stores key- +// value pairs from the JSON object into the map. The map's key type must +// either be a string or implement encoding.TextUnmarshaler. +// +// If a JSON value is not appropriate for a given target type, +// or if a JSON number overflows the target type, Unmarshal +// skips that field and completes the unmarshaling as best it can. +// If no more serious errors are encountered, Unmarshal returns +// an UnmarshalTypeError describing the earliest such error. +// +// The JSON null value unmarshals into an interface, map, pointer, or slice +// by setting that Go value to nil. Because null is often used in JSON to mean +// ``not present,'' unmarshaling a JSON null into any other Go type has no effect +// on the value and produces no error. +// +// When unmarshaling quoted strings, invalid UTF-8 or +// invalid UTF-16 surrogate pairs are not treated as an error. +// Instead, they are replaced by the Unicode replacement +// character U+FFFD. +// +func Unmarshal(data []byte, v interface{}) error { + // Check for well-formedness. + // Avoids filling out half a data structure + // before discovering a JSON syntax error. + var d decodeState + err := checkValid(data, &d.scan) + if err != nil { + return err + } + + d.init(data) + return d.unmarshal(v) +} + +// Unmarshaler is the interface implemented by types +// that can unmarshal a JSON description of themselves. +// The input can be assumed to be a valid encoding of +// a JSON value. UnmarshalJSON must copy the JSON data +// if it wishes to retain the data after returning. +type Unmarshaler interface { + UnmarshalJSON([]byte) error +} + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError struct { + Value string // description of JSON value - "bool", "array", "number -5" + Type reflect.Type // type of Go value it could not be assigned to + Offset int64 // error occurred after reading Offset bytes +} + +func (e *UnmarshalTypeError) Error() string { + return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() +} + +// An UnmarshalFieldError describes a JSON object key that +// led to an unexported (and therefore unwritable) struct field. +// (No longer used; kept for compatibility.) +type UnmarshalFieldError struct { + Key string + Type reflect.Type + Field reflect.StructField +} + +func (e *UnmarshalFieldError) Error() string { + return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String() +} + +// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. +// (The argument to Unmarshal must be a non-nil pointer.) +type InvalidUnmarshalError struct { + Type reflect.Type +} + +func (e *InvalidUnmarshalError) Error() string { + if e.Type == nil { + return "json: Unmarshal(nil)" + } + + if e.Type.Kind() != reflect.Ptr { + return "json: Unmarshal(non-pointer " + e.Type.String() + ")" + } + return "json: Unmarshal(nil " + e.Type.String() + ")" +} + +func (d *decodeState) unmarshal(v interface{}) (err error) { + defer func() { + if r := recover(); r != nil { + if _, ok := r.(runtime.Error); ok { + panic(r) + } + err = r.(error) + } + }() + + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + return &InvalidUnmarshalError{reflect.TypeOf(v)} + } + + d.scan.reset() + // We decode rv not rv.Elem because the Unmarshaler interface + // test must be applied at the top level of the value. + d.value(rv) + return d.savedError +} + +// A Number represents a JSON number literal. +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +// isValidNumber reports whether s is a valid JSON number literal. +func isValidNumber(s string) bool { + // This function implements the JSON numbers grammar. + // See https://tools.ietf.org/html/rfc7159#section-6 + // and http://json.org/number.gif + + if s == "" { + return false + } + + // Optional - + if s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + + // Digits + switch { + default: + return false + + case s[0] == '0': + s = s[1:] + + case '1' <= s[0] && s[0] <= '9': + s = s[1:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // . followed by 1 or more digits. + if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { + s = s[2:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // e or E followed by an optional - or + and + // 1 or more digits. + if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { + s = s[1:] + if s[0] == '+' || s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // Make sure we are at the end. + return s == "" +} + +// decodeState represents the state while decoding a JSON value. +type decodeState struct { + data []byte + off int // read offset in data + scan scanner + nextscan scanner // for calls to nextValue + savedError error + useNumber bool + ext Extension +} + +// errPhase is used for errors that should not happen unless +// there is a bug in the JSON decoder or something is editing +// the data slice while the decoder executes. +var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?") + +func (d *decodeState) init(data []byte) *decodeState { + d.data = data + d.off = 0 + d.savedError = nil + return d +} + +// error aborts the decoding by panicking with err. +func (d *decodeState) error(err error) { + panic(err) +} + +// saveError saves the first err it is called with, +// for reporting at the end of the unmarshal. +func (d *decodeState) saveError(err error) { + if d.savedError == nil { + d.savedError = err + } +} + +// next cuts off and returns the next full JSON value in d.data[d.off:]. +// The next value is known to be an object or array, not a literal. +func (d *decodeState) next() []byte { + c := d.data[d.off] + item, rest, err := nextValue(d.data[d.off:], &d.nextscan) + if err != nil { + d.error(err) + } + d.off = len(d.data) - len(rest) + + // Our scanner has seen the opening brace/bracket + // and thinks we're still in the middle of the object. + // invent a closing brace/bracket to get it out. + if c == '{' { + d.scan.step(&d.scan, '}') + } else if c == '[' { + d.scan.step(&d.scan, ']') + } else { + // Was inside a function name. Get out of it. + d.scan.step(&d.scan, '(') + d.scan.step(&d.scan, ')') + } + + return item +} + +// scanWhile processes bytes in d.data[d.off:] until it +// receives a scan code not equal to op. +// It updates d.off and returns the new scan code. +func (d *decodeState) scanWhile(op int) int { + var newOp int + for { + if d.off >= len(d.data) { + newOp = d.scan.eof() + d.off = len(d.data) + 1 // mark processed EOF with len+1 + } else { + c := d.data[d.off] + d.off++ + newOp = d.scan.step(&d.scan, c) + } + if newOp != op { + break + } + } + return newOp +} + +// value decodes a JSON value from d.data[d.off:] into the value. +// it updates d.off to point past the decoded value. +func (d *decodeState) value(v reflect.Value) { + if !v.IsValid() { + _, rest, err := nextValue(d.data[d.off:], &d.nextscan) + if err != nil { + d.error(err) + } + d.off = len(d.data) - len(rest) + + // d.scan thinks we're still at the beginning of the item. + // Feed in an empty string - the shortest, simplest value - + // so that it knows we got to the end of the value. + if d.scan.redo { + // rewind. + d.scan.redo = false + d.scan.step = stateBeginValue + } + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '"') + + n := len(d.scan.parseState) + if n > 0 && d.scan.parseState[n-1] == parseObjectKey { + // d.scan thinks we just read an object key; finish the object + d.scan.step(&d.scan, ':') + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '}') + } + + return + } + + switch op := d.scanWhile(scanSkipSpace); op { + default: + d.error(errPhase) + + case scanBeginArray: + d.array(v) + + case scanBeginObject: + d.object(v) + + case scanBeginLiteral: + d.literal(v) + + case scanBeginName: + d.name(v) + } +} + +type unquotedValue struct{} + +// valueQuoted is like value but decodes a +// quoted string literal or literal null into an interface value. +// If it finds anything other than a quoted string literal or null, +// valueQuoted returns unquotedValue{}. +func (d *decodeState) valueQuoted() interface{} { + switch op := d.scanWhile(scanSkipSpace); op { + default: + d.error(errPhase) + + case scanBeginArray: + d.array(reflect.Value{}) + + case scanBeginObject: + d.object(reflect.Value{}) + + case scanBeginName: + switch v := d.nameInterface().(type) { + case nil, string: + return v + } + + case scanBeginLiteral: + switch v := d.literalInterface().(type) { + case nil, string: + return v + } + } + return unquotedValue{} +} + +// indirect walks down v allocating pointers as needed, +// until it gets to a non-pointer. +// if it encounters an Unmarshaler, indirect stops and returns that. +// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. +func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { + // If v is a named type and is addressable, + // start with its address, so that if the type has pointer methods, + // we find them. + if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { + v = v.Addr() + } + for { + // Load value from interface, but only if the result will be + // usefully addressable. + if v.Kind() == reflect.Interface && !v.IsNil() { + e := v.Elem() + if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { + v = e + continue + } + } + + if v.Kind() != reflect.Ptr { + break + } + + if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { + break + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + if v.Type().NumMethod() > 0 { + if u, ok := v.Interface().(Unmarshaler); ok { + return u, nil, v + } + if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { + return nil, u, v + } + } + v = v.Elem() + } + return nil, nil, v +} + +// array consumes an array from d.data[d.off-1:], decoding into the value v. +// the first byte of the array ('[') has been read already. +func (d *decodeState) array(v reflect.Value) { + // Check for unmarshaler. + u, ut, pv := d.indirect(v, false) + if u != nil { + d.off-- + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)}) + d.off-- + d.next() + return + } + + v = pv + + // Check type of target. + switch v.Kind() { + case reflect.Interface: + if v.NumMethod() == 0 { + // Decoding into nil interface? Switch to non-reflect code. + v.Set(reflect.ValueOf(d.arrayInterface())) + return + } + // Otherwise it's invalid. + fallthrough + default: + d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)}) + d.off-- + d.next() + return + case reflect.Array: + case reflect.Slice: + break + } + + i := 0 + for { + // Look ahead for ] - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + // Get element of array, growing if necessary. + if v.Kind() == reflect.Slice { + // Grow slice if necessary + if i >= v.Cap() { + newcap := v.Cap() + v.Cap()/2 + if newcap < 4 { + newcap = 4 + } + newv := reflect.MakeSlice(v.Type(), v.Len(), newcap) + reflect.Copy(newv, v) + v.Set(newv) + } + if i >= v.Len() { + v.SetLen(i + 1) + } + } + + if i < v.Len() { + // Decode into element. + d.value(v.Index(i)) + } else { + // Ran out of fixed array: skip. + d.value(reflect.Value{}) + } + i++ + + // Next token must be , or ]. + op = d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + if op != scanArrayValue { + d.error(errPhase) + } + } + + if i < v.Len() { + if v.Kind() == reflect.Array { + // Array. Zero the rest. + z := reflect.Zero(v.Type().Elem()) + for ; i < v.Len(); i++ { + v.Index(i).Set(z) + } + } else { + v.SetLen(i) + } + } + if i == 0 && v.Kind() == reflect.Slice { + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + } +} + +var nullLiteral = []byte("null") +var textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem() + +// object consumes an object from d.data[d.off-1:], decoding into the value v. +// the first byte ('{') of the object has been read already. +func (d *decodeState) object(v reflect.Value) { + // Check for unmarshaler. + u, ut, pv := d.indirect(v, false) + if d.storeKeyed(pv) { + return + } + if u != nil { + d.off-- + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + v = pv + + // Decoding into nil interface? Switch to non-reflect code. + if v.Kind() == reflect.Interface && v.NumMethod() == 0 { + v.Set(reflect.ValueOf(d.objectInterface())) + return + } + + // Check type of target: + // struct or + // map[string]T or map[encoding.TextUnmarshaler]T + switch v.Kind() { + case reflect.Map: + // Map key must either have string kind or be an encoding.TextUnmarshaler. + t := v.Type() + if t.Key().Kind() != reflect.String && + !reflect.PtrTo(t.Key()).Implements(textUnmarshalerType) { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + if v.IsNil() { + v.Set(reflect.MakeMap(t)) + } + case reflect.Struct: + + default: + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + + var mapElem reflect.Value + + empty := true + for { + // Read opening " of string key or closing }. + op := d.scanWhile(scanSkipSpace) + if op == scanEndObject { + if !empty && !d.ext.trailingCommas { + d.syntaxError("beginning of object key string") + } + break + } + empty = false + if op == scanBeginName { + if !d.ext.unquotedKeys { + d.syntaxError("beginning of object key string") + } + } else if op != scanBeginLiteral { + d.error(errPhase) + } + unquotedKey := op == scanBeginName + + // Read key. + start := d.off - 1 + op = d.scanWhile(scanContinue) + item := d.data[start : d.off-1] + var key []byte + if unquotedKey { + key = item + // TODO Fix code below to quote item when necessary. + } else { + var ok bool + key, ok = unquoteBytes(item) + if !ok { + d.error(errPhase) + } + } + + // Figure out field corresponding to key. + var subv reflect.Value + destring := false // whether the value is wrapped in a string to be decoded first + + if v.Kind() == reflect.Map { + elemType := v.Type().Elem() + if !mapElem.IsValid() { + mapElem = reflect.New(elemType).Elem() + } else { + mapElem.Set(reflect.Zero(elemType)) + } + subv = mapElem + } else { + var f *field + fields := cachedTypeFields(v.Type()) + for i := range fields { + ff := &fields[i] + if bytes.Equal(ff.nameBytes, key) { + f = ff + break + } + if f == nil && ff.equalFold(ff.nameBytes, key) { + f = ff + } + } + if f != nil { + subv = v + destring = f.quoted + for _, i := range f.index { + if subv.Kind() == reflect.Ptr { + if subv.IsNil() { + subv.Set(reflect.New(subv.Type().Elem())) + } + subv = subv.Elem() + } + subv = subv.Field(i) + } + } + } + + // Read : before value. + if op == scanSkipSpace { + op = d.scanWhile(scanSkipSpace) + } + if op != scanObjectKey { + d.error(errPhase) + } + + // Read value. + if destring { + switch qv := d.valueQuoted().(type) { + case nil: + d.literalStore(nullLiteral, subv, false) + case string: + d.literalStore([]byte(qv), subv, true) + default: + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) + } + } else { + d.value(subv) + } + + // Write value back to map; + // if using struct, subv points into struct already. + if v.Kind() == reflect.Map { + kt := v.Type().Key() + var kv reflect.Value + switch { + case kt.Kind() == reflect.String: + kv = reflect.ValueOf(key).Convert(v.Type().Key()) + case reflect.PtrTo(kt).Implements(textUnmarshalerType): + kv = reflect.New(v.Type().Key()) + d.literalStore(item, kv, true) + kv = kv.Elem() + default: + panic("json: Unexpected key type") // should never occur + } + v.SetMapIndex(kv, subv) + } + + // Next token must be , or }. + op = d.scanWhile(scanSkipSpace) + if op == scanEndObject { + break + } + if op != scanObjectValue { + d.error(errPhase) + } + } +} + +// isNull returns whether there's a null literal at the provided offset. +func (d *decodeState) isNull(off int) bool { + if off+4 >= len(d.data) || d.data[off] != 'n' || d.data[off+1] != 'u' || d.data[off+2] != 'l' || d.data[off+3] != 'l' { + return false + } + d.nextscan.reset() + for i, c := range d.data[off:] { + if i > 4 { + return false + } + switch d.nextscan.step(&d.nextscan, c) { + case scanContinue, scanBeginName: + continue + } + break + } + return true +} + +// name consumes a const or function from d.data[d.off-1:], decoding into the value v. +// the first byte of the function name has been read already. +func (d *decodeState) name(v reflect.Value) { + if d.isNull(d.off - 1) { + d.literal(v) + return + } + + // Check for unmarshaler. + u, ut, pv := d.indirect(v, false) + if d.storeKeyed(pv) { + return + } + if u != nil { + d.off-- + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over function in input + return + } + v = pv + + // Decoding into nil interface? Switch to non-reflect code. + if v.Kind() == reflect.Interface && v.NumMethod() == 0 { + out := d.nameInterface() + if out == nil { + v.Set(reflect.Zero(v.Type())) + } else { + v.Set(reflect.ValueOf(out)) + } + return + } + + nameStart := d.off - 1 + + op := d.scanWhile(scanContinue) + + name := d.data[nameStart : d.off-1] + if op != scanParam { + // Back up so the byte just read is consumed next. + d.off-- + d.scan.undo(op) + if l, ok := d.convertLiteral(name); ok { + d.storeValue(v, l) + return + } + d.error(&SyntaxError{fmt.Sprintf("json: unknown constant %q", name), int64(d.off)}) + } + + funcName := string(name) + funcData := d.ext.funcs[funcName] + if funcData.key == "" { + d.error(fmt.Errorf("json: unknown function %q", funcName)) + } + + // Check type of target: + // struct or + // map[string]T or map[encoding.TextUnmarshaler]T + switch v.Kind() { + case reflect.Map: + // Map key must either have string kind or be an encoding.TextUnmarshaler. + t := v.Type() + if t.Key().Kind() != reflect.String && + !reflect.PtrTo(t.Key()).Implements(textUnmarshalerType) { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + if v.IsNil() { + v.Set(reflect.MakeMap(t)) + } + case reflect.Struct: + + default: + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + + // TODO Fix case of func field as map. + //topv := v + + // Figure out field corresponding to function. + key := []byte(funcData.key) + if v.Kind() == reflect.Map { + elemType := v.Type().Elem() + v = reflect.New(elemType).Elem() + } else { + var f *field + fields := cachedTypeFields(v.Type()) + for i := range fields { + ff := &fields[i] + if bytes.Equal(ff.nameBytes, key) { + f = ff + break + } + if f == nil && ff.equalFold(ff.nameBytes, key) { + f = ff + } + } + if f != nil { + for _, i := range f.index { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + v = v.Field(i) + } + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + } + } + + // Check for unmarshaler on func field itself. + u, _, _ = d.indirect(v, false) + if u != nil { + d.off = nameStart + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + + var mapElem reflect.Value + + // Parse function arguments. + for i := 0; ; i++ { + // closing ) - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndParams { + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + if i >= len(funcData.args) { + d.error(fmt.Errorf("json: too many arguments for function %s", funcName)) + } + key := []byte(funcData.args[i]) + + // Figure out field corresponding to key. + var subv reflect.Value + destring := false // whether the value is wrapped in a string to be decoded first + + if v.Kind() == reflect.Map { + elemType := v.Type().Elem() + if !mapElem.IsValid() { + mapElem = reflect.New(elemType).Elem() + } else { + mapElem.Set(reflect.Zero(elemType)) + } + subv = mapElem + } else { + var f *field + fields := cachedTypeFields(v.Type()) + for i := range fields { + ff := &fields[i] + if bytes.Equal(ff.nameBytes, key) { + f = ff + break + } + if f == nil && ff.equalFold(ff.nameBytes, key) { + f = ff + } + } + if f != nil { + subv = v + destring = f.quoted + for _, i := range f.index { + if subv.Kind() == reflect.Ptr { + if subv.IsNil() { + subv.Set(reflect.New(subv.Type().Elem())) + } + subv = subv.Elem() + } + subv = subv.Field(i) + } + } + } + + // Read value. + if destring { + switch qv := d.valueQuoted().(type) { + case nil: + d.literalStore(nullLiteral, subv, false) + case string: + d.literalStore([]byte(qv), subv, true) + default: + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) + } + } else { + d.value(subv) + } + + // Write value back to map; + // if using struct, subv points into struct already. + if v.Kind() == reflect.Map { + kt := v.Type().Key() + var kv reflect.Value + switch { + case kt.Kind() == reflect.String: + kv = reflect.ValueOf(key).Convert(v.Type().Key()) + case reflect.PtrTo(kt).Implements(textUnmarshalerType): + kv = reflect.New(v.Type().Key()) + d.literalStore(key, kv, true) + kv = kv.Elem() + default: + panic("json: Unexpected key type") // should never occur + } + v.SetMapIndex(kv, subv) + } + + // Next token must be , or ). + op = d.scanWhile(scanSkipSpace) + if op == scanEndParams { + break + } + if op != scanParam { + d.error(errPhase) + } + } +} + +// keyed attempts to decode an object or function using a keyed doc extension, +// and returns the value and true on success, or nil and false otherwise. +func (d *decodeState) keyed() (interface{}, bool) { + if len(d.ext.keyed) == 0 { + return nil, false + } + + unquote := false + + // Look-ahead first key to check for a keyed document extension. + d.nextscan.reset() + var start, end int + for i, c := range d.data[d.off-1:] { + switch op := d.nextscan.step(&d.nextscan, c); op { + case scanSkipSpace, scanContinue, scanBeginObject: + continue + case scanBeginLiteral, scanBeginName: + unquote = op == scanBeginLiteral + start = i + continue + } + end = i + break + } + + name := bytes.Trim(d.data[d.off-1+start:d.off-1+end], " \n\t") + + var key []byte + var ok bool + if unquote { + key, ok = unquoteBytes(name) + if !ok { + d.error(errPhase) + } + } else { + funcData, ok := d.ext.funcs[string(name)] + if !ok { + return nil, false + } + key = []byte(funcData.key) + } + + decode, ok := d.ext.keyed[string(key)] + if !ok { + return nil, false + } + + d.off-- + out, err := decode(d.next()) + if err != nil { + d.error(err) + } + return out, true +} + +func (d *decodeState) storeKeyed(v reflect.Value) bool { + keyed, ok := d.keyed() + if !ok { + return false + } + d.storeValue(v, keyed) + return true +} + +var ( + trueBytes = []byte("true") + falseBytes = []byte("false") + nullBytes = []byte("null") +) + +func (d *decodeState) storeValue(v reflect.Value, from interface{}) { + switch from { + case nil: + d.literalStore(nullBytes, v, false) + return + case true: + d.literalStore(trueBytes, v, false) + return + case false: + d.literalStore(falseBytes, v, false) + return + } + fromv := reflect.ValueOf(from) + for fromv.Kind() == reflect.Ptr && !fromv.IsNil() { + fromv = fromv.Elem() + } + fromt := fromv.Type() + for v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + vt := v.Type() + if fromt.AssignableTo(vt) { + v.Set(fromv) + } else if fromt.ConvertibleTo(vt) { + v.Set(fromv.Convert(vt)) + } else { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + } +} + +func (d *decodeState) convertLiteral(name []byte) (interface{}, bool) { + if len(name) == 0 { + return nil, false + } + switch name[0] { + case 't': + if bytes.Equal(name, trueBytes) { + return true, true + } + case 'f': + if bytes.Equal(name, falseBytes) { + return false, true + } + case 'n': + if bytes.Equal(name, nullBytes) { + return nil, true + } + } + if l, ok := d.ext.consts[string(name)]; ok { + return l, true + } + return nil, false +} + +// literal consumes a literal from d.data[d.off-1:], decoding into the value v. +// The first byte of the literal has been read already +// (that's how the caller knows it's a literal). +func (d *decodeState) literal(v reflect.Value) { + // All bytes inside literal return scanContinue op code. + start := d.off - 1 + op := d.scanWhile(scanContinue) + + // Scan read one byte too far; back up. + d.off-- + d.scan.undo(op) + + d.literalStore(d.data[start:d.off], v, false) +} + +// convertNumber converts the number literal s to a float64 or a Number +// depending on the setting of d.useNumber. +func (d *decodeState) convertNumber(s string) (interface{}, error) { + if d.useNumber { + return Number(s), nil + } + f, err := strconv.ParseFloat(s, 64) + if err != nil { + return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} + } + return f, nil +} + +var numberType = reflect.TypeOf(Number("")) + +// literalStore decodes a literal stored in item into v. +// +// fromQuoted indicates whether this literal came from unwrapping a +// string from the ",string" struct tag option. this is used only to +// produce more helpful error messages. +func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) { + // Check for unmarshaler. + if len(item) == 0 { + //Empty string given + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + return + } + wantptr := item[0] == 'n' // null + u, ut, pv := d.indirect(v, wantptr) + if u != nil { + err := u.UnmarshalJSON(item) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + if item[0] != '"' { + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + } + return + } + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + err := ut.UnmarshalText(s) + if err != nil { + d.error(err) + } + return + } + + v = pv + + switch c := item[0]; c { + case 'n': // null + switch v.Kind() { + case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: + v.Set(reflect.Zero(v.Type())) + // otherwise, ignore null for primitives/string + } + case 't', 'f': // true, false + value := c == 't' + switch v.Kind() { + default: + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)}) + } + case reflect.Bool: + v.SetBool(value) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(value)) + } else { + d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)}) + } + } + + case '"': // string + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + switch v.Kind() { + default: + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + case reflect.Slice: + if v.Type().Elem().Kind() != reflect.Uint8 { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + break + } + b := make([]byte, base64.StdEncoding.DecodedLen(len(s))) + n, err := base64.StdEncoding.Decode(b, s) + if err != nil { + d.saveError(err) + break + } + v.SetBytes(b[:n]) + case reflect.String: + v.SetString(string(s)) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(string(s))) + } else { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + } + } + + default: // number + if c != '-' && (c < '0' || c > '9') { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + s := string(item) + switch v.Kind() { + default: + if v.Kind() == reflect.String && v.Type() == numberType { + v.SetString(s) + if !isValidNumber(s) { + d.error(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item)) + } + break + } + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(&UnmarshalTypeError{"number", v.Type(), int64(d.off)}) + } + case reflect.Interface: + n, err := d.convertNumber(s) + if err != nil { + d.saveError(err) + break + } + if v.NumMethod() != 0 { + d.saveError(&UnmarshalTypeError{"number", v.Type(), int64(d.off)}) + break + } + v.Set(reflect.ValueOf(n)) + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n, err := strconv.ParseInt(s, 10, 64) + if err != nil || v.OverflowInt(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetInt(n) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n, err := strconv.ParseUint(s, 10, 64) + if err != nil || v.OverflowUint(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetUint(n) + + case reflect.Float32, reflect.Float64: + n, err := strconv.ParseFloat(s, v.Type().Bits()) + if err != nil || v.OverflowFloat(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetFloat(n) + } + } +} + +// The xxxInterface routines build up a value to be stored +// in an empty interface. They are not strictly necessary, +// but they avoid the weight of reflection in this common case. + +// valueInterface is like value but returns interface{} +func (d *decodeState) valueInterface() interface{} { + switch d.scanWhile(scanSkipSpace) { + default: + d.error(errPhase) + panic("unreachable") + case scanBeginArray: + return d.arrayInterface() + case scanBeginObject: + return d.objectInterface() + case scanBeginLiteral: + return d.literalInterface() + case scanBeginName: + return d.nameInterface() + } +} + +func (d *decodeState) syntaxError(expected string) { + msg := fmt.Sprintf("invalid character '%c' looking for %s", d.data[d.off-1], expected) + d.error(&SyntaxError{msg, int64(d.off)}) +} + +// arrayInterface is like array but returns []interface{}. +func (d *decodeState) arrayInterface() []interface{} { + var v = make([]interface{}, 0) + for { + // Look ahead for ] - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndArray { + if len(v) > 0 && !d.ext.trailingCommas { + d.syntaxError("beginning of value") + } + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + v = append(v, d.valueInterface()) + + // Next token must be , or ]. + op = d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + if op != scanArrayValue { + d.error(errPhase) + } + } + return v +} + +// objectInterface is like object but returns map[string]interface{}. +func (d *decodeState) objectInterface() interface{} { + v, ok := d.keyed() + if ok { + return v + } + + m := make(map[string]interface{}) + for { + // Read opening " of string key or closing }. + op := d.scanWhile(scanSkipSpace) + if op == scanEndObject { + if len(m) > 0 && !d.ext.trailingCommas { + d.syntaxError("beginning of object key string") + } + break + } + if op == scanBeginName { + if !d.ext.unquotedKeys { + d.syntaxError("beginning of object key string") + } + } else if op != scanBeginLiteral { + d.error(errPhase) + } + unquotedKey := op == scanBeginName + + // Read string key. + start := d.off - 1 + op = d.scanWhile(scanContinue) + item := d.data[start : d.off-1] + var key string + if unquotedKey { + key = string(item) + } else { + var ok bool + key, ok = unquote(item) + if !ok { + d.error(errPhase) + } + } + + // Read : before value. + if op == scanSkipSpace { + op = d.scanWhile(scanSkipSpace) + } + if op != scanObjectKey { + d.error(errPhase) + } + + // Read value. + m[key] = d.valueInterface() + + // Next token must be , or }. + op = d.scanWhile(scanSkipSpace) + if op == scanEndObject { + break + } + if op != scanObjectValue { + d.error(errPhase) + } + } + return m +} + +// literalInterface is like literal but returns an interface value. +func (d *decodeState) literalInterface() interface{} { + // All bytes inside literal return scanContinue op code. + start := d.off - 1 + op := d.scanWhile(scanContinue) + + // Scan read one byte too far; back up. + d.off-- + d.scan.undo(op) + item := d.data[start:d.off] + + switch c := item[0]; c { + case 'n': // null + return nil + + case 't', 'f': // true, false + return c == 't' + + case '"': // string + s, ok := unquote(item) + if !ok { + d.error(errPhase) + } + return s + + default: // number + if c != '-' && (c < '0' || c > '9') { + d.error(errPhase) + } + n, err := d.convertNumber(string(item)) + if err != nil { + d.saveError(err) + } + return n + } +} + +// nameInterface is like function but returns map[string]interface{}. +func (d *decodeState) nameInterface() interface{} { + v, ok := d.keyed() + if ok { + return v + } + + nameStart := d.off - 1 + + op := d.scanWhile(scanContinue) + + name := d.data[nameStart : d.off-1] + if op != scanParam { + // Back up so the byte just read is consumed next. + d.off-- + d.scan.undo(op) + if l, ok := d.convertLiteral(name); ok { + return l + } + d.error(&SyntaxError{fmt.Sprintf("json: unknown constant %q", name), int64(d.off)}) + } + + funcName := string(name) + funcData := d.ext.funcs[funcName] + if funcData.key == "" { + d.error(fmt.Errorf("json: unknown function %q", funcName)) + } + + m := make(map[string]interface{}) + for i := 0; ; i++ { + // Look ahead for ) - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndParams { + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + if i >= len(funcData.args) { + d.error(fmt.Errorf("json: too many arguments for function %s", funcName)) + } + m[funcData.args[i]] = d.valueInterface() + + // Next token must be , or ). + op = d.scanWhile(scanSkipSpace) + if op == scanEndParams { + break + } + if op != scanParam { + d.error(errPhase) + } + } + return map[string]interface{}{funcData.key: m} +} + +// getu4 decodes \uXXXX from the beginning of s, returning the hex value, +// or it returns -1. +func getu4(s []byte) rune { + if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { + return -1 + } + r, err := strconv.ParseUint(string(s[2:6]), 16, 64) + if err != nil { + return -1 + } + return rune(r) +} + +// unquote converts a quoted JSON string literal s into an actual string t. +// The rules are different than for Go, so cannot use strconv.Unquote. +func unquote(s []byte) (t string, ok bool) { + s, ok = unquoteBytes(s) + t = string(s) + return +} + +func unquoteBytes(s []byte) (t []byte, ok bool) { + if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { + return + } + s = s[1 : len(s)-1] + + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < len(s) { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == len(s) { + return s, true + } + + b := make([]byte, len(s)+2*utf8.UTFMax) + w := copy(b, s[0:r]) + for r < len(s) { + // Out of room? Can only happen if s is full of + // malformed UTF-8 and we're replacing each + // byte with RuneError. + if w >= len(b)-2*utf8.UTFMax { + nb := make([]byte, (len(b)+utf8.UTFMax)*2) + copy(nb, b[0:w]) + b = nb + } + switch c := s[r]; { + case c == '\\': + r++ + if r >= len(s) { + return + } + switch s[r] { + default: + return + case '"', '\\', '/', '\'': + b[w] = s[r] + r++ + w++ + case 'b': + b[w] = '\b' + r++ + w++ + case 'f': + b[w] = '\f' + r++ + w++ + case 'n': + b[w] = '\n' + r++ + w++ + case 'r': + b[w] = '\r' + r++ + w++ + case 't': + b[w] = '\t' + r++ + w++ + case 'u': + r-- + rr := getu4(s[r:]) + if rr < 0 { + return + } + r += 6 + if utf16.IsSurrogate(rr) { + rr1 := getu4(s[r:]) + if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { + // A valid pair; consume. + r += 6 + w += utf8.EncodeRune(b[w:], dec) + break + } + // Invalid surrogate; fall back to replacement rune. + rr = unicode.ReplacementChar + } + w += utf8.EncodeRune(b[w:], rr) + } + + // Quote, control characters are invalid. + case c == '"', c < ' ': + return + + // ASCII + case c < utf8.RuneSelf: + b[w] = c + r++ + w++ + + // Coerce to well-formed UTF-8. + default: + rr, size := utf8.DecodeRune(s[r:]) + r += size + w += utf8.EncodeRune(b[w:], rr) + } + } + return b[0:w], true +} diff --git a/vendor/github.com/globalsign/mgo/internal/json/encode.go b/vendor/github.com/globalsign/mgo/internal/json/encode.go new file mode 100644 index 0000000000000..e4b8f86487cdb --- /dev/null +++ b/vendor/github.com/globalsign/mgo/internal/json/encode.go @@ -0,0 +1,1260 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package json implements encoding and decoding of JSON as defined in +// RFC 4627. The mapping between JSON and Go values is described +// in the documentation for the Marshal and Unmarshal functions. +// +// See "JSON and Go" for an introduction to this package: +// https://golang.org/doc/articles/json_and_go.html +package json + +import ( + "bytes" + "encoding" + "encoding/base64" + "fmt" + "math" + "reflect" + "runtime" + "sort" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf8" +) + +// Marshal returns the JSON encoding of v. +// +// Marshal traverses the value v recursively. +// If an encountered value implements the Marshaler interface +// and is not a nil pointer, Marshal calls its MarshalJSON method +// to produce JSON. If no MarshalJSON method is present but the +// value implements encoding.TextMarshaler instead, Marshal calls +// its MarshalText method. +// The nil pointer exception is not strictly necessary +// but mimics a similar, necessary exception in the behavior of +// UnmarshalJSON. +// +// Otherwise, Marshal uses the following type-dependent default encodings: +// +// Boolean values encode as JSON booleans. +// +// Floating point, integer, and Number values encode as JSON numbers. +// +// String values encode as JSON strings coerced to valid UTF-8, +// replacing invalid bytes with the Unicode replacement rune. +// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" +// to keep some browsers from misinterpreting JSON output as HTML. +// Ampersand "&" is also escaped to "\u0026" for the same reason. +// This escaping can be disabled using an Encoder with DisableHTMLEscaping. +// +// Array and slice values encode as JSON arrays, except that +// []byte encodes as a base64-encoded string, and a nil slice +// encodes as the null JSON value. +// +// Struct values encode as JSON objects. Each exported struct field +// becomes a member of the object unless +// - the field's tag is "-", or +// - the field is empty and its tag specifies the "omitempty" option. +// The empty values are false, 0, any +// nil pointer or interface value, and any array, slice, map, or string of +// length zero. The object's default key string is the struct field name +// but can be specified in the struct field's tag value. The "json" key in +// the struct field's tag value is the key name, followed by an optional comma +// and options. Examples: +// +// // Field is ignored by this package. +// Field int `json:"-"` +// +// // Field appears in JSON as key "myName". +// Field int `json:"myName"` +// +// // Field appears in JSON as key "myName" and +// // the field is omitted from the object if its value is empty, +// // as defined above. +// Field int `json:"myName,omitempty"` +// +// // Field appears in JSON as key "Field" (the default), but +// // the field is skipped if empty. +// // Note the leading comma. +// Field int `json:",omitempty"` +// +// The "string" option signals that a field is stored as JSON inside a +// JSON-encoded string. It applies only to fields of string, floating point, +// integer, or boolean types. This extra level of encoding is sometimes used +// when communicating with JavaScript programs: +// +// Int64String int64 `json:",string"` +// +// The key name will be used if it's a non-empty string consisting of +// only Unicode letters, digits, dollar signs, percent signs, hyphens, +// underscores and slashes. +// +// Anonymous struct fields are usually marshaled as if their inner exported fields +// were fields in the outer struct, subject to the usual Go visibility rules amended +// as described in the next paragraph. +// An anonymous struct field with a name given in its JSON tag is treated as +// having that name, rather than being anonymous. +// An anonymous struct field of interface type is treated the same as having +// that type as its name, rather than being anonymous. +// +// The Go visibility rules for struct fields are amended for JSON when +// deciding which field to marshal or unmarshal. If there are +// multiple fields at the same level, and that level is the least +// nested (and would therefore be the nesting level selected by the +// usual Go rules), the following extra rules apply: +// +// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, +// even if there are multiple untagged fields that would otherwise conflict. +// 2) If there is exactly one field (tagged or not according to the first rule), that is selected. +// 3) Otherwise there are multiple fields, and all are ignored; no error occurs. +// +// Handling of anonymous struct fields is new in Go 1.1. +// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of +// an anonymous struct field in both current and earlier versions, give the field +// a JSON tag of "-". +// +// Map values encode as JSON objects. The map's key type must either be a string +// or implement encoding.TextMarshaler. The map keys are used as JSON object +// keys, subject to the UTF-8 coercion described for string values above. +// +// Pointer values encode as the value pointed to. +// A nil pointer encodes as the null JSON value. +// +// Interface values encode as the value contained in the interface. +// A nil interface value encodes as the null JSON value. +// +// Channel, complex, and function values cannot be encoded in JSON. +// Attempting to encode such a value causes Marshal to return +// an UnsupportedTypeError. +// +// JSON cannot represent cyclic data structures and Marshal does not +// handle them. Passing cyclic structures to Marshal will result in +// an infinite recursion. +// +func Marshal(v interface{}) ([]byte, error) { + e := &encodeState{} + err := e.marshal(v, encOpts{escapeHTML: true}) + if err != nil { + return nil, err + } + return e.Bytes(), nil +} + +// MarshalIndent is like Marshal but applies Indent to format the output. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + b, err := Marshal(v) + if err != nil { + return nil, err + } + var buf bytes.Buffer + err = Indent(&buf, b, prefix, indent) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 +// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 +// so that the JSON will be safe to embed inside HTML

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions

BodyParameter

body

true

false

v1.DeleteOptions